#spring.formInput in #list iterator - spring-mvc

<#list flowList as flow>
<#spring.formInput "flow.createDatetime" />
</#list>
flowList is arrayList.
freemarker.template.TemplateModelException: Method public org.springframework.web.servlet.support.BindStatus org.springframework.web.servlet.support.RequestContext.getBindStatus(java.lang.String) throws java.lang.IllegalStateException threw an exception when invoked on org.springframework.web.servlet.support.RequestContext#8bc713e with arguments of types [java.lang.String,]
at freemarker.ext.beans.OverloadedMethodModel.exec(OverloadedMethodModel.java:134)
at freemarker.core.MethodCall._getAsTemplateModel(MethodCall.java:93)
How can I resolve #spring.formInput in #list.

Have you tried doing an intermediate assign? I saw this problem on other StackOverflow pages, like Freemarker syntax for a form for a collection of objects (Spring 3 MVC):
<#list flowList as flow>
<#assign flowDate = flow.createDatetime />
<#spring.formInput "flowDate" />
<\#list>

The following workaround works for me, but is pretty ugly:
<#list flowList as flow>
<#assign index=flowList?seq_index_of(flow)>
<#spring.formInput "flowList[${index}].createDatetime" />
</#list>
When the above form is posted, you'll need to ensure that the flow-list is pre-populated with empty flows. Alternatively, just using Spring's AutoPopulatingList as the flow-list implementation.

For spring to bind the object, the exact reference must be provided. Hence you need to add the index in the tag. This is needed when you post the form back and want the flowlist object as request body in a controller method.
<#list flowList as flow>
<#spring.formInput "flowList[${flow_index}].createDatetime" />
</#list>
After rendering if you look at the HTML it would be like
<input type="text" id="flowList0.createDatetime" name="flowList[0].createDatetime" value="..." />

Related

Pass loop variable from Freemarker template to Spring controller

I am listing objects in a table in my view. I want to be able to edit an object using a button in the table.
<#list products as product>
<tr>
<td>${product.productName}</td>
<td>${product.price}</td>
<td>${product.quantity}</td>
<td>
<form name="product" method="post" action="/product/edit">
<input type="submit" name="submit" value="Edit this product"/>
</form>
</td>
</tr>
</#list>
The object then should be passed to a controller method:
#RequestMapping(value="/edit", method = RequestMethod.POST)
public ModelAndView edit(#ModelAttribute("product") Product product){
ModelAndView mav = new ModelAndView("product/edit");
mav.addObject("product", product);
return mav;
}
However, the product obtained by the edit method is null. How do I fix this? I tried to bind the product inside form using the code below, but that did not work either.
<form name="product" method="post" action="/product/edit">
<#spring.bind "product" />
<input type="hidden" name="${spring.status.expression}" value="${spring.status.value}"/>
<input type="submit" name="submit" value="Edit this product"/>
</form>
I want to use the POST method.
I would like to suggest a different approach. If I'm not mistaken you just want to pick an object for later editing - you don't really edit it in that very view.
If so, all you have to do is to pass an identifier of your object to your controller, but not the selected object itself.
If not, you should give us the hole story and provide the rest of the view as well.
Assuming I'm right the next question is why you need to use a form submission at all. Passing an id is best done by links - either as parameter or, if you follow REST-style, as part of the URI itself:
<!-- Link parameter -->
<#list products as product>
<tr>
<td>${product.productName}</td>
<td>${product.price}</td>
<td>${product.quantity}</td>
<td>
Edit ${product.productName}
</td>
</tr>
</#list>
<!-- REST-style -->
...
Edit ${product.productName}
...
productName isn't a good id of course. If products is a list (meaning, java.util.List) the index of the list is handy. Even in a HashMap or Set I'd create a unique id instead of using the product name.
Now that you can identify your object, select it in the backing code for later editing, but not in the view.
You'll find loads of examples of how to get link parameters in a controller. So, no need to go into detail here.
If however you insist on using a form and a POST-method then do it like this:
<form method="post" action="/product/edit">
<#list products as product>
<tr>
<td>${product.productName}</td>
<td>${product.price}</td>
<td>${product.quantity}</td>
<td>
<button value="${product.productName}" name="product" type="submit">Edit ${product.productName}</button>
</td>
</tr>
</#list>
</form>
Note that this won't work for older IE browsers (below Ver. 10), because they don't return the value, but everything that is inside the button tag.
Hidden inputs and a single submit button won't help at all, because all inputs are submitted and using different forms is not the way either.

struts2 s:radio cssClass and cssStyle add attribute twice

I would put my JSP file in HTML5 format.
I have a problem with the tag struts radio button;
when I put cssclass"disabled" ( or other like cssClass"red" ) , when I look the source I get twice attribute class="disabled".
But It works nice for the other struts tag.
See example below:
JSP file:
<s:radio cssClass="disabled" name="mirror.swiBlo" list="Y"/>
source:
<input type="radio" name="mirror.swiBlo" id="consultation_mirror_swiBloY" value="Y" class="disabled" class="disabled"/>
If someone has any idea to solve that.
Thanks
Actually it's a bug in struts.
In simple/radiomap.ftl setting of class and style occurs twice.
source code:
<#if parameters.cssClass??>
class="${parameters.cssClass?html}"<#rt/>
</#if>
<#if parameters.cssStyle??>
style="${parameters.cssStyle?html}"<#rt/>
</#if>
<#include "/${parameters.templateDir}/simple/css.ftl" />
And css.ftl handle class and style again.

MVC - Receive Form with Viewbag Variable from database and passing to the view

i have a html form into my database.
In this form i have a value which contains a Viewbag,
for example value="#Viewbag.MyVariable"
In my view when i try to receive my form all works fine,
but my problem is that the Viewbag value are not converting
to the value which comes from my controller.
any ideia how to resolve this ?
my code:
View:
#Html.Raw(p.Form)
My form in my database looks like:
<form action="/MyController/MyAction" method="post">
<input type="hidden" name="num" value="#ViewBag.num" />
....
....
....
</form>
What i have try to do was with:
Stringbuilder a=new Stringbuilder;
#Html.Raw(a.To.String())
Your code should technically work, if you are using MVC you could try
#MvcHtmlString.Create(p.Form);
I found a solution and now i solved it.
what i have done:
in my form the only part which are different from the others
forms are the dropdownlists.
i only put the part from <select> to </select> in my
database. (only the dynamically part of my form)
in my view i have write my form and only insert the variable
which comes from my controller to insert the data from my
database on the right part in my form.
here is the code:
<form action="/MyController/MyAction" method="post">
<input type="hidden" name="num" value="#ViewBag.num" />
#MvcHtmlString.Create(p.Form);
<button type="submit" name="submit" id="submit">OK</button>
</form>
So i have never more the problem with the variables to be
converted, because the variables are still the same

More than one form in one view. Spring web flow + displaytag + checkbox

I have a table, using display tag, in my application, that is using spring web flow. I would like to have a check box in each row, a button that allows me to select/uselect all and a button to execute a function. After clicking the button, the action will perform some database actions and the page should be render, so we can see these changes.
I don´t know which could be the best option, submitting the whole table
<form method="POST" (more params)>
<display:table id="row">
....
</display:table>
</form>
Or only the checkbox column. I this case I wouldn´t know how to implement it.
I have tryed two different approaches:
1. Using a simple input text, checkbox type. This is not possible, because when I submit the form, I need to set a path to another page.jsp (I am working with flows). Besides, I wouldn´t know how to send these values to java backend.
Using spring tags.
In this case, the problem comes whith the class conversationAction
I found some examples, but allways using MVC and controller cases.
How could I implement this issue??
EDIT
I have found a kind of solution, but I faced a new problem...
flow.xml
var name="model1" class="com.project.Model1"/>
var name="model2" class="com.project.Model2"/>
view-state id="overview" model="formAggregation">
...
</view-state>
page.jsp
form:form modelAttribute="formAggregation.model1" id="overviewForm">
...
/form:form>
...
form:form method="POST" modelAttribute="formAggregation.model2">
display:table id="row" name="displayTagValueList" requestURI="overview?_eventId=tableAction">
display:column title="">
form:checkbox path="conversationIds" value="${row.threadId}"/>
/display:column>
/display:table>
input type="submit" name="_eventId_oneFunction" value="Send>>"/>
/form:form>
FormAggregation.java
#Component("formAggregation")
public class FormAggregation {
private Model1 model1;
private Model2 model2;
//Getters and setters
I need this aggregator, because I need both models. I have tested it one by one and it is working as wished. Any idea about that??
Thanks!!
I couldn´t find a solution to add two model in a view-state. So I made a workaround, adding the fields I needed to the model I was using, com.project.Model1. So the result is:
page.jsp
<form:form method="POST" id="tableForm" modelAttribute="model1">
<display:table id="row">
<display:column title="">
<form:checkbox path="chosenIds" value="${row.id}"/>
</display:column>
<display:footer>
<div class="tableFooter" >
<input type="submit" name="_eventId_workIds" value="Send"/>
</div>
</display:footer>
</display:table>
</form:form>
flow.xml
<var name="model1" class="com.project.Model1"/>
...
<transition on="workIds" to="overview" validate="false">
<evaluate expression="actionBean.workIds(model1.chosenIds)" />
</transition>
java class
public void workIds(List<Long> ids) {
Hope it helps

Check Using JSTL regarding Spring Binding Error

I have been trying this for a while but can't find the right solution.
I want to use JSTL to check if there is any binding errors (field error or global error) that happened in my Spring MVC 2.5.
I know I can use this code:
<p>
<spring:hasBindErrors name="searchItems">
An Error has occured
</spring:hasBindErrors>
</p>
But I want to utilize JSTL to check for any errors.
I have tried this one using JSTL:
<c:if test="${not empty errors}">
An Error has occured
</c:if>
But it seems that I cannot catch it correctly.
I need to used JSTL since there are other parts of the JSP that relies on the presence or absence of a binding errors.
As said
I want to utilize JSTL to check for any errors
Just use (It just works on Spring MVC 2.5 - Not portable for Spring MVC 3.0 although i suppose it is requestScope['bindingResult.<COMMAND_NAME_GOES_HERE>.allErrors'])
<c:if test="${not empty requestScope['org.springframework.validation.BindingResult.<COMMAND_NAME_GOES_HERE>'].allErrors}">
An Error has occured!!!
</c:if>
Keep in mind default command name is The non-qualified command class name with The first letter lowercased. Notice bellow command name is pet
private PetValidator petValidator = new PetValidator();
#RequestMapping(method.RequestMethod.POST)
public void form(Pet command, BindingResult bindingResult) {
if(petValidator.validate(command, bindingResult)) {
// something goes wrong
} else {
// ok, go ahead
}
}
So your form should looks like
<!--Spring MVC 3.0 form Taglib-->
<form:form modelAttribute="pet">
</form:form>
<!--Spring MVC 2.5 form Taglib-->
<form:form commandName="pet">
</form:form>
Unless you use #ModelAttribute
#RequestMapping(method.RequestMethod.POST)
public void form(#ModelAttribute("command") Pet command, BindingResult bindingResult) {
// same approach shown above
}
This way, your form should looks like
<!--Spring MVC 3.0 form Taglib-->
<form:form modelAttribute="command">
</form:form>
<!--Spring MVC 2.5 form Taglib-->
<form:form commandName="command">
</form:form>
Something like this:
<spring:hasBindErrors name="userName">
<c:set var="userNameHasError" value="true" />
</spring:hasBindErrors>
<c:choose>
<c:when test="${userNameHasError}">
<%-- Display username as textbox --%>
</c:when>
<c:otherwise>
<%-- Display username as label --%>
</c:otherwise>
</c:choose>
You can probably also put a setup the errors to catch all errors on the page (untested):
<spring:hasBindErrors name="*">
<c:set var="userNameHasError" value="true" />
</spring:hasBindErrors>
Enjoy!
After playing around with <spring:hasBindErrors> tag, I found it had certain limitations:
It is useful only when there are errors.
org.springframework.validation.Errors object is only accessible inside the tag
What if just wanted to know if there are errors or not. If there are no errors, <spring:hasBindErrors> is rendered useless. After doing some research with my colleague, we printed out all the request attributes. Turns out there is an attribute called:
org.springframework.validation.BindingResult.command
The command object here is your form backing command object.
As unintuitive as it may be named, this attribute holds a reference to our Errors object.
Thus, this works:
${requestScope['org.springframework.validation.BindingResult.command'].errorCount}
and gives us a handle over the much sought after Errors object in JSTL

Resources