Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Handle a form submission with unknown form fields

 
Ryan Silva
Greenhorn
Posts: 7
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm happily using struts2 and providing setters for all my form fields. But now I'm writing a form which allows a user to upload multiple files. I can't provide setters for each field because I don't know how many fields there will be. (Picture gmail, where you could upload multiple files).

I would like to keep the action class from being request-aware.

Is there any way to do this? Maybe if I could give my fields a similar naming pattern and they got passed to the struts action as an array?

Thanks

Ryan
 
Tom Rispoli
Ranch Hand
Posts: 349
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I haven't done this with files before, but I assume its the same as the way you do it with other input fields. You need to define an array or a collection that can be accessed by getters and setters (indexed and non-indexed ones) through your action class. I believe the type of objects in the collection will need to be a bean (I've never had occasion to do it any other way, but I think it is a rule), these objects will need a getter and setter for the file. On your page, when you add new files to be uploaded you'll need to put the index that you want to use for the file in the name of your input filed like this:

name="myCollection[myIndex].file"

so myCollection should be the name of the collection, myIndex should be an Integer representing what index in the collection the file should go in, and the objects in your array/collection should have a setFile method to take in the new file object.

so in your html the name of the first input filed should be:

name="myCollection[0].file"

Hope this helps
 
Ryan Silva
Greenhorn
Posts: 7
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the reply.

I'm a little hazy on how this works. I put three fields in my form:

<input type="hidden" name="fields[0].title"" value="A" />
<input type="hidden" name="fields[1].title"" value="B" />
<input type="hidden" name="fields[2].title"" value="C" />

And in my class I have a getter getFields(). I debugged it and it gets called 3 times. The object it returns has a setTitle(String title) method but it never gets called. So I guess I'm not sure where struts knows to create an array of size 3, even though it doesn't even know what class is in the array.
 
Tom Rispoli
Ranch Hand
Posts: 349
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That property of your action class that you named "fields" should be an array or a collection. In addition to a getter and a setter for this array you should have an indexed getter and setter, they should take in an extra parameter that is an int, representing a position in the collection (in the case of the setter, the int should come before the value being set). Also, in your getter and setter you'll probably need to add some code to make sure that the element at the specified position is not null and create the object if it is null.

I believe when the values in your action class are populated from the html form, struts will do something like this for these input fields:

yourForm.getFields(0).setTitle("A");
yourForm.getFields(1).setTitle("B");
yourForm.getFields(2).setTitle("C");
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You don't need an indexed getter or setter; there only needs to be a collection or an array property. You *can* used indexed properties like that, and use parentheses in the OGNL expression (as opposed to brackets), but I'm not convinced it'd be useful in a simple usecase like this one. I'm not even sure the array notation is necessary anymore, but that may have been a version-specific thing--but I know at one point when I had multiple fields with the same name it put them into a collection for me.

(Obviously if order is important the browser ordering shouldn't be relied upon.)
 
Ryan Silva
Greenhorn
Posts: 7
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
David Newton wrote:You don't need an indexed getter or setter; there only needs to be a collection or an array property. You *can* used indexed properties like that, and use parentheses in the OGNL expression (as opposed to brackets), but I'm not convinced it'd be useful in a simple usecase like this one. I'm not even sure the array notation is necessary anymore, but that may have been a version-specific thing--but I know at one point when I had multiple fields with the same name it put them into a collection for me.

(Obviously if order is important the browser ordering shouldn't be relied upon.)
If you don't need an indexed getter/setter, how is struts filling the array? I saw struts calling getFields() three times, so it wasn't like it called getFields() once and filled it up with the 3 values.
 
Ryan Silva
Greenhorn
Posts: 7
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To answer my own question, when I changed the form names to be identical (instead of specifically providing indexes), struts filled the array itself. Now I just need to try with files.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic