验证失败时保持<p:dialog>打开</p:dialog>

时间:2013-01-14 22:40:18

标签: validation jsf jsf-2 primefaces

我有一个CRUD页面,显示Primefaces数据表中查询(域对象列表)的数据。

<p:dataTable 
                id="negozi" 
                var="n" 
                value="#{nController.theListFromQuery}" 
                rowKey="#{n.id}"
                selection="#{nController.selected}" 
                selectionMode="single">

                <p:column headerText="Field1">
                    <h:outputText value="#{n.f1}" />
                </p:column>
                <p:column headerText="Field2">
                    <h:outputText value="#{n.f2}" />
                </p:column>
<p:column style="width:4%">
                    <p:commandButton 
                        actionListener="#{nController.prepareEdit(n)}"
                        update=":editDialogId" 
                        oncomplete="editDialog.show()" 
                        value="Edit" />
                </p:column>
...

单击编辑按钮将显示一个对话框:

    <p:dialog 
                header="Edit N" 
                widgetVar="editDialog" 
                id="editDialogId">

                    <h:form id="formDialog">

                        <h:panelGrid id="editDialogTable" columns="2" cellpadding="10" style="margin:0 auto;">

                            <p:outputLabel for="field1" value="F1:" />
                            <p:inputText id="field1" value="#{nController.selected.f1}" />
                            <p:outputLabel for="field2" value="F2:" />
                            <p:inputText id="field2" value="#{nController.selected.f2}" />
<p:commandButton 
                        value="Confirm" 
                        actionListener="#{nController.doEdit}" 
                        update=":form" 
                        oncomplete="editDialog.hide()"
                        rendered="#{nController.selected.id!=null}" />                  
...

有效。现在我想让F1成为必填项目。

我在inputText字段中添加了“required”属性,会发生什么?

当我尝试确认没有必填字段的表单时,实体不会被编辑(这是正确的)但是对话框已关闭(这不对!)

当我重新打开对话框时,我可以看到所需(和无效)字段上的红色突出显示。

我想要的是在表单无效时阻止对话框关闭。

我是否必须编写一些JS或者JSF会帮助我吗?

4 个答案:

答案 0 :(得分:32)

PrimeFaces ajax响应将args对象放在具有validationFailed属性的范围内。你可以利用它。

oncomplete="if (args &amp;&amp; !args.validationFailed) PF('editDialog').hide()"

(在请求期间抛出异常时,args预先检查是必要的,不会导致JS错误

您可以将其重构为可重用的JS函数,如下所示。

oncomplete="hideDialogOnSuccess(args, 'editDialog')"
function hideDialogOnSuccess(args, dialogWidgetVar) {
    if (args && !args.validationFailed) {
        PF(dialogWidgetVar).hide();
    }
}

答案 1 :(得分:5)

这篇文章现在已经有三年了,但我发现有帮助,所以我的发现可能对其他人有所帮助。

至少在PF 5.x中,似乎BalusC提供的解决方案必须以两种方式进行修改。 (1)在oncomplete事件处理器中为调用添加“args”参数,以及(2)使用PF primefaces原语来识别PF表中的窗口小部件。这是我正在使用的代码:

oncomplete="hideDialogOnSuccess(args, PF('editDialog'))"

function hideDialogOnSuccess(args, dialogWidgetVar) {
    if (args && !args.validationFailed) {
        dialogWidgetVar.hide();
    }
}

答案 2 :(得分:2)

我相信这是最干净的解决方案。 这样做不需要更改按钮代码。 该解决方案覆盖了隐藏功能原型。

$(document).ready(function() {
    PrimeFaces.widget.Dialog.prototype.originalHide = PrimeFaces.widget.Dialog.prototype.hide; // keep a reference to the original hide()
    PrimeFaces.widget.Dialog.prototype.hide = function() {
        var ajaxResponseArgs = arguments.callee.caller.arguments[2]; // accesses oncomplete arguments
        if (ajaxResponseArgs && ajaxResponseArgs.validationFailed) {
            return;  // on validation error, prevent closing
        }
        this.originalHide();
    };
});

通过这种方式,您可以将代码保留为:

<p:commandButton value="Save" oncomplete="videoDetalheDialogJS.hide();" 
   actionListener="#{videoBean.saveVideo(video)}" />

答案 3 :(得分:0)

保持对话框在验证时打开失败,只需按如下方式设置commandButton:

<p:commandButton value="save"
action="#{YourBean.yourActionMethod}"
oncomplete="if (!args.validationFailed) PF('yourDialogWidgetVar').hide()"/>

我将在这里留下一个完整的例子:

<h:form id="ad-form">
            <p:dialog id="ad-dialog" widgetVar="adDialog" modal="true" width="400"
            closeOnEscape="true" resizable="false" header="Addreass">

            <p:messages id="a-msgs" closable="true" />

            <h:panelGrid columns="2" id="ad-painel-dialog" width="100%">
                <p:outputLabel value="Country" for="country" />
                <p:inputText id="country" style="width:100%"
                    value="#{clientSaverBean.editableAddress.country}" />

                <p:outputLabel value="City" for="city" />
                <p:inputText id="city"
                    value="#{clientSaverBean.editableAddress.city}" />

                <p:outputLabel value="Zip-Code" for="zipcode" />
                <p:inputText id="zipcode"
                    value="#{clientSaverBean.editableAddress.zipCode}" />

                <p:outputLabel value="Street" for="street" />
                <p:inputTextarea id="street"
                    value="#{clientSaverBean.editableAddress.street}" />

                <p:outputLabel value="Number" for="number" />
                <p:inputText id="number"
                    value="#{clientSaverBean.editableAddress.number}" />

                <h:panelGroup />

                <f:facet name="footer">
                    <p:commandButton value="save"
                        action="#{clientSaverBean.saveAddress}"
                        process=":ad-form:ad-dialog"
                        update=":ad-form:a-msgs :ad-form:ad-painel-dialog :client-form:ad-table" 
                        oncomplete="if (!args.validationFailed) PF('adDialog').hide()"/>
                </f:facet>
            </h:panelGrid>
        </p:dialog>

    </h:form>