2012-06-18 139 views
5

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 ""; 
} 
... 
} 
+0

hola tengo el mismo problema, buena solución. , pero ¿tiene una idea de cómo deshabilitar los validadores incorporados, como "required = true"? – wutzebaer

+2

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

+2

@ 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. –

Respuesta

0

que tenían exactamente el mismo problema. En resumen, NO puede usar acciones inmediatas que actualicen la tabla de datos (UIData) o la repetición del recuadro. Breve explicación: los valores enviados no se guardan para volver a visualizarse si las entradas en UIData no pasan por la validación. Larga explicación se puede encontrar aquí: long explanation y a related bug in Mojarra

2

que establece el atributo inmediato a "true" en los botones con el fin de no validar los campos de entrada cuando agrego o eliminar una fila.

immediate="true" es la herramienta incorrecta para el trabajo. Se debe utilizar para priorizar la validación, no para activar/desactivar validación.La diferencia es bastante grande cuando te encuentras a ti mismo.

Desea activar la validación de forma condicional. En el caso de, p. required="true" eso sería tan fácil como

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

donde #{saveButtonPressed} evalúa true cuando se pulsa el botón de guardar. P.ej. cuando su ID de cliente está presente en el mapa de parámetros de solicitud.

En caso de JSR 303 Bean Validation, eso sería una cuestión de

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

o con OmniFaces <o:validateBean>, que permite controlar que en función de cada comando.

<h:commandButton id="add" ...> 
    <o:validateBean disabled="true" /> 
</h:commandButton> 
Cuestiones relacionadas