验证失败应阻止关闭模式对话框

Failed validation should prevent closing of modal dialog

我正在使用 Bootsfaces 来显示模态对话框。在模式对话框中有一个字段(实际上是 b:inputTextarea)和一个使用 Ajax 提交数据的命令按钮。我想确保用户在提交之前已经在文本字段中输入了一些内容。如果该字段为空,则不应关闭模式并且不应进行提交,如果该字段为非空,则应关闭对话框并应进行提交 Ajax-style.

由于 Bootsfaces 1.4.2 的 issue,我无法使用 b:command 完成 Ajax 部分。我必须使用 h:commandButtonf:ajax 的标准方式。

我正在尝试这样解决我的问题:

<b:form>
    <!--  section that gets updated by ajax-request -->
    <b:panel id="updateSection">
        <h:outputText value="#{testBean.value1}" />
        <b:button value="open dialog" onclick="$('.pseudoClass').modal()" />
    </b:panel>
    <!-- modal dialog -->
    <b:modal title="model" styleClass="pseudoClass" closable="false" closeOnEscape="true">
        <b:panel id="modalOutput"><h:inputText value="#{testBean.value1}" /></b:panel>
        <f:facet name="footer">
            <!-- cancel button -->
            <b:button largeScreen="half" value="cancel" dismiss="modal" onclick="return false;" />
            <!-- submit button ajax-style -->
            <h:commandButton value="submit" action="#{testBean.save()}" onclick="validateModalDialog();">
                <f:ajax render="updateSection" execute="@this modalOutput" onevent="closeModalDialog" />
            </h:commandButton>
            <!-- scripts to close & validate modal dialog -->
            <h:outputScript>
                    function closeModalDialog(data) {
                        var status = data.status;
                        if (status === 'complete') { $('.pseudoClass').modal('hide'); }
                    }
                    function validateModalDialog() {
                        alert('i get called before closing dialog');
                        return false;
                    }    
            </h:outputScript>
        </f:facet>
    </b:modal>
</b:form>

脚本函数 validateModalDialog 在模态对话框关闭之前被调用,但无论函数的 return 值(true 或 false)如何,对话框都会关闭。

我对JavaScript的了解相当有限。这是我选择使用 JSF 和 Bootsfaces 的原因之一。但我很确定有一种方法可以进行验证并防止对话框关闭。

如何在使用标准组件 h:commandButtonf:ajax 时模拟 Bootsfaces 功能(模式对话框中文本字段的客户端验证)?

解决方案:

为了实现客户端验证以防止触发 Ajax 请求和关闭模态对话框,与我的初始代码相比,需要进行以下更改:

<h:commandButton value="submit" action="#{testBean.save()}" onclick="return validateModalDialog();">
     <f:ajax render="updateSection" execute="@this modalOutput" onevent="closeModalDialog" />
</h:commandButton>

确实像

<h:commandButton>
    <f:ajax onevent="function(e){if(e.status == 'complete') doSomething();}"/>
</h:commandButton>

不等同于

<b:commandButton ajax="true" oncomplete="doSomething();"/>

要通过 javascript 从 h:commandButton 关闭模态对话框,仅当表单没有验证错误时,您必须:

  1. 添加我最初提出的 <b:fetchBeanInfos/> component to your form as suggested in 作为您问题的副本。还要确保它随每个 ajax 请求更新。
  2. 不检查 data.status == 'complete' 而是检查 data.status == 'success'
  3. 完全删除 onclick="validateModalDialog();"

这是为服务器端验证更改的代码,仅当输入不为空时关闭对话框 (required="true")。请注意,testBean.save() 也仅针对有效输入被调用。

<b:form>
    <!--  section that gets updated by ajax-request -->
    <b:panel id="updateSection">
        <h:outputText value="#{testBean.value1}" />
        <b:button value="open dialog" onclick="$('.pseudoClass').modal()" />
    </b:panel>
    <!-- modal dialog -->
    <b:modal title="model" styleClass="pseudoClass" closable="false"
        closeOnEscape="true">
        <b:panel id="modalOutput">
            <h:inputText id="myInput" value="#{testBean.value1}" required="true" />
            <h:message for="myInput" />
            <b:fetchBeanInfos /> <!-- creates the validationFailed JavaScript variable 
                                  and must be within rendered components. -->
        </b:panel>
        <f:facet name="footer">
            <!-- cancel button -->
            <b:button largeScreen="half" value="cancel" dismiss="modal"
                onclick="return false;" />
            <!-- submit button ajax-style -->
            <h:commandButton value="submit" action="#{testBean.save()}">
                <f:ajax render="updateSection modalOutput"
                    execute="@this modalOutput" onevent="closeModalDialog" />
            </h:commandButton>
            <!-- scripts to close & validate modal dialog -->
            <h:outputScript>
                   function closeModalDialog(data) {
                       var status = data.status;
                       if (!validationFailed &amp;&amp; status === 'success') { $('.pseudoClass').modal('hide'); }
                   }
           </h:outputScript>
        </f:facet>
    </b:modal>
</b:form>

一点示范:


如果您想完全阻止 ajax 表单提交无效表单并进行客户端验证,您必须根据以下内容修改您的 onclickJSF ajax request is not fired when combined with JS client-side validation:

<h:commandButton value="submit" action="#{testBean.save()}" 
        onclick="if(!validateModalDialog()) return false;">
    <f:ajax render="updateSection" execute="@this modalOutput" onevent="closeModalDialog" />
</h:commandButton>

注意客户端验证不会阻止用户提交无效数据简单地使用他们的浏览器开发工具。