jsf - sesion - ¿Cómo prevenir el botón siguiente del asistente de la interfaz de datos? ¿Activar las validaciones del cliente?
seguridad login jsf (3)
Usted tiene formularios anidados. Cada <h:form>
en una pestaña está dentro de otra <h:form>
fuera de <p:wizard>
. No necesita formularios separados, solo el asistente externo.
EDITAR:
Hay una solución para esto que funciona para mí (no valide el campo después de hacer clic en SIGUIENTE, pero valida después de hacer clic en mi botón para validar).
Para los campos que no desea validar en NEXT agregue esta etiqueta (por ejemplo para <h:inputText>
)
<f:validateBean disabled="#{!request.getParameter(''validate'')}" />
y a su botón agregue esta etiqueta <f:param name="validate" value="true"/>
.
Tengo en mi aplicación JSF 2.2 + PrimeFaces un asistente con tres pestañas. En cada pestaña, tengo un formulario para capturar datos del usuario. Cada uno de esta forma tiene algunas validaciones. En este momento, cuando hago clic en siguiente para ir a la siguiente pestaña, está validando los datos del formulario. No quiero que esto suceda.
El usuario está conservando los datos en una pestaña y luego quiere seguir avanzando. NO es necesario tener datos en el formulario para pasar a la siguiente pestaña.
Pude solucionar esto al NO tener la validación del lado del cliente (es decir, no usar la palabra requerida en los campos de entrada) y validar solo en el back-end. El problema es que quiero la validación del lado del cliente.
Mi asistente se ve así:
<h:form id="wizard">
<p:wizard flowListener="#{afiliadoController.onFlowProcess}" nextLabel="Siguiente"
backLabel="Anterior" showStepStatus="true">
<p:tab id="afiliadoTab" title="Afiliado">
<p:growl autoUpdate="true"/>
<p:panel styleClass="panels" id="panelAfiliado" style="margin-bottom:1em;" >
<p:focus context="panelAfiliado"/>
<h1> Agregue un Afiliado </h1>
<h:panelGrid columns="4" styleClass="panelGrid" >
<p:outputLabel for="nombres" value="Nombres:" />
<p:inputText id="nombres" value="#{afiliadoController.afiliado.nombre}"
requiredMessage="Debe insertar un nombre." />
<p:outputLabel for="apellidos" value="Apellidos:" />
<p:inputText id="apellidos" value="#{afiliadoController.afiliado.apellido}"
requiredMessage="Debe insertar un apellido." />
<p:outputLabel for="estadoCivil" value="Estado Civil:" />
<p:selectOneMenu id="estadoCivil" effect="drop" value="#{afiliadoController.afiliado.estado_civil}"
requiredMessage="Debe seleccionar un estado civil." >
<f:selectItem itemLabel="Estado Civil" itemValue=""/>
<f:selectItem itemLabel="Soltero" itemValue="S"/>
<f:selectItem itemLabel="Casado" itemValue="C"/>
<f:selectItem itemLabel="Union Libre" itemValue="U"/>
<f:selectItem itemLabel="Divorciado" itemValue="D"/>
<f:selectItem itemLabel="Viudo" itemValue="V"/>
</p:selectOneMenu>
<p:outputLabel for="direccion" value="Direccion:" />
<p:inputText id="direccion" value="#{afiliadoController.afiliado.direccion}"/>
<p:outputLabel for="telefono" value="Telefono:" />
<p:inputMask id="telefono" value="#{afiliadoController.afiliado.telefono}" mask="(999) 999-9999"
requiredMessage="Debe insertar un telefono." />
<p:outputLabel for="fechaNacimiento" value="Fecha de Nacimiento:"/>
<p:calendar id="fechaNacimiento" yearRange="c-100:c" pattern="dd/MM/yyyy" navigator="true"
value="#{afiliadoController.afiliado.fecha_nacimiento}"
requiredMessage="Debe insertar su fecha de nacimiento." showOn="button"
readonly="#{facesContext.currentPhaseId.ordinal eq 6}">
<p:ajax event="dateSelect" listener="#{afiliadoController.dateSelect}" update="edadAfi"/>
</p:calendar>
<p:outputLabel for="plan" value="Plan:" />
<p:selectOneMenu id="plan" effect="drop" value="#{afiliadoController.afiliado.plan}"
requiredMessage="Debe seleccionar un plan." >
<f:selectItem itemLabel="Seleccione un plan" itemValue=""/>
<f:selectItem itemLabel="Vital Base" itemValue="1"/>
<f:selectItem itemLabel="Vital Elite" itemValue="2"/>
<f:selectItem itemLabel="Plan Vital Elite Internacional" itemValue="3"/>
</p:selectOneMenu>
<h:outputText value="Fecha: #{of:formatDate(now, ''dd/MM/yyyy'')}"/>
<h:outputText value="Edad Afiliado: #{afiliadoController.afiliado.edad}" id="edadAfi"/>
<p:outputLabel for="modalidad" value="Modalidad:" />
<p:selectOneMenu id="modalidad" effect="drop" value="#{afiliadoController.afiliado.modalidad}"
requiredMessage="Debe seleccionar una modalidad." required="true">
<f:selectItem itemLabel="Seleccione una modalidad" itemValue=""/>
<f:selectItem itemLabel="Solo Titular Del Contrato" itemValue="A"/>
<f:selectItem itemLabel="Titular del Contrato + Grupo Familiar" itemValue="B"/>
<f:validateBean disabled="#{!request.getParameter(''validate'')}" />
</p:selectOneMenu>
<p:commandButton value="Insertar" icon="fa fa-save" process="panelAfiliado" update="afiliadoTable"
actionListener="#{afiliadoController.insertAfiliado}" >
<f:param name="validate" value="true"/>
</p:commandButton>
</h:panelGrid>
</p:panel>
</p:tab>
</p:wizard>
</h:form>
Es a propósito, estoy mostrando solo la primera pestaña para que sea más legible. En esta primera pestaña tengo dos dentro de la principal (no estoy seguro de si esto es una buena práctica).
Hago esto porque quiero que la palabra clave enter funcione en forma separada en cada formulario. El con id afiliadoTab tiene algunas validaciones. Quiero que estas validaciones sucedan solo cuando hago clic en el botón:
<p:commandButton value="Insertar" icon="fa fa-save" process="panelAfiliado" update=":wizard:tablaAfiliados:afiliadoTable"
actionListener="#{afiliadoController.insertAfiliado}" validateClient="true"/>
No quiero que estas validaciones sucedan cuando hago clic en SIGUIENTE. ¿Que puedo hacer? (Sé que hay algunas preguntas similares en SO, pero no pude obtener la respuesta. Por ejemplo, la siguiente está usando vars de widgets personalizados. Intenté hacerlo, pero encontré algunos problemas:
¿Cómo puedo mostrar el botón Atrás solo cuando sea necesario? (No se muestra en la primera pestaña)
Las validaciones siguen vigentes, incluso cuando utilizo @this.
¿Cuáles son mis mejores opciones?
Entonces, si alguien tendrá un problema de validación similar a este, hay dos casos:
- Si usa la validación JSF como atributo
required
PrimeFaces o etiquetas normales como<f:validateRequired/>
puede hacerrequired = "#{!request.getParameter(''validate'')}"
y<f:validateRequired disabled="#{!request.getParameter(''validate'')}"/>
como OP o - Si usa la validación de JSR Bean como
@NotNull
, puede hacer<f:validateBean disabled="#{!request.getParameter(''validate'')}" />
para deshabilitar la validación con <f:param name="validate" value="true"/>
en un botón de acción.
Finalmente descubrí una forma de hacerlo gracias a @Geinmachi y @BaulusC publicar aquí
Este es el código actualizado:
<p:panel styleClass="panels" id="panelAfiliado" style="margin-bottom:1em;" >
<p:focus context="panelAfiliado"/>
<h1> Agregue un Afiliado </h1>
<h:panelGrid columns="4" styleClass="panelGrid" >
<p:outputLabel for="nombres" value="Nombres:" />
<p:inputText id="nombres" value="#{afiliadoController.afiliado.nombre}"
requiredMessage="Debe insertar un nombre." required="#{request.getParameter(''validate'')}"/>
<p:outputLabel for="apellidos" value="Apellidos:" />
<p:inputText id="apellidos" value="#{afiliadoController.afiliado.apellido}"
requiredMessage="Debe insertar un apellido." required="#{request.getParameter(''validate'')}"/>
<p:outputLabel for="estadoCivil" value="Estado Civil:" />
<p:selectOneMenu id="estadoCivil" effect="drop" value="#{afiliadoController.afiliado.estado_civil}"
requiredMessage="Debe seleccionar un estado civil." required="#{request.getParameter(''validate'')}">
<f:selectItem itemLabel="Estado Civil" itemValue=""/>
<f:selectItem itemLabel="Soltero" itemValue="S"/>
<f:selectItem itemLabel="Casado" itemValue="C"/>
<f:selectItem itemLabel="Union Libre" itemValue="U"/>
<f:selectItem itemLabel="Divorciado" itemValue="D"/>
<f:selectItem itemLabel="Viudo" itemValue="V"/>
</p:selectOneMenu>
<p:outputLabel for="direccion" value="Direccion:" />
<p:inputText id="direccion" value="#{afiliadoController.afiliado.direccion}" required="#{request.getParameter(''validate'')}"/>
<p:outputLabel for="telefono" value="Telefono:" />
<p:inputMask id="telefono" value="#{afiliadoController.afiliado.telefono}" mask="(999) 999-9999"
requiredMessage="Debe insertar un telefono." required="#{request.getParameter(''validate'')}"/>
<p:outputLabel for="fechaNacimiento" value="Fecha de Nacimiento:"/>
<p:calendar id="fechaNacimiento" yearRange="c-100:c" pattern="dd/MM/yyyy" navigator="true"
value="#{afiliadoController.afiliado.fecha_nacimiento}"
requiredMessage="Debe insertar su fecha de nacimiento." showOn="button"
readonly="#{facesContext.currentPhaseId.ordinal eq 6}" required="#{request.getParameter(''validate'')}">
<p:ajax event="dateSelect" listener="#{afiliadoController.dateSelect}" update="edadAfi"/>
</p:calendar>
<p:outputLabel for="plan" value="Plan:" />
<p:selectOneMenu id="plan" effect="drop" value="#{afiliadoController.afiliado.plan}"
requiredMessage="Debe seleccionar un plan." required="#{request.getParameter(''validate'')}">
<f:selectItem itemLabel="Seleccione un plan" itemValue=""/>
<f:selectItem itemLabel="Vital Base" itemValue="1"/>
<f:selectItem itemLabel="Vital Elite" itemValue="2"/>
<f:selectItem itemLabel="Plan Vital Elite Internacional" itemValue="3"/>
</p:selectOneMenu>
<h:outputText value="Fecha: #{of:formatDate(now, ''dd/MM/yyyy'')}"/>
<h:outputText value="Edad Afiliado: #{afiliadoController.afiliado.edad}" id="edadAfi"/>
<p:outputLabel for="modalidad" value="Modalidad:" />
<p:selectOneMenu id="modalidad" effect="drop" value="#{afiliadoController.afiliado.modalidad}"
requiredMessage="Debe seleccionar una modalidad." required="#{request.getParameter(''validate'')}">
<f:selectItem itemLabel="Seleccione una modalidad" itemValue=""/>
<f:selectItem itemLabel="Solo Titular Del Contrato" itemValue="A"/>
<f:selectItem itemLabel="Titular del Contrato + Grupo Familiar" itemValue="B"/>
<!-- <f:validateBean disabled="#{!request.getParameter(''validate'')}" /> -->
</p:selectOneMenu>
<p:commandButton value="Insertar" icon="fa fa-save" process="panelAfiliado" update="afiliadoTable"
actionListener="#{afiliadoController.insertAfiliado}" >
<f:param name="validate" value="true"/>
</p:commandButton>
</h:panelGrid>
Echa un vistazo a todos mis campos. Todos ellos tienen esto:
required="#{request.getParameter(''validate'')}"
Si echas un vistazo a mi botón, tiene:
<f:param name="validate" value="true"/>
De esta manera, cuando hago clic en el botón SIGUIENTE en mi asistente, NO activará las validaciones. ¡Las validaciones SÓLO se activarán cuando haga clic en el botón de ese formulario en particular!
Espero que esto ayude a alguien algún día.