Struts logic:iterate input field

22,300

Solution 1

So this is tricky, because there are many things to get done in order for it to work. First, declare your tags inside the iterator with the html tags, with attribute INDEXED=TRUE and an ID DIFFERENT THAN THE NAME, i also took out the "indexId" attribute to use the simple "index" word for the index:

<logic:iterate name="myList" id="myListI"   type="com.mycompany.MyBean">  
<tr>  
    <td> <html:input name="myListI" property="weight"  indexed="true"/> </td>  
    <td> <html:input name="myListI" property="sku"  indexed="true"/> </td>  
    <td> <html:input name="myListI" property="quantity"  indexed="true"/> </td>  
</tr>  

after that, in order for struts to be able to get and set the attributes of your beans, you need to declare EXTRA get and set methods inside your collection object, using the name you wrote in the id of the iterate tag. In this case, you would write 2 extra get and set methods for the "myListI" :

public void setMyListI(int index, myBean value){
    this.myList.add(value);
}
public myBean getMyListI(int index){
    return this.myList.get(index);
}

Solution 2

I think Th0rndikes answer is mostly correct. My implementation is slightly different, so it might be worth trying this as well.

Form

private List<Parameter> activeParameters;

public List<Parameter> getActiveParameters() {
    return activeParameters;
}

public Parameter getParam(int index){
    return this.activeParameters.get(index);
}

JSP

<logic:iterate name="MyForm" property="activeParameters" id="param">
  <tr>
    <td><bean:write name="param" property="prompt"/></td>
    <td><html:text name="param" property="value" indexed="true"/></td>
  </tr>
</logic:iterate>

In summary, I didn't use Type in the iterate tag, using the property tag instead. In the bean adding a getter with matched the name of the iterate ID in the JSP (param) with an index as a method parameter did the trick.

Solution 3

Take a look at this: http://wiki.apache.org/struts/StrutsCatalogLazyList

Indexed Properties

Struts html tags have an indexed attribute which will generate the appropriate html to populate a collection of beans when the form is submitted. The trick is to name the id attribute to the same as the indexed property.

For example the following jsp...

   <logic:iterate name="skillsForm" property="skills" id="skills">

       <html:text name="skills" property="skillId" indexed="true"/>

   </logic:iterate>

...will generate the following html

<input type="text" name="skills[0].skillId value="..."/>
<input type="text" name="skills[1].skillId value="..."/>
....
<input type="text" name="skills[n].skillId value="..."/>

When the form is submitted BeanUtils will first call the getSkills(index) method to retrieve the indexed bean followed by setSkillId(..) on the retrieved bean.

Solution 4

Theoretically, the indexed attribute of the struts html tags could be used for this:

Valid only inside of logic:iterate tag. If true then name of the html tag will be rendered as "id[34].propertyName". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag.

But, there is no corresponding indexed attribute on the html:errors tag, which limits its usefulness. Also, the required combination of id, name and property attributes can be rather confusing.

I found it easier to use jsp scriptlets to generate the property name including the iteration index. The following code requires that your form has a string array property "quantity".

<% int idx=0; %>
<logic:iterate ...>
    <html:text property='<%= "quantity[" + idx + "]" %>'/>
    <html:errors property='<%= "quantity[" + idx + "]" %>'/>
    <% i++; %>
</logic:iterate>
Share:
22,300
LatinCanuck
Author by

LatinCanuck

Updated on July 09, 2022

Comments

  • LatinCanuck
    LatinCanuck almost 2 years

    I currently have the following code and the data is displayed fine.

    <logic:iterate name="myList" id="product"  indexId="iteration" type="com.mycompany.MyBean">  
        <tr>  
            <td> <bean:write name="product" property="weight"/> </td>  
            <td> <bean:write name="product" property="sku"/> </td>  
            <td> <bean:write name="product" property="quantity"/> </td>  
        </tr>  
    </logic:iterate>  
    

    But now I need to make the "quantity" part modifiable. The user should be able to update that field, press submit and when its sent to the server, "myList" should automatically update with the new quantities.

    I've tried searching for help on this but all I keep finding is examples on how to display data only, not modify it. Any help would be appreciated.

  • LatinCanuck
    LatinCanuck about 12 years
    Hi, only quantity should be modifiable, the rest should stay as read only. What tag should I use for those?
  • Th0rndike
    Th0rndike about 12 years
    just play with it. Use the bean:write tags for what should not be modified, or an html:input which has been disabled. There are many ways of accomplish this, it's up to you how to implement it.
  • javatestcase
    javatestcase over 11 years
    excellent answer. In my case I needed the getNameOfId(int index) for the solution to work, but I post that solution separately for reference. Thanks!
  • Marinha do Nascimento
    Marinha do Nascimento almost 6 years
    más 10 lince ❤️❤️❤️