Ajax 提交后出现验证错误时,保持p:对话框打开
最小示例对话框:Ajax 提交后出现验证错误时,保持p:对话框打开,ajax,validation,jsf,primefaces,dialog,Ajax,Validation,Jsf,Primefaces,Dialog,最小示例对话框: 我希望能够做到的是,让mbean.saveMethod在出现问题时以某种方式阻止对话框关闭,并且只通过咆哮输出消息。在这种情况下,验证器没有帮助,因为在将保存提交到后端服务器之前,无法判断someValue是否有效。目前,我使用visible属性来实现这一点,并将其指向mbean中的一个布尔字段。这是可行的,但会使用户界面变慢,因为弹出或关闭对话框需要点击服务器。如果ajax请求本身成功(即没有网络错误、未捕获异常等),而不是成功调用操作方法,onsuccess将运行 给定
我希望能够做到的是,让mbean.saveMethod在出现问题时以某种方式阻止对话框关闭,并且只通过咆哮输出消息。在这种情况下,验证器没有帮助,因为在将保存提交到后端服务器之前,无法判断someValue是否有效。目前,我使用visible属性来实现这一点,并将其指向mbean中的一个布尔字段。这是可行的,但会使用户界面变慢,因为弹出或关闭对话框需要点击服务器。如果ajax请求本身成功(即没有网络错误、未捕获异常等),而不是成功调用操作方法,
onsuccess
将运行
给定一个
,您可以在saveMethod()中删除onsuccess
并用PrimeFacesRequestContext\execute()
替换它:
注意:PF()
是在PrimeFaces 4.0中引入的。在较旧的PrimeFaces版本中,您需要使用testDialog.hide()
如果您不想用视图特定脚本扰乱控制器,可以使用oncomplete
,它提供了一个args
对象,该对象具有布尔validationFailed
属性:
if(args)
检查是必要的,因为当发生ajax错误时,它可能不存在,因此当您试图从中获取验证失败时,它会导致新的JS错误;&代码>而不是&
是必需的,原因如中所述,如有必要,重构为您调用的JS函数,如oncomplete=“hideDialogOnSuccess(args,testDialog)”
,如中所示
但是,如果没有验证错误,并且操作方法已成功触发,并且由于服务方法调用中的异常等原因,您仍然希望保持对话框打开,那么您可以通过显式调用从backingbean操作方法内部手动触发validationFailed
到true
。例如
使用命令按钮中的oncomplete
属性和非常简单的脚本将对您有很大帮助
您的对话框和命令按钮与此类似:
<p:dialog widgetVar="dialog">
<h:form id="dialogView">
<p:commandButton id="saveButton" icon="ui-icon-disk"
value="#{ui['action.save']}"
update=":dataList :dialogView"
actionListener="#{mbean.save()}"
oncomplete="handleDialogSubmit(xhr, status, args)" />
</h:form>
</p:dialog>
脚本的一个示例如下所示:
<script type="text/javascript">
function handleDialogSubmit(xhr, status, args) {
if (args.validationFailed) {
dialog.show();
} else {
dialog.hide();
}
}
</script>
函数handleDialogSubmit(xhr、状态、参数){
if(args.validationFailed){
dialog.show();
}否则{
dialog.hide();
}
}
我相信这是最干净的解决方案。
执行此操作时,无需更改按钮代码。
此解决方案覆盖隐藏函数原型
$(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)}" />
我刚在谷歌上搜索过。基本上,这个想法是使用actionListener而不是button的操作,并且在backingbean中添加回调参数,该参数随后将签入button的oncomplete方法。部分代码示例:
JSF优先:
<p:commandButton actionListener="#{myBean.doAction}"
oncomplete="if (!args.validationFailed && args.saved) schedulesDialog.hide();" />
希望这对某人有所帮助:)我使用此解决方案:
JSF代码:
<p:dialog ... widgetVar="dlgModify" ... >
...
<p:commandButton value="Save" update="@form" actionListener="#{AdminMB.saveTable}" />
<p:commandButton value="Cancel" oncomplete="PF('dlgModify').hide();"/>
最简单的解决方案是不在onclick和oncomplete中使用任何“widget.hide”。删除隐藏函数,只需将
visible="#{facesContext.validationFailed}"
对于对话框标记,使用RequestContext非常有趣。我不知道你能这么做。oncomplete中的表达式需要被否定。oncomplete=“if(args.validationFailed)…”@BalusConcomplete=“if(args&;!args.validationFailed)
这是我的做法。null
检查我的代码是否不必要?@BalusC,为什么在这种情况下使用actionlistener而不是action?@Mah:我只是接管了OP的原始代码。问题不是actionlistener和action,所以我保留了OP的原始代码。但我同意,对于c来说,这不是推荐的方法如果你想知道的话。链接改为。你让我在三点后过了一天。谢谢你!
public void doAction(ActionEvent actionEvent) {
// do your stuff here...
if (ok) {
RequestContext.getCurrentInstance().addCallbackParam("saved", true);
} else {
RequestContext.getCurrentInstance().addCallbackParam("saved", false);
}
}
<p:dialog ... widgetVar="dlgModify" ... >
...
<p:commandButton value="Save" update="@form" actionListener="#{AdminMB.saveTable}" />
<p:commandButton value="Cancel" oncomplete="PF('dlgModify').hide();"/>
public void saveTable() {
RequestContext rc = RequestContext.getCurrentInstance();
rc.execute("PF('dlgModify').hide()");
}
visible="#{facesContext.validationFailed}"