Tengo una h: tabla de datos que muestra una lista de filas, y los campos de cada fila son campos de entrada.JSF tabla de datos: agregar y eliminar filas borrar valores de filas
Presto un botón "Agregar fila" antes de la tabla, y un botón "Eliminar fila" en cada fila de la tabla.
El bean para hornear es viewScoped, y los botones agregan/eliminan elementos de la lista java en el bean de respaldo, y luego regresan a la misma vista.
Establecí el atributo inmediato a "verdadero" en los botones para no validar los campos de entrada cuando agrego o elimino una fila.
Todo funciona bien, pero una cosa: los valores de los archivos de entrada se borran. Pensé que la vista guardaba los valores porque el bean es viewScoped.
¿Cómo puedo lograr agregar/eliminar filas sin activar las validaciones y mantener los valores que ya fueron escritos por el usuario en el formulario?
Mi opinión:
<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>
Mi respaldo de frijol:
@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 "";
}
...
}
ACTUALIZACIÓN -> Mi solución:
que escribo aquí mi solución si alguien está interesado.
El problema es que uso immediate = "true" para omitir las validaciones, pero esto hace que también se salten los update_model_values, de modo que los valores ingresados por el usuario en el formulario se pierden después de hacer clic en los botones para agregar/eliminar -rediciendo la página.
Como utilizo la "validación de beans JSR-303", mi solución fue omitir las validaciones utilizando f: validateBean para habilitarlas/deshabilitarlas. Dependiendo del botón en el que hago clic, si quiero que se ejecuten las validaciones, habilito la validación del bean (por ejemplo, en un botón "enviar"), y si quiero omitirlas, deshabilito la validación del bean (como en add/remove botones de fila). Pero, de todos modos, update_model_values siempre se ejecuta, por lo que los valores no se pierden.
Aquí está la vista:
<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>
El bean de respaldo:
@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 "";
}
...
}
hola tengo el mismo problema, buena solución. , pero ¿tiene una idea de cómo deshabilitar los validadores incorporados, como "required = true"? – wutzebaer
Puede poner required = "# {empty param ['disableValidation']}". De esta manera, el campo será requerido o no dependiendo del botón en el que haga clic. Usted pasa el parámetro "disableValidation" si desea deshabilitar el atributo requerido. – choquero70
@ choquero70 Debe publicar su respuesta por separado. No solo lo agregue a la pregunta. De esta forma, será más fácil para los usuarios de SO analizarlo y entenderlo. –