提交后发生validation错误时,请保持p:对话框打开
最小示例对话框:
<p:dialog header="Test Dialog" widgetVar="testDialog"> <h:form> <p:inputText value="#{mbean.someValue}"/> <p:commandButton value="Save" onsuccess="testDialog.hide()" actionListener="#{mbean.saveMethod}"/> </h:form> </p:dialog>
我想要做的是有mbean.saveMethod以某种方式阻止对话框closures,如果有一些问题,只通过咆哮输出一条消息。 这是一个validation器不会帮助的情况,因为没有办法告诉someValue是否有效,直到提交到后端服务器。 目前我使用可见属性来做到这一点,并将其指向mbean中的布尔型字段。 这样的工作,但它使用户界面变慢,因为popup或closures对话框需要击中服务器。
如果ajax请求本身成功(即没有networking错误,未捕获exception等), onsuccess
运行,而不是如果成功调用操作方法。
给定一个<p:dialog widgetVar="testDialog">
你可以移除onsuccess
并用saveMethod()
PrimeFaces RequestContext#execute()
replace它:
if (success) { RequestContext.getCurrentInstance().execute("PF('testDialog').hide()"); }
注意: PF()
是在PrimeFaces 4.0中引入的。 在较老的PrimeFaces版本中,您需要使用testDialog.hide()
。
如果您不希望使用特定于视图的脚本oncomplete
控制器,则可以使用oncomplete
来提供具有boolean validationFailed
属性的args
对象:
<p:commandButton ... oncomplete="if (args && !args.validationFailed) PF('testDialog').hide()" />
if (args)
检查是必要的,因为在发生ajax错误时它可能不存在,并且当您尝试从它获得validationFailed
失败时导致新的JS错误; &
而不是&
强制性的,在这个答案中解释的原因,必要时重构JS函数,你像oncomplete="hideDialogOnSuccess(args, testDialog)"
调用。
不幸的是,PrimeFaces不支持RichFaces已经支持的内容:在on*
属性中on*
EL进行请求时重新评估。 否则,你也可以做到这一点:
<p:commandButton ... oncomplete="if (#{not facesContext.validationFailed}) PF('testDialog').hide()" />
使用你的命令button的oncomplete
属性和真正简单的脚本将会帮助你很多。
你的对话框和命令button将类似于这样的:
<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>
我刚刚search了这个解决scheme 。 基本上,这个想法是使用actionListener而不是button的动作,在支持bean中添加callback参数,然后检查button的oncomplete方法。 部分代码示例:
JSF第一:
<p:commandButton actionListener="#{myBean.doAction}" oncomplete="if (!args.validationFailed && args.saved) schedulesDialog.hide();" />
豆类:
public void doAction(ActionEvent actionEvent) { // do your stuff here... if (ok) { RequestContext.getCurrentInstance().addCallbackParam("saved", true); } else { RequestContext.getCurrentInstance().addCallbackParam("saved", false); } }
希望这可以帮助别人:)
我使用这个解决scheme:
JSF代码:
<p:dialog ... widgetVar="dlgModify" ... > ... <p:commandButton value="Save" update="@form" actionListener="#{AdminMB.saveTable}" /> <p:commandButton value="Cancel" oncomplete="PF('dlgModify').hide();"/>
备份bean代码:
public void saveTable() { RequestContext rc = RequestContext.getCurrentInstance(); rc.execute("PF('dlgModify').hide()"); }
我相信这是最干净的解决scheme。 这样做,你不需要改变你的button代码 。 该解决scheme覆盖隐藏函数原型。
$(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)}" />
最简单的解决scheme是没有任何“widget.hide”,既不在onclick,也不在oncomplete。 删除隐藏function,只是把
visible="#{facesContext.validationFailed}"
为对话框标记