Struts logic:iterate input field

2020-02-29 05:52发布

问题:

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.

回答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);
}


回答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.



回答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.



回答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>