How can I call a controller method from within a Play! template?
I have a default controller, Application, and the hasliked() method inside that controller.
The method returns whether the logged in user has liked the post ID.
It returns "none" if the user has liked the post, otherwise it returns "block" (for the CSS)
I have added the following route: GET /hasliked/{id} Application.hasliked
I tried the following:
#{list items:postList, as:'post'}
%{
display = Application.hasliked(post.id);
%}
<div style="display: ${display}">...</div>
#{/list}
But I get this error:
Template execution error
Execution error occured in template /app/views/Application/dashboard.html. Exception raised was NullPointerException : Cannot invoke method hasliked() on null object.
Try using a fully qualified name like:
controllers.Application.hasliked()
EDIT on comment:
The issue with your exception is that you are accessing the controller to get a value. That's wrong.
Controllers in Play are used to navigate. They are static, they return "void", and they do a call to another controller method or to a render method. What you try to do may have unexpected results.
What you want to do is to get the value inside the controller and pass it as a parameter:
//On controller
public static void yourRequest() {
//...
Object display = getDisplay(); //get your value
render(display);
}
//On template
<div style="display: ${display}">...</div>
That's the recommended way.
The exception you get is (most likely) caused because your Application.hasLiked() ends up with a redirect call (either render() or call to another controller's method) and that's happening while you render the page corresponding to the initial call. So it breaks.
It would probably be a better way to do fill the information that is required into the list of items instead of calling back the controller:
Your template doesn't need to know about your controllers. It should just convert data to HTML and not acquire data from somewhere else. That's the task of the controller.
It would also be more efficient in terms of database access to fetch the like status for all items at once instead of doing several calls.
When doing refactoring (e.g. renaming methods etc of your controller) the IDE cannot help you if you call controllers from the template (unless it's aware of how Play! templates work).
If you really must do this (and again, you shouldn't) you need to fully qualify the name of the controller:
controllers.Application.hasLiked()
just like Pere Villega pointed out.
An alternative to this may be to issue an AJAX call to set the style, rather than using the controller.
Set the style of your "liked" element to display: none by default, and when your view has rendered, issue an GET request to /hasliked/ with the ID as a parameter and update your CSS styles accordingly: when the user has not already liked this, output false (or whatever you want), so that you can use JavaScript to re-define the style.
The easiest way to do this would be to use jQuery to issue a request to your controller when the view has loaded. Have a look at the Play! documentation on AJAX for some inspiration. Note that you don't have to use #{jsAction /} at all - personally I find it easier to define the jQuery calls myself.
Try the following:
<script type="text/javascript" language="javascript">
var url = "#{Application.hasliked}" + "/" + yourId;
window.location.replace(url);
</script>
Related
How do I get the validation messages I set using the struts2 validation:
public void validate() {
addFieldError("user", "Invalid User");
}
I want to get the "Invalid User" and "user" strings from a custom tagLib to print like:
public int doStartTag() {
pageContext.getOut().print( "Invalid User - user" )
}
UPDATE:
The example was a reduced and non-functional usage just explaining how I would like the values to be returned not exactly how I would use it, but here is the use case:
I want to create a custom tagLib that prints the error from struts validation. In a single tagLib I want to verify if the page contains a validation error for a given input then print in the screen the content of the error.
Scriptlet, <logic:*, javascript -> it is all out of question.
If the jsp is meant to hold the structure of the document a taglib with internal specific rules makes much more sense than flooding the page with logic comparisons.
I am not using <s:fieldError /> (or smth like that) because it create an ul and li structure I cant get rid of, even setting the default template as "simple"
Aleksandr M is correct. If you only want to change the markup spit out by the tag, you definitely don't want to create a tag, you only want to override the template that is rendering it. This is quite easy. You will get a copy of the template from the struts core jar, edit it, and put it in your project. Here's a link to the docs:
http://struts.apache.org/2.3.4.1/docs/template-loading.html
Note, depending on what you want to do, you could just get the error messages yourself. They are all exposed as JavaBeans properties on ActionSupport, which your actions should inherit from, and you can reach them with OGNL expressions, such as in the property tag.
Note, ActionSupport implementst these to fullfil the contract of the ValidationAware interface which it implements.
I have two different divisions in a JSP page. One contains a menu of links, when clicked the div2 (id-content) loads different pages accordingly. I am doing something like -
<div id="menu">
<ul class="navbar">
<li><a name="login" href="Login.jsp" onclick="changeContent()">Login</a>
</li></div>
and in the script I have something as -
<script language="JavaScript">
function changeContent() {
document.getElementById('content').load('Login.jsp');
}
</script>
I also tried -
document.getElementById('content').innerHTML=
"<jsp:include page="Login.jsp">";
None of the ways worked. Please suggest how should I
Try jquery..
function changeContent() {
$('#content').load('Login.jsp');
}
The solution is to use Ajax, which will asynchronously retrieve your page content that can be pasted in with the innerHTML method. See my answer to a similar question of how an Ajax call works and some introductory links.
As to why your examples in your answer don't work, in the first case there is no load() method on an Element object (unless you've defined one yourself and not shown it). In the second example, as one of the question comments says, there is probably something causing a syntax error in the javascript.
As an FYI, when there is a syntax error in some javascript in a web page, the current expression being parsed and the rest of the <script></script> block will be ignored. Since this is inside a function declaration, that function will never get defined.
For instance, an embedded quote in the included page will end the string for the innerHTML assignment. Then the javascript parser will try to parse the remainder of the HTML causing a syntax error as the HTML will not be valid javascript.
We use jquery. Add a click event handler to the anchor elements. In the click handler call $('#content').load(your_url);. You might want to use the load(url, function() { ...}) version. More info here http://api.jquery.com/load/
Your initial page comes down from the server. It's displayed by the browser. When you click on a link (or a button) in the browser, you want to fill the second div with new HTML. This is is a perfect job for an AJAX request. What the AJAX object in the browser does, is to send a POST (or whatever) string to the server. And then the Ajax object receives the HTML response back from the server. And then you can display that response data which the AJAX object contains, anywhere you want.
In my JSP page I have DIV.
<div id="100">
ALI
</div>
When I click on this DIV...
$("#100").click(function(){
});
...I need to send the value of the id 100, to a servlet, so that the servlet makes some database java codes, and returns for example, either 1 or 0. How can I do that? and is this the proper way?
Using Ajax, you should call your server using a URL similar to this:
http://localhot:8080/youAppContext/yourServer?id=100
Then, in the servler side, you should retrieve the value that will be in the request with the name "id"
There are out there many tool as jQuery that can help you to do the Ajax petition.
Edited
Well, here you can find a very simple Ajax example using jQuery. In the example, instead call a file (test1.txt) you should invoke a URL (as I described above). Of course, you will need to write some JS code to build your URL (where id be a variable). Once task is done in servlet side, you can return whatever, for example: "done" and display or not this information the HTML as it is done in the example.
Take a look to this Web, there are many links that can help you.
get the value using
var value = $("#100").html();
and pass it to servlet using AJAX
I have index page,which contain div section.i want to call different pages into this div section on the basis of her-link click,this is done. when calling pages that may also using ajax call,in this case ajax call not work for this page.please tell me it is possible to call ajax inside an ajax.if yes then please help me.
Update Edit:
I have created a gist where i have include all used pages,script https://gist.github.com/2786811.page service_status called the view.jsp using ajax call every 5 second,on hand view.jsp interact with database and prepare view.when we do ajax call from index.jsp, service_status called but it doesn't called view.jsp file.
Thanks
You can make ajax call on page load using $(document).ready(function () {...}); in target page you are calling.
If you are trying to dump a <script> tag with innerHTML, it won't work.
However, you could (as an example) return a JSON object with two properties:
{
html: "All your <b>HTML</b> here",
js: "alert('JavaScript to be run');"
}
Then, use the html property to put content on the page, and then eval the js property.
This isn't the best solution, since it uses the evil eval, but unless you want to rewrite your whole basic structure to use callbacks properly then it's probably your best bet.
Is it possible to call a spring controller from javascript included in a jsp?
I'm trying to call it like this:
form.action='${pageContext.request.contextPath}/spring/myController';
I can see that the control passes throught the lines, but nothing is happening.
Also I get messages like get or post is not supported.
when I submit the form with a post method I get error message post is not supported.
I use the annotations like this in controller.
#RequestMapping(method = RequestMethod.GET)
How can I handle both get and post in spring controllers?
Your javascript is not actually calling anything. Rather, it is setting the "action" attribute of (I assume) a <form> element in your web page to some URL assembled by the JSP. The "call" to your server will happen later ... when the user clicks some button that causes the form to be submitted.