How can I use Java's constants value as th:value name? - spring

I have a constant for a name.
public static final NAME_SOME = "some"
In my html I tried,
<input th:value="${T(the.package.TheClass).NAME_SOME}"/>
I expected the actual value from the model named by some.
Yet I see value=some.
How can I fix this?

It's a bit unclear what you're asking. The expression <input th:value="${T(the.package.TheClass).NAME_SOME}" /> should indeed evaluate to <input value="some" />. You mean you have a form with a model object and you want to bind it to the expression model.some? You can use preprocessing to do that, I think...
<input th:field="*{__${T(the.package.TheClass).NAME_SOME}__}" />

Related

Why does the Spring form:hidden tag print two value attributes?

Basic question, but haven't found any other relevant posts on SO.
I have this Spring code in my JSP with a property called vacant:
<form:hidden path="vacant" value="false"/>
And here is the generated output:
<input id="vacant" name="vacant" value="false" type="hidden" value=""/>
Why would value get printed twice with an empty second one?
(It's relevant because I'm trying to use the value in some Javascript.)
What you're seeing is "normal". According to the doc:
This tag renders an HTML 'input' tag with type 'hidden' using the
bound value
Let's assume vacant is Boolean vacant; in your DTO, since its value is null, the tag'll print it as value="". In addition, it'll print any other field you pass to it, e.g:
<form:hidden path="vacant" my-field="test"/>
<input id="vacant" name="vacant" my-field="test" type="hidden" value=""/>
So if you happen to use value in <form:hidden path="vacant" my-field="test" value="true"/>, it'll consider it an additional field:
<input id="vacant" name="vacant" my-field="test" value="false" type="hidden" value=""/>
Here is what happens in the source:
org.springframework.web.servlet.tags.form.HiddenInputTag
protected int writeTagContent(TagWriter tagWriter) throws JspException {
...
writeDefaultAttributes(tagWriter); // *) Here it'll print the value that you passed to the tag
...
//The next two statements get the bound value of vacant (null) and print it as value=""
String value = getDisplayString(getBoundValue(), getPropertyEditor());
tagWriter.writeAttribute("value", processFieldValue(getName(), value, "hidden"));
*) writeDefaultAttributes() calls writeOptionalAttributes(), where your passed value is printed (it's in this.dynamicAttributes along with my-field):
if (!CollectionUtils.isEmpty(this.dynamicAttributes)) {
for (String attr : this.dynamicAttributes.keySet()) {
tagWriter.writeOptionalAttributeValue(attr, getDisplayString(this.dynamicAttributes.get(attr)));
}
}
So, http:input is intended to be used for bound values, so set the value you need in the DTO before rendering the JSP.

Thymeleaf, Spring nested backing object is not binding the values on form submit

I have a nested object and I'm using it as a model for a form.
public AgeBracketSet implements Serializable{
private String id;
private List<AgeBracket> ageBrackets;
/* Getters and Setters */
}
I have successfully bound all the properties of this object to the form and I can visualize their values when the view state is rendered. Here's a simplified version of how I'm doing it with Thymeleaf. Essentially, I loop through the items of the list and get their attributes.
<form id="bracketForm" role="form" th:action="${flowExecutionUrl}" th:object="${ageBracketSet}" method="post">
<input th:id="'bracketSet_'+*{id}" th:field="*{id}" />
<th:block th:each="bracket,loop : *{ageBrackets}" th:id="'bracket_'+${bracket.id}">
<input th:id="'fromAge_'+${bracket.id}" th:field="*{ageBrackets[__${loop.index}__].fromAge}" />
<input th:id="'toAge_'+${bracket.id}" th:field="*{ageBrackets[__${loop.index}__].toAge}" />
</th:block>
</form>
However, when I make changes in the form and submit it, the model remains unchanged. I have confirmed this by debugging the service that receives the form data. The model does not have the changes made in the form. Am I doing anything wrong here?
I am embarrassed to say I've found the solution. The values simply weren't posted to the webflow for a lack of a 'name' attribute in each input. Using the same dynamically generated ID as a name did the job, and the bindings were correct for each item of the list. Like this:
<input th:id="'fromAge_'+${bracket.id}" th:name="'fromAge_'+${bracket.id}" th:field="*{ageBrackets[__${loop.index}__].fromAge}" />
Thanks to everyone who took the time to read this silly post. I'll be more careful next time ;)

Ajax.BeginForm with Collection

Isn't that possible to use "Ajax.BeginForm" in a collection model? Form repeats itself, Html elements are rendered correctly, values are ok. However, all parameters going through action are being null.
I've realized that, it posts like that:
ProductList[0].Id 501
ProductList[0].quantity 1
However it should be like
Id 501
quantity 1
Any Ideas?
You should use prefix in UpdateModel function:
UpdateModel(MyModel, "MyModel")
I solved by using pure html, thanks anyway.
<input type="hidden" value="#Model.Id" name="Id"/>
<input type="text" value="" name="quantity"/>

Posting an array of Guid pairs to an Action

As you can see here, I'm allowing a user to dynamically create a table of data, and storing the ids of the table in a hidden field (in the example it's a text area so you can see it, and the final solution will be Guid rather than integers).
My question is simply this: What data type should I use on the server/MVC action to take the data held in the textarea/hidden field?
At the moment I have a string, and am contemplating doing a load of .split()'ing and whatnot, but it doesn't feel right!
Ultimately I need some sort of IEnumerable<Guid, Guid> thing?!?! so I can do a foreach and get each pair of Ids.
I'm sure the answer will be simple, but I can't think of what to do.
Any help appreciated.
If your UI has multiple, like-named form fields, they will be submitted to your action method and bound properly to an array. We could use string[] for this case.
<form action="">
<input type="text" name="guids"/>
<input type="text" name="guids"/>
<input type="text" name="guids"/>
<input type="text" name="guids"/>
<input type="submit" value="Submit"/>
</form>
Then your controller could handle them like so:
public ActionResult MyAction(string[] guids)
{
guids.Count == 4 // if all four fields were filled in.
}
Note that if there is just a single guids value sent by the form, the string[] guids will still work - it will contain just a single item.
Finally, note that if no values are entered, the array value will be null, not an empty array.
You can actually bind to a list from your model, take a look at this post
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Dynamic fielderror struts2 validation

i'm dynamically generating fields (from a hashmap):
<s:iterator value="app.fields" status="field">
<s:set name="findex" value="%{'app.fields[' + #field.index + '].id'}"/>
<s:fielderror value="%{#findex}"/>
<s:textfield name="%{#findex}" />
</s:iterator>
This method sets up the textfield ok:
<input type="text" id="saveapp_app_fields_1__id" value="[DE]Enter an ID" name="app.fields[1].id">
but not the fielderror.
I add the fielderrors manually in the validate method. but all field errors get displayed n times for each fielderror tag. wich implies that what is actually happening is that the #findex seems to evaluate to null and i'm adding n <fielderror/> tags.
I could extract the field errors manulally in the jsp but was hoping for a more elegant solution.
Thanks in advance. Michael.
I've never seen a fielderror declared in that way. Perhaps try:
<s:fielderror>
<s:param value="%{#findex}" />
</s:fielderror>

Resources