JSF datatable: adding and removing rows with explicit row values

I have h: datatable showing a list of rows, and the fields of each row are input fields.

I present the Add Row button in front of the table and the Delete Row button in each row of the table.

A baked bean is a viewScoped, and the buttons add / remove items from the java list in the bean base, and then return to the same view.

I set the direct attribute "true" in the buttons so as not to check the input fields when adding or removing a line.

Everything works fine, but one thing: the values ​​of the input fields are cleared. I thought the view would save the values ​​due to which the bean is viewScoped.

How can I achieve adding / removing lines without starting a check and saving values ​​that have already been entered by the user in the form?

My opinion:

<h:form>
    <h:commandButton value="Añadir Fila" immediate="true" action="#{tablaController.addRowAction}" />
    <h:dataTable value="#{tablaController.lista}" var="fila" cellpadding="0" cellspacing="0" border="1">
        <f:facet name="header">TABLA</f:facet>
        <h:column>
             <f:facet name="header"><h:outputLabel value="NOMBRE" /></f:facet>
             <h:inputText id="nom" value="#{fila.nombre}" />
             <h:message for="nom" class="msjError" />
        </h:column>
        <h:column>
            <f:facet name="header"></f:facet>
            <h:commandButton value="Quitar Fila" immediate="true" action="#{tablaController.removeRowAction(fila)}" />
        </h:column>
    </h:dataTable>
</h:form>

My bean support:

@ManagedBean(name="tablaController")
@ViewScoped
public class TablaController {

private List<Fila> lista;
...
public TablaController() { }
...
@PostConstruct
public void init() {
    this.lista = new ArrayList<Fila>();
    for (int i=0; i<5; i++) {
        Fila fila = new Fila();
        fila.setNombre("");
        this.lista.add(i,fila);
    }
}
...
public String addRowAction () {
    Fila fila = new Fila();
    fila.setNombre("");
    this.lista.add(fila);
    return "";
}

public String removeRowAction (Fila f) {
    boolean exito = this.lista.remove(f);
    return "";
}
...
}

UPDATE → MY DECISION:

I am writing my decision here if anyone is interested.

The problem is that I use immediate value = "true" to skip checks, but it also allows to skip update_model_values, so that the values ​​entered by the user in the form are lost after clicking the add / rename buttons on the page.

"JSR-303 bean ", f: validateBean, / . , , , , bean (, "" ), , bean (, / ). update_model_values ​​ , .

:

<h:form>
    <f:validateBean disabled="#{!empty param['disableValidation']}">
        <h:commandButton value="Añadir Fila" action="#{tablaController.addRowAction}">
            <f:param name="disableValidation" value="true" />
        </h:commandButton>
        <h:dataTable value="#{tablaController.lista}" var="fila" cellpadding="0" cellspacing="0" border="1">
            <f:facet name="header">TABLA</f:facet>
            <h:column>
                <f:facet name="header"><h:outputLabel value="NOMBRE" /></f:facet>
                <h:inputText id="nom" value="#{fila.nombre}" />
                <h:message for="nom" class="msjError" />
            </h:column>
            <h:column>
                <f:facet name="header"></f:facet>
                <h:commandButton value="Quitar Fila" action="#{tablaController.removeRowAction(fila)}">
                    <f:param name="disableValidation" value="true" />
               </h:commandButton>
            </h:column>
        </h:dataTable>
        <h:commandButton value="Submit" action="#{tablaController.saveData}" />
    </f:validateBean>
</h:form>

bean:

@ManagedBean(name="tablaController")
@ViewScoped
public class TablaController {

private List<Fila> lista;
...
public TablaController() { }
...
@PostConstruct
public void init() {
    this.lista = new ArrayList<Fila>();
    for (int i=0; i<5; i++) {
        Fila fila = new Fila();
        fila.setNombre("fila "+i);
        this.lista.add(i,fila);
    }
}
...
public String addRowAction () {
    Fila fila = new Fila();
    fila.setNombre("");
    this.lista.add(fila);
    return "";
}

public String removeRowAction (Fila f) {
    this.lista.remove(f);
    return "";
}
...
public String saveData () {
    ...
    //processes the valid data
    //for example, calls to a service method to store them in a database
    ...
    return "";
}
...
}
+5
2

"true" , .

immediate="true" . , /. , .

. , , required="true", ,

<h:inputText ... required="#{saveButtonPressed}" />

#{saveButtonPressed} true . . .

JSR 303 bean

<f:validateBean disabled="#{not saveButtonPressed}">
    <h:inputText ... />
</f:validateBean>

OmniFaces <o:validateBean>, .

<h:commandButton id="add" ...>
    <o:validateBean disabled="true" />
</h:commandButton>
+2

. , , (UIData) . : , UIData . : Mojarra

0

All Articles