Struts 1: form can read bean value but on submit does not write in it

5.1k Views Asked by At

Hello dear folks of stack overflow. I encountered a problem recently in my Struts application. I have a jsp which displays some bean value correctly (i paste only relevant part of the code, i simplified to the extreme):

<table>
    <logic:iterate name="bean" property="list1" id="listItem">
    <tr>
        <td>
            <html:checkbox name="listItem" property="selected">
            </html:checkbox>
        </td>
    </logic:iterate>
</table>

My bean has a list1 property with its getter and setter

private List<RandomObject> list1;

public List getList1() {
    return list1;
    }


public void setList1(List list1) {
    this.list1=list1;
    }

and my sub-bean has a selected property:

private boolean selected;
public boolean isSelected() {
    return selected;
}

public void setSelected(boolean selected) {
    this.selected = selected;
}

Now, when enter this jsp, the values i get are correct, ie: if my mapped object in DB was at selected=true, the checkbox is checked. What i dont get is how do i save the changes i make in this form. When i submit, all the changes are lost. This is pure struts related, because in debug when i enter the StrutsAction linked to submit, the ActionForm i get has already lost all interesting values. Also i feel like it has to do with the fact that the value i want to retain isn't directly stored on the main bean, but rather is a property of a sub-bean, because on the same page there are a lot of other properties directly on the main bean that i have no trouble saving.

What did i miss ?

2

There are 2 best solutions below

0
On

in my case i had to put the name attribute into the iterate otherwise it gives me error(cannot find property into any bean...)

I resolved deleting the attribute name into the checkbox: it seems it create a new object at page scope that is not connected with the form.

This is my code:

<nested:iterate id="apertura" type="it.puglia.innova.view.actionform.AperturaForm" indexId="index"  name="strutturaRuraleForm"  property="listAperturaForm">
     <nested:checkbox styleId="checkbox_${index}" property="flagContinuato" onchange="changeOrarioContinuato(${index})"/>

that's it :-) didn't need to change html:form to nested too.

Bye

0
On

It's probably declaring incorrect name attributes in the rendered HTML. If you look at the generated source code for your page it probably looks like this:

<input type="checkbox" name="selected" ...>

which would look for a selected field in your form bean class.

If you're using a collection that's a field in your form bean you want to be using the <nested:form>, <nested:iterate> and <nested:checkbox Struts tags, not the <html:form>,and` ones. So it would then look like this:

<nested:form action="foo">
...

    <nested:iterate property="list1" id="listItem">
    <tr>
        <td>
            <nested:checkbox property="selected">
            </nested:checkbox>
        </td>
    </tr>
    </nested:iterate>

...
</nested:form>

Note that I've removed the name attributes from the Struts tags, because they're not needed (in my experience they actually cause all kinds of problems - if you use <nested:*> tags don't use a name attribute). In the case of the <nested:iterate> the level of nesting is the form bean itself, so it knows that it needs to look for the list1 property in the form bean.

That tag creates its own nesting level, so the <nested:checkbox knows that it needs to look for the selected property of the current element in the iteration.

The rendered HTML will look something like this (for the first element):

<input type="checkbox" name="list1[0].selected" ...>

which means the selected field of the first element (index 0) in the collection referenced by the list1 field of your form bean.

And, of course, you'll need to make sure that you're using a session-scoped form bean, rather than a request-scoped one.