keeping track of multiple related input boxes using spring mvc - java

we have a list of domain objects needing to be edited on an html page. For example, the command & domain objects:
class MyCommand {
List<Person> persons;
}
class Person {
String fname;
String lname;
}
Then, the HTML I expect to have the Spring MVC tag libraries generate is like this:
<form>
<input name="persons[0].fname"> <input name="persons[0].lname"><br/>
<input name="persons[1].fname"> <input name="persons[1].lname"><br/>
<input name="persons[2].fname"> <input name="persons[2].lname"><br/>
...
<input name="persons[n].fname"> <input name="persons[n].lname"><br/>
</form>
But can't see how to express this using the Spring Form Tag Libraries (using Spring 2.5.6.). I want to use the tag libraries so that it takes care of binding existing values to the tags for editing (when they're there).
Any tips?

There isn't a way to simply have the Spring Form Tags generate the whole list based on the collection (it will do this for the options in a select box, but that's the only collection-based expansion I'm aware of). However, you can still use the Spring Form Tags within a loop like so:
<c:forEach var="person" varStatus="loopStatus" items="myCommand.persons">
<form:input path="persons[${loopStatus.index}].fname" /> <form:input path="persons[${loopStatus.index}].lname" /><br />
</c:forEach>

Related

Put a form key-values subset in a scope parameter

I've got a form (not linked with Spring pojos) with questions and answers.
I want to retrieve a String which contains only the key-values, like Q1=A1_3&Q2=A2_1 and so on. I was doing that using Spring #RequestBody annotation.
The problem is that if I put an hidden field ("code") in the form, I'll get its value at the end of this string, and I don't want to mix the questions-answers key-values with the hidden field value.
This is my JSP:
<form name="pollform" method="post" action="1/submitpoll.do">
<input type="hidden" name="code" value="C1"></input>
<h4>T1Q1. How do you blabla?</h4>
<input type="radio" name="Q1" value="A1_1">Very Good</input><br/>
<input type="radio" name="Q1" value="A1_2">Could be better</input><br/>
<input type="radio" name="Q1" value="A1_3">Bleah.</input><br/>
<h4>T1Q2. Are you even bliblibli?</h4>
<input type="radio" name="Q2" value="A2_1">Yes sure</input><br/>
<input type="radio" name="Q2" value="A2_2">Not everytime</input><br/>
<input type="radio" name="Q2" value="A2_3">Never</input><br/>
<input type="submit" value="Submit"/>
</form>
This way, using #RequestBody in my controller I'll get something like Q1=A1_2&Q2=A2_3&code=C1 (and it's not what I want since I have to convert the result string in a HashMap later).
So, how can I get only the questions key-values of the form, excluding the hidden input value?
Should I use jstl or something else?
If you need map of question-answer pairs and the hidden code parameter, I suggest to introduce model object, which will contain the code and the map, and let the spring make the mapping for you. Checkout this example. There is map of contact details to be saved by controller, similar to your map of answers to questions.

How to bind a comma separated string to a Java collection (List) in Spring form?

I'm stuck in a situation where I've an input element in a JSP where user enters tags. E.g. java, foo, bar, anotherTag..etc
<c:url var="saveUrl" value="/create" />
<form:form modelAttribute="myAttribute" method="POST"
action="${saveUrl}">
<form:input path="myTitle" />
<form:textarea path="myPost" />
<form:input type="text" id="tagInput"path="???" />
<input type="submit" value="create" />
</form:form>
Now in my domain model corresponding to this input is a
private List<Tag> listOfTags
How to bind a csv to a List. If I enter listOfTags in the path(which is wrong for obvious reasons), I get incorrect binding exception.
How do I convert(or bind) a csv to a List so that the Spring form is submitted properly and the listOfTags get the tags entered in the JSP.
What is the best way to achieve it?
Please help.
I'm not sure but try this. Do a simple html input :
<input type="text" id="tagInput" name="myTags" />
And then in your controller do something like :
#RequestMapping(value="/create", method=RequestMethod.POST)
public void create(..., #ModelAttribute("myAttribute") MyClass myAttribute,
#RequestParam("myTags") String myTags, ...) {
...
myAttribute.setListOfTags(Arrays.asList(myTags.split(",")));
...
}
Note : for more generic ways to bind and convert objects, you may want to take a look at PropertyEditors and Converters.
I suggest try to bind it directly to listOfTags property. And to make it work just add contructor with one argument of String type (or define static method valueOf(String)) to Tag class.
Pretty sure you could do something like this:
<c:forEach var="i" begin="1" end="10">
<form:input type="text" path="listOfTags" />
</c:forEach>
Where you get the user to enter each tag into a separate text input. This is because Spring will automagically bind multiple inputs with the same form name to a List, when it does its binding.
You could use some jQuery sugar to only show one or two and then provide a widget to show more tag inputs. Or even write some cool JS to populate the inputs from a single text input just like StackOverflow does when you add tags.

Possibility to get all form inputs from several layers of panels and forms

Kinda new to wicket and im wondering if its possible to use a AjaxButton in order to get form values from forms within the first form...
For example, using the "ajaxButton" below would it be possible to also get the value of "anothervalue" even though its not in the same form?
<form>
<input type="submit" wicket:id="ajaxButton" />
<input type="text" wicket:id="aValue" />
<panel>
<form>
<input type="text" wicket:id="anothervalue" />
</form>
</panel>
</form>
Wicket supports nested forms. When you submit the outer form, the inner one should also processed (validate params, update models).

What is <spring:bind> for? When to use it, and when not to use it?

I am having problems with submitting form data in spring. <spring:bind> seems to be a part of the solution. See my full problem here.
The documentation of BindTag found here is not clear to me. Why is <spring:bind> needed in some cases to submit data, while it is not needed in most cases?
What are the typical cases where the <spring:bind> must be used in order for a form to function properly?
You will find the tag <spring:bind> useful when you want to parse multiple objects from an input form. Here's a modified example from the Spring's doc (http://docs.spring.io/spring/docs/1.2.6/taglib/tag/BindTag.html):
<form method="post">
## now bind on the name of the company
<spring:bind path="company.name">
## render a form field, containing the value and the expression
Name: <input
type="text"
value="<c:out value="${status.value}"/>"
name="<c:out value="${status.expression}"/>">
</spring:bind>
<spring:bind path="address.street">
Name: <input
type="text"
value="<c:out value="${status.value}"/>"
name="<c:out value="${status.expression}"/>">
</spring:bind>
<input type="submit">
</form>
Although I've never used this tag myself, my understanding of the documentation is this. A tag will provide you with information about the binding status of a form property to a bean. For example in:
<form:form modelAttribute="employee">
<form:input path="name"/>
<spring:bind path="name"/>
<spring:bind path="employee"/>
</form:form>
The tag will display (or expose through a BindStatus object) all errors that have occurred with the name attribute (the first case) and all errors on the Employee entity and its attributes (the second case). I am not sure that this tag has anything to do with the succesfulness of submitting data, but rather that it's used as an information tool.

How to POST multiple "record sets" from an HTML Form to JSP or a Java Servlet?

Does JSP or any related lightweight technology like JSTL perform HTTP POST "data grouping", or support form element "indexing" in the way PHP does?
For example, you can create an HTML form with the following inputs:
<input type="text" name="person[1][name]" />
<input type="text" name="person[1][age]" />
<input type="text" name="person[2][name]" />
<input type="text" name="person[2][age]" />
... and PHP will parse that into a nested associative array automatically. Do JSP, Java Servlets, or any related spec or tool provide this kind of translation out of the box?
The goal is to submit multiple "record groups" in a single form, and process them server-side in JSP or a Servlet.
Requirements:
The functionality cannot rely on JavaScript
No full frameworks like Spring, Struts, or the like
I'm trying to avoid reinventing the wheel with my own naming convention and manual String parsing / Regex
Related Links:
How this is accomplished in PHP
Another PHP example from ONLamp
Try this,
<input type="text" name="personNames" />
<input type="text" name="personAges" />
<input type="text" name="personNames" />
<input type="text" name="personAges" />
You should consider to create input fields using a loop, you don't need to postfix the name even. and get parameter values like this in your servlet,
String[] names = request.getParameterValues("personNames");
String[] ages = request.getParameterValues("personAges");
It will come in the same order as defined in your HTML. Then loop over it like below,
for( String name : names) {
System.out.println(name);
}

Categories