Populate List<String> in struts2 from form data

10,325

I believe as you have it, your jsp code would render something like:

<input type="text" name="strings[0]" style="width: 5em" value="1"/>
<input type="text" name="strings[1]" style="width: 5em" value="2"/>
<input type="text" name="strings[2]" style="width: 5em" value="3"/>
...

Notice that the name of the field references are "strings[x]" where as you need the name to be just "strings". I would suggest something like:

<s:iterator value="strings" status="stringStatus">
   <s:textfield name="strings" value="%{[0].toString()}" style="width: 5em" />
</s:iterator>

Not sure if the value attribute above may is correct, but I think something like this will get you the desired result.

Share:
10,325
Chris
Author by

Chris

Updated on June 04, 2022

Comments

  • Chris
    Chris almost 2 years

    I feel this should be exceedingly obvious, but so far I've failed to find an answer.

    I want to have a list of strings (or an array of strings, I really don't care) get populated by form data in Struts2.

    I've seen several examples of how to do indexed properties with beans, but wrapping a single string inside an object seems fairly silly.

    So I have something like

        public class Controller extends ActionSupport {
    
            private List<String> strings = new ArrayList<String>();
            public Controller() {
                strings.add("1");
                strings.add("2");
                strings.add("3");
                strings.add("4");
                strings.add("5");
            }
            public String execute() throws Exception {
                return ActionSupport.SUCCESS;
            }
            public List<String> getStrings() {
                return strings;
            }
    
            public void setStrings(List<String> s) {
                strings = s;
            }
        }    
    

    ...

    <s:iterator value="strings" status="stringStatus">
       <s:textfield name="strings[%{#stringStatus.index}]" style="width: 5em" />
    </s:iterator>
    

    The form fields get populated with their initial values (e.g. 1, 2, etc), but the results are not properly posted back. setStrings is never called, but the values get set to empty strings.

    Anybody have any idea what's going on? Thanks in advance!

  • Chris
    Chris about 13 years
    That works, thanks! It seems odd that you have to specify the value for what seems to be the simple case, but not for beans. shrug Also, when you say that 'the name of the field references are "strings[x]" where as you need the name to be just "string,"' I'm assuming you mean "strings"...? Finally, the former would be the correct format for beans, right (e.g. people[0].name with ArrayList<Person> people)?
  • Quaternion
    Quaternion about 13 years
    Please mark this answer as solved if it has solved the issue.
  • Chris
    Chris about 13 years
    @Quaternion: Already done. Though he (seemingly inadvertently) edited out the key part of his solution; that is, the value should be along the lines of %{getStrings().get(#stringStatus.index)}
  • nmc
    nmc about 13 years
    @Chris:I'm not sure the value field has to be that complex. Did you try it with just the value="[0]"? I forgot when I initially posted the answer that it's in an iterator loops which may remove the need for the complex %{getStrings().get(#stringStatus.index)}
  • Quaternion
    Quaternion about 13 years
    Yes the expression should be reducible to at least value="%{[#stringStatus.index]}", and you should be able to drop the %{} because the should assume OGNL in this case.
  • Chris
    Chris about 13 years
    Unfortunately that (and a large number of 'simpler' things I tried with and without braces) didn't work.
  • Quaternion
    Quaternion about 13 years
    You are right, the reason is that the iterator is pushing the string onto the stack, so you'll see inside the iterator <s:property/> will render the string, I should have really tested first! I will test something, that should make this much shorter.
  • Quaternion
    Quaternion about 13 years
    Well just for educational value... this also works, but it isn't as short as I'd like: <s:iterator value="strings" status="stat"><s:textfield name="[%{#stat.index}]" value="%{#this.toString()}"/></s:iterator>
  • nmc
    nmc about 13 years
    @Quaternion: Thanks for that idea. I corrected the answer above and it should now work and is slightly simpler than what I had originally posted and hopefully makes more sense.
  • Chris
    Chris about 13 years
    @nmc: I assume you meant value="%{#this.toString()} ?