I get this error when I use "${#fields.hasErrors('whatever')}"
The identifier [#fields] is not a valid Java identifier as required by section 1.19 of the EL specification (Identifier ::= Java language identifier). This check can be disabled by setting the system property org.apache.el.parser.SKIP_IDENTIFIER_CHECK to true.
How can I fix this?
looking at the official thymeleaf documentation, we see this example:
<input type="text" th:field="*{datePlanted}" />
<p th:if="${#fields.hasErrors('datePlanted')}" th:errors="*{datePlanted}">Incorrect date</p>
looking at that example, it seems like you need to put a thymeleaf field (which you passed from your controller and/or get it from a th:object) into the hasErrors bracket but in single quotation marks.
if you already did that, maybe check if you have thymeleaf imported in your html template (i doubt that you forgot that but may still wanna check that) and if thats the case, let me know.
Related
Short version
How is one supposed to make nested templates in Thymeleaf when using Spring? It appears asterisk notation is not supported ("*{mailingAddress}") inside th:object attributes in Spring. Is there a work-around / different tag to use?
Long version
For example, let's say I have these classes:
class Address { String street; }
class Person { Address mailingAddress; Address shippingAddress; }
class Order { int orderNo; Person customer; }
So I make an address.html Thymeleaf template:
<span th:text="*{street}"></span>
We test it with a sample Address. Looks good.
and I make a person.html Thymeleaf template that references the address like so:
<span th:text="*{firstName}"></span>
<span th:object="${person.shippingAddress}">
<span th:include="fragments/address :: address"></span>
</span>
And we test it with an example person. I could even reference the same template and set the context to be the ${person.mailingAddress}. So far so good.
Now let's make our Order template. Only, hey, wait. Earlier, in our person.html file we said ${person.shippingAddress} but now we need it to say ${order.customer.shippingAddress}. If I were not using Spring I'd put the following into person.html:
<span th:text="*{firstName}"></span>
<span th:object="*{shippingAddress}">
<span th:include="fragments/address :: address"></span>
</span>
That way, no matter what my path to getting here all I have to care about is that my current context has a shippingAddress. I could then use person.html directly as well as within my order.html template.
Unfortunately I am in Spring, so I get the following exception:
org.thymeleaf.exceptions.TemplateProcessingException:
The expression used for object selection is *{shippingAddress},
which is not valid: only variable expressions (${...}) are
allowed in 'th:object' attributes in Spring-enabled environments.
(include:510)
at org.thymeleaf.spring4.processor.attr.SpringObjectAttrProcessor.validateSelectionValue(SpringObjectAttrProcessor.java:73)
at org.thymeleaf.standard.processor.attr.AbstractStandardSelectionAttrProcessor.getNewSelectionTarget(AbstractStandardSelectionAttrProcessor.java:69)
at org.thymeleaf.processor.attr.AbstractSelectionTargetAttrProcessor.processAttribute(AbstractSelectionTargetAttrProcessor.java:61)
To move forward I must duplicate all my nested templates. In this example, I would have one person.html with th:object="${person.mailingAddress}" calling to address.html, and a duplicate of person.html called orderCustomer.html where we change the line to th:object="${order.customer.mailingAddress}", but is otherwise identical.
Is there a work-around out there that would let me re-use templates?
You can report a bug to the thymeleaf developers in github, or fork the project to add this functionality and convince the Daniel Fernández to accept it.
https://github.com/thymeleaf/thymeleaf/issues
Or else, he is available in StackOverflow. You can simply send him a message about the posibility of integrating this functionality
https://stackoverflow.com/users/550664/daniel-fern%C3%A1ndez
apart from that there is nothing much we can do rather to stick with the approach of putting th:object="${person.mailingAddress}" and th:object="${order.customer.mailingAddress}" outside each import.
I am using Spring 3.0.6 and their tag library. I am using the form:checkbox tag. From what I read and researched, it is supposed to create a hidden field with the same name and a leading _ character. This tells spring whether the checkbox was checked or not so that it will properly set my model attribute when the checkbox is not checked or when it is disabled.
The problem is that I am not seeing a hidden field created for my form:checkbox. I thought it might be my version of Spring, but I saw another post where a developer appeared to be using Spring 3.0.5 and it was generating the hidden field for him.
Here is a code snippet from my JSP where I create the checkbox.
<form:checkbox path="contactInformation.optOutOfProgram" value="Y" id="chkOptOutOfProgram" disabled="true" />
Here is the resulting HTML that is generated:
<input id="chkOptOutOfProgram" name="contactInformation.optOutOfProgram" disabled="disabled" type="checkbox" value="Y"/>
There is no hidden field with the name _contactInformation.optOutOfProgram generated on the page. I read that I could manually code this but I also read it is supposed to automatically create the hidden field.
I found the issue when looking at the Tutorials that Braj pointed out even though the Tutorial does no explicitly explain this. One of the things that is different from my code and the code in the tutorials as well as all of the other code that I saw in my research is that I have disabled="true" in my form:checkbox declaration. I disable it using jQuery based on stuff entered by the user in other fields. Apparently if you set the field using the disabled attribute for the form:checkbox Spring tag, it does not generate the hidden field. As soon as I removed that from form:checkbox, the generated html content had the hidden field.
I guess I need to report that as a possible bug to the Spring developers.
In PHP we can do the following with the help of Variable variables in PHP:
$privateVar = 'Hello!';
$publicVar = 'privateVar';
echo $$publicVar; // Hello!
Suppose we have the following chunk of Java code:
request.setAttribute("privateVar", "Hello!");
request.setAttribute("publicVar", "privateVar");
I've tried the following but an error occurs.
${${publicVar}}
Does anyone know how we can get value of privateVar via using only publicVar in JSP (JSTL)?
UPDATE 1:
I have a custom tag which allows to print a message if an object foo doesn't have a field bar.
I know I must catch exceptions in the case but I don't want to handle ones in JSP. I want to do it only in CustomTag file.
<%-- JSP file --%>
<ctf:tagName varName="foo.bar" />
<%-- CustomTag file --%>
<%# attribute name="varName" required="true" rtexprvalue="true"%>
<c:catch var="exception">
<c:set var="valX" value="${${varName}}" scope="page"/>
</c:catch>
<c:if test="${exception != null}">Can't find getter for the VAR in the OBJ.</c:if>
UPDATE 2:
JB Nizet gave me the answer and the following works well! :)
<c:set var="privateVar" value="Hello!" />
<c:set var="publicVar" value="privateVar" />
${pageScope[pageScope.publicVar]}
I don't think you can directly do this in the same way that you can in PHP. Instead you could change the attribute to use the value of the privateVar instead of the name, like this:
String privateVar = "Hello!";
request.setAttribute("privateVar", privateVar);
request.setAttribute("publicVar", privateVar);
This gives you access to the value under both names, which I think is the closest you'd get. No need to even put the attribute privateVar in the request if you are ultimately going to use publicVar on the JSP.
Ultimately you may want to rethink the design here as it doesn't really work in Java.
The basics:
That's not JSTL but Expression Language. And you should only use a single ${} evaluator. The code would be:
${publicVar}
More info:
StackOverflow Expression Language wiki
To your problem:
Expression Language doesn't allow that. You cannot have private attributes in any scope (page, request, session, application), so you can at most set the attribute twice with different names but the same value. But as you may note, this is useless.
I have a Stripes JSP with a <stripes:form> tag etc.
I have a line like the following one:
<span class='amount'>
<fmt:formatNumber value="${MyJavaClass.amount}" type="number"/>
</span>
I know this is working fine in combination with the corresponding Stripes Action Bean.
Now I want to format that "amount" variable in a different way, i.e. being sure that at least 2 decimals are used.
For example:
199.1 becomes 199.10
362.44 remains 362.44
I thought that adding a formatPattern="decimal" would have been enough, according to Stripes documentation.
Please note that I want to keep the "number" format type, I do not want to change it to be a currency type.
Actually I am experiencing errors like the following one:
org.apache.jasper.JasperException: /MyJSPPath/MyJSP.jsp(19,6) Attribute formatPattern invalid for tag formatNumber according to TLD
How can I fix it?
I fixed it setting properly the pattern parameter.
<fmt:formatNumber value="${MyJavaClass.amount}" type="number" pattern="#.00"/>
This was not enough:
<fmt:formatNumber value="${MyJavaClass.amount}" type="number" maxFractionDigits="2"/>
The issue related to only one digit was still there (i.e. "199.3" was still "199.3", rather than "199.30")
How can I check for a particular error on a JSP page and only show it when it is present.
For example I would like to check whether the following error exists using <c:if> tag and only then render it as HTML.
<form:errors path="transactionType" cssClass="error"></form:errors>
Use the <spring:hasBindErrors name="myFormBean"> tag, and inspect the page-scope errors bean.
Reference doc link
You already get this functionality with the <form:errors> tag. It only renders its contents when there is a corresponding error (based on the path attribute), so it is analogous to using a <c:if> to first check for an error.