如何在 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
组件中,您不应具有指向 errorMsgId
的 for
属性。在 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)" />
我使用 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
组件中,您不应具有指向 errorMsgId
的 for
属性。在 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)" />