views:

933

answers:

3

I am trying to make a dynamic form using Spring forms. Basically, the form gets a title of learning activity and then there's the a button below it that says, "Add one more Learning Activity". This makes it possible for the user to add one more learning activity. I want him to be able to add as much as he likes.

I haven't tried this before so obviously I encountered errors with the first solution I thought of. I really had a feeling doing what I did will generate an error but just do drive home what I am trying to do, here's the code:

<script language="javascript">
 fields = 0;
 function addInput() {
      document.getElementById('text').innerHTML += "<form:input path='activity[fields++].activity'/><br />";
 }

<div id="text">
  <form:form commandName="course">
   Learning Activity 1 
   <form:input path="activity[0].activity"/>
    <input type="button" value="add activity" onclick="addInput()"/>
    <br/><br/>
   <input type="submit"/>
  </form:form>  
  <br/><br/>
 </div>
A: 

Is <form:input> a JSP tag? If so, then client-side Javascript to add <form:input> nodes to the DOM will have no effect - since the server-side JSP engine is not interpreting those.

Your Javascript needs to work with raw HTML and DOM, such as adding an <input> element.

matt b
Yes it's a jsp tag for Spring. I've thought of just brute-forcing the forms already by just getting the parameters from the request directly. However, I wanted to use Spring's SimpleFormController ability to bind the form fields to a command class. I was just wondering if there's a way to do it in my situation. Cheers!
Jeune
+3  A: 

You can't use <form:input> within the javascript because is a jsp tag that runs on the server-side.

However, there's nothing magical about how an HTML input gets bound to a field in the Spring command object; it's just based on the name. So in your javascript, add a new <input type="text" name="activity[1].activity"> (for example -- obviously you'll increment the index).

Another option I've used for more complicated controls is to grab the HTML of the existing control (which was created using the Spring form:input tag) and clone it, replacing the indexes with the incremented number. This gets a lot easier if you use jQuery.

EDITED TO ADD: One issue that may cause you problems: you're appending your new input box to the end of your outer div ("text"), which means it's not inside the form tags. That won't work.

JacobM
I tried doing this but the the values of the generated forms are not bound to the command class. Only the one that I explicitly set in the spring form is bound e.g In the code above: <form:input path="activity[0].activity"/>
Jeune
"One issue that may cause you problems: you're appending your new input box to the end of your outer div ("text"), which means it's not inside the form tags. That won't work." I addressed this already I appended the new input boxes inside another div within the form tags, still the appended input boxes don't bind.
Jeune
Can you give an example of your appended input box? I have used this approach to do exactly this and it does work. An input box named "activity[1].activity" should bind to the second item in your activity list (assuming it has an "activity" field), etc.
JacobM
I finally made it to work! Thanks a lot. :) Here's my blogpost about it: http://jeungun.wordpress.com/2009/09/18/binding-to-dynamically-generated-form-elements-in-spring-mvc/
Jeune
A: 

guys, how do you handle that form into the controller? Can you post also the controller's code?

jenue