如何在 primefaces 中单击带有 ajax=false 的命令按钮时在对话框中显示消息

How to display message in dialog while clicking command button with ajax=false in primefaces

我使用 inputText、commandButton 和 uploadFile 组件。在 commandButton 中,我在两个字段中都使用了 ajax=false 并设置为 required=true 。当单击带有空值的保存时,错误消息不会显示在对话框中并且对话框正在关闭。但是在控制台中,警告消息显示为 "Messages are rendered but not displayed".

下面是我的代码:

<p:dialog widgetVar="addDialogWidgetVar" id="addDialogWidgetVarId"  dynamic="true" >

            <table  style="width: 100%;">
                    <tr>
                        <td>
                            <p:messages for="errorMsgId" id="errorMsgId" autoUpdate="true" showDetail="false" showSummary="true" closable="true"/>
                        </td>
                    </tr>
                </table>

            <h:form id="formId" enctype="multipart/form-data">



                <table>
                    <tr>
                        <td>
                            <label style="margin-top: 5%"><h:outputText value="Name:"/><h:outputText value="*" style="color:red"/></label>
                        </td>
                        <td width="10%"/>
                        <td>
                            <p:inputText value="#{manageBean.attachment.fileName}" id="fileNameId" maxlength="60" style="width:70"
                                        required="#{not empty param[save.clientId]}" requiredMessage="Please enter Attachment name"></p:inputText>
                        </td>
                    </tr>
                    <tr height="10"></tr>
                    <tr>
                        <td>
                            <label style="margin-top: 5%"><h:outputText value="Upload Attachment:"/><h:outputText value="*" style="color:red"/></label>
                        </td>
                        <td width="10%"/>
                        <td>
                            <p:fileUpload label="Select a file" mode="simple" value="#{manageBean.attachment.file}"
                                        allowTypes="/(\.|\/)(pdf|doc|docx|xls|xlsx|gif|jpg|jpeg|png|PNG|GIF|JPG|JPEG)$/"
                                        invalidFileMessage="Allow only (pdf|doc|docx|xls|xlsx|gif|jpg|jpeg|png|PNG|GIF|JPG|JPEG) file."
                                        multiple="false" required="#{not empty param[save.clientId]}" requiredMessage="Please select a file" >
                            </p:fileUpload>

                        </td>
                    </tr>
                    </table>
                    <br />
                    <table style="margin-left: 30%;">                           
                    <tr align="center">

                        <td>
                            <p:commandButton value="Close" actionListener="#{manageBean.cancelAttachment}" oncomplete="addDialogWidgetVar.hide()" />
                        </td>

                        <td> 
                            <p:commandButton id="submitbtnid" value="Save" ajax="false" binding="#{save}"
                                        actionListener="#{manageBean.saveAttachment}" update=":errorMsgId"/>
                        </td>
                    </tr>
                </table>

            </h:form>

        </p:dialog>

当值为空时,对话框本身应显示错误消息。

这是您使用 ajax=false 时的预期行为,因为在提交时整个页面被刷新,这就是对话框关闭的原因。

此外,在您的 p:messages 组件中,您不应具有指向 errorMsgIdfor 属性。在 for 中,您应该输入不想显示消息的输入字段的 ID。例如,如果你输入 formId:fileNameId,当你不输入文件名时,它会显示错误。但是如果你没有 for,它会显示所有消息。

你不需要 update=":errorMsgId" 因为你已经把 autoUpdate="true".

现在,要完成您的需要,并在不关闭对话框的情况下使用 ajax=false 显示消息,有以下解决方法:

JSF(在定义保存按钮的地方):*稍后重新定义保存按钮

<p:commandButton id="submitbtnid" **style="display:none"** ajax="false" binding="#{save}" actionListener="#{manageBean.saveAttachment}" />
<p:commandButton value="Save" oncomplete="checkIfValid(xhr, status, args)" />

和JavaScript函数:

function checkIfValid(xhr, status, args)
  {
      if (!args.validationFailed)
      {
          $("#formId\:submitbtnid").click();
      }
  }

所以,这里是使用ajax并调用JS方法来检查验证是否失败的可见按钮。只有当所有验证条件都通过时,它才会单击实际提交表单的不可见按钮。

更新

对于 fileUpload 输入,应该进行额外检查。通过这种方式,您可以从 fileUpload 组件中删除 allowTypes 所需的属性,并为其添加一个 id - 所有验证都将在 JavaScript 函数中进行。

这是您的文件上传组件:

<p:fileUpload label="Select a file" mode="simple" value="#{manageBean.attachment.file}" multiple="false"></p:fileUpload>

并且您还应该在您的表单中添加 hiddenInput(以及您的 bean 中的 messageHidden 字段):

<h:inputHidden id="errorMsg" value="#{manageBean.messageHidden}"/>

现在,这是执行文件输入验证的 JavaScript 函数:

function checkFileInput() {
                if ($("#formId\:fileInput")[0].files.length == 0) {
                    $("#formId\:errorMsg").val("Please select a file");
                    return;
                }
                var validExtensions = ['pdf','doc','docx','xls','xlsx','gif','png','jpg','jpeg'];
                var maxFileSize = 5000;

                var ext = $('#formId\:fileInput').val().split('.').pop().toLowerCase();
                if($.inArray(ext, validExtensions) == -1) {
                    $("#formId\:errorMsg").val("Allow only (pdf|doc|docx|xls|xlsx|gif|jpg|jpeg|png|PNG|GIF|JPG|JPEG) file.");
                    return;
                }

                if ($("#formId\:fileInput")[0].files[0].size > maxFileSize) {
                    $("#formId\:errorMsg").val("File is to big");
                    return;
                }
                $("#formId\:errorMsg").val("");
            }

它首先检查文件是否被选中,然后是它的扩展名,然后是允许的文件最大大小。如果其中某些内容无效,它会为隐藏的输入字段设置新值。

现在,在您的 bean 中,您应该检查文件验证是否成功:

public void validateFile() {
        if(!messageHidden.trim().equals("")) {
            FacesContext.getCurrentInstance().validationFailed();

            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, messageHidden, messageHidden);
            FacesContext.getCurrentInstance().addMessage(null, message);
        }
    }

如果没有,验证失败将被设置为上下文并添加来自 inputHidden 的消息。

最后,您应该将保存按钮更改为首先使用 JS 检查文件输入,然后使用 bean 方法对其进行验证,然后检查验证是否失败:

<p:commandButton value="Save" onclick="checkFileInput()" actionListener="#{testBean.validateFile}"
              oncomplete="checkIfValid(xhr, status, args)" />