【问题标题】:How to prevent PrimeFaces wizard' next button activate client validations?如何防止 PrimeFaces 向导的下一个按钮激活客户端验证?
【发布时间】:2015-12-04 18:22:35
【问题描述】:

我的 JSF 2.2 + PrimeFaces 应用程序中有一个带有三个选项卡的向导。在每个选项卡中,我都有一个表单来捕获用户的数据。每个表单都有一些验证。现在,当我单击下一步转到下一个选项卡时,它正在验证表单中的数据。我不希望这种情况发生。

用户将数据保存在一个选项卡中的数据中,然后他们希望继续前进。无需在表单上有数据即可移至下一个选项卡。

我能够通过不进行客户端验证(即:不在输入字段上使用 required 字词)并仅在后端进行验证来解决此问题。问题是我想要客户端验证。

我的向导如下所示:

<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>

我故意只显示第一个选项卡以使其更具可读性。在第一个选项卡上,我在主 &lt;h:form&gt; 中有两个 &lt;h:form&gt;(我不确定这是否是好的做法。)

我这样做是因为我希望 enter 关键字在每个表单上单独工作。 id 为 afiliadoTab&lt;h:form&gt; 有一些验证。我希望这些验证仅在我单击按钮时发生:

<p:commandButton value="Insertar" icon="fa fa-save" process="panelAfiliado" update=":wizard:tablaAfiliados:afiliadoTable"
                         actionListener="#{afiliadoController.insertAfiliado}" validateClient="true"/>

我不希望在单击“下一步”时发生这些验证。我能做些什么? (我知道 SO 中有一些类似的问题,但我无法完全得到答案。例如,下面的问题是使用自定义小部件变量。我尝试这样做,但发现了一些问题:

  1. 如何仅在需要时显示后退按钮? (不在第一个选项卡上显示)

  2. 验证仍然存在,即使我使用 @this。

我最好的选择是什么?

Required Validation PrimeFaces wizard

【问题讨论】:

  • 对正在考虑点击上述链接的任何人的警告:不要这样做。这是一个通往丰富答案的黑暗深渊的兔子洞,所有答案都从一个连接到另一个,您将永远无法逃脱。

标签: jsf primefaces


【解决方案1】:

您有嵌套表单。选项卡中的每个&lt;h:form&gt;&lt;p:wizard&gt; 之外的其他&lt;h:form&gt; 内部。您不需要单独的表格,只需要一个外部向导。

编辑:

有一些对我有用的解决方法(单击 NEXT 后不验证字段,但单击我的按钮进行验证后验证)。

对于您不想在 NEXT 上验证的字段,添加此标签(例如 &lt;h:inputText&gt;

&lt;f:validateBean disabled="#{!request.getParameter('validate')}" /&gt; 并在您的按钮上添加此标签&lt;f:param name="validate" value="true"/&gt;

【讨论】:

  • 但是你了解我的情况吗?我希望能够对每个表单进行客户端验证,并能够单击 NEXT 转到下一个选项卡
  • hmm 所以我的想法是只有在我点击某个按钮后才会激活验证?
  • 这不是你想说的“我希望这些验证仅在我点击按钮时发生”?
  • 这是正确的,但它不起作用。我将 添加到我的一个字段中。然后我将 添加到表单上的按钮中。我将该字段留空并单击“下一步”,但由于验证,它没有让我继续。
  • 如果您仅将其添加到 1 个字段,那么其他具有验证的字段仍会阻塞,请尝试将其添加到具有验证的每个字段。
【解决方案2】:

因此,如果有人遇到与此类似的验证问题,则有两种情况:

  1. 如果您使用 JSF 验证,如 PrimeFaces required 属性或普通标签(如 &lt;f:validateRequired/&gt;),您可以使用 required = "#{!request.getParameter('validate')}"&lt;f:validateRequired disabled="#{!request.getParameter('validate')}"/&gt; 等 OP 或
  2. 如果你使用像@NotNull 这样的 JSR Bean 验证,你可以这样做 &lt;f:validateBean disabled="#{!request.getParameter('validate')}" /&gt;

使用&lt;f:param name="validate" value="true"/&gt; 禁用对操作按钮的验证。

【讨论】:

    【解决方案3】:

    感谢@Geinmachi 和@BaulusC 发帖here,我终于找到了一种方法

    这是更新后的代码:

    <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>       
    

    看看我所有的领域。他们都有这个:

    required="#{request.getParameter('validate')}"
    

    如果你看看我的按钮,它有:

    <f:param name="validate" value="true"/>
    

    这样,当我单击向导上的“下一步”按钮时,它不会激活验证。只有当我单击该特定表单上的按钮时,验证才会激活!

    我希望有一天这对某人有所帮助。

    【讨论】:

    • 没想到在required做,可能对我来说太晚了。
    猜你喜欢
    • 2014-04-21
    • 2015-12-19
    • 2016-12-05
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-03
    相关资源
    最近更新 更多