Pregunta

I have a dynamically expansible table with an add and remove button:

<h:form>
        <h:dataTable id="tblFields" value="#{bean.fields}" var="field">
            <h:column>
                <h:inputText value="#{field.value}" />
            </h:column>

            <h:column>
                <h:inputText value="#{field.value2}" />
            </h:column>
            <h:column>
                <h:inputText value="#{field.value3}" />
            </h:column>


            <h:column>
                <h:commandButton value="Remove">
                    <f:ajax listener="#{bean.onButtonRemoveFieldClick(field)}" immediate="true" render="@form" /> 
                </h:commandButton>
            </h:column>
        </h:dataTable>

        <h:commandButton value="Add">
            <f:ajax listener="#{bean.onButtonAddFieldClick}" execute="@form" render="tblFields" /> 
        </h:commandButton>
    </h:form>

This is the associated backing bean:

@Named
@ViewScoped
public class Bean {

    private List<Field> fields;

    @PostConstruct
    public void init() {
        fields = new ArrayList();

        fields.add(new Field());
    }

    public List<Field> getFields() {
        return fields;
    }

    public void setFields(List<Field> fields) {
        this.fields = fields;
    }

    public void onButtonRemoveFieldClick(Field field) {
        fields.remove(field);
    }

    public void onButtonAddFieldClick() {
        fields.add(new Field());
    }
}

The use case is as follows:

  • Press the add button multiple times.
  • Fill out all values.
  • Press the remove button of one random row.

After that, all values filled so far disappears and show up blank. How can I keep them filled after pressing the remove button?

¿Fue útil?

Solución

It's because you're in the remove button ajax-updating the entire form without processing the newly submitted input values. The immediate="true" on ajax listener skips the processing of all input components which do not have immediate="true" set. You need to remove the attribtue. The absence of execute attribute will cause only the current component (@this) to be processed by default. You need to explicitly specify @form.

So, just do the same as in your add button. Replace immediate="true" by execute="@form".

<f:ajax listener="#{bean.onButtonRemoveFieldClick(field)}" execute="@form" render="@form" /> 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top