提交后发生验证错误时,保持p:对话框打开

JOT*_*OTN 64 validation ajax jsf dialog primefaces

最小示例对话框:

<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> 
Run Code Online (Sandbox Code Playgroud)

我想要做的是让mbean.saveMethod以某种方式阻止对话框关闭,如果有问题并且只通过growl输出消息.这是验证器无法帮助的情况,因为在将保存提交给后端服务器之前无法判断someValue是否有效.目前我使用visible属性执行此操作,并将其指向mbean中的布尔字段.这有效,但它使用户界面变慢,因为弹出或关闭对话框需要命中服务器.

Bal*_*usC 150

onsuccess运行,如果AJAX请求本身是成功的(即有没有网络故障,未捕获的异常等),如果不采取行动方法成功地调用.

给定一个<p:dialog widgetVar="testDialog">你可以删除onsuccess和替换PrimeFaces它RequestContext#execute()里面saveMethod():

if (success) {
    RequestContext.getCurrentInstance().execute("PF('testDialog').hide()");
}
Run Code Online (Sandbox Code Playgroud)

注意:PF()在PrimeFaces 4.0中引入.在较旧的PrimeFaces版本中,您需要testDialog.hide()使用它.

如果您不希望控制器与特定于视图的脚本混乱,您可以使用oncomplete而不是提供args具有布尔validationFailed属性的对象:

<p:commandButton ...
    oncomplete="if (args &amp;&amp; !args.validationFailed) PF('testDialog').hide()" />
Run Code Online (Sandbox Code Playgroud)

if (args)检查是必要的,因为当发生Ajax错误,从而引起新的JS错误,当你设法得到它可能是不存在的validationFailed,从它; 的&amp;,而不是&强制性的理由解释这个答案,如果有必要,你调用像JS功能,重构oncomplete="hideDialogOnSuccess(args, testDialog)"如图保持<P:对话框>打开时验证失败.

后一种解决方案(稍加重写)应该适用于普通的jsf validationFailed和一个true


令人遗憾的是,PrimeFaces不支持RichFaces已经支持的内容:EL FacesContext#validationFailed()属性的请求时重新评估.否则你也可以做到这一点:

FacesContext.getCurrentInstance().validationFailed();
Run Code Online (Sandbox Code Playgroud)

  • 使用RequestContext非常有趣.我不知道你能做到这一点. (2认同)
  • @Mah:我刚接手OP的原始代码.问题不在于actionListener与action的关系,所以我按原样保留了OP的原始代码.但我同意这不是推荐的方式,对于你想知道的情况. (2认同)

sol*_*ysh 16

我刚刚用谷歌搜索了这个解决方案.基本上我的想法是使用actionListener而不是按钮的动作,并在支持bean中添加回调参数,然后检查按钮的oncomplete方法.示例部分代码:

JSF第一:

<p:commandButton actionListener="#{myBean.doAction}"
   oncomplete="if (!args.validationFailed &amp;&amp; args.saved) schedulesDialog.hide();" />
Run Code Online (Sandbox Code Playgroud)

支持豆:

public void doAction(ActionEvent actionEvent) {
    // do your stuff here...
    if (ok) {
        RequestContext.getCurrentInstance().addCallbackParam("saved", true);
    } else {
        RequestContext.getCurrentInstance().addCallbackParam("saved", false);
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这有助于某人:)


Alo*_*uez 15

使用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>
Run Code Online (Sandbox Code Playgroud)

脚本将是这样的:

<script type="text/javascript">
    function handleDialogSubmit(xhr, status, args) {
        if (args.validationFailed) {
            dialog.show();
        } else {
            dialog.hide();
        }
    }
</script>
Run Code Online (Sandbox Code Playgroud)


小智 7

我使用这个解决方案:

JSF代码:

<p:dialog ... widgetVar="dlgModify" ... >
...
<p:commandButton value="Save" update="@form" actionListener="#{AdminMB.saveTable}" />
<p:commandButton value="Cancel" oncomplete="PF('dlgModify').hide();"/>
Run Code Online (Sandbox Code Playgroud)

支持bean代码:

public void saveTable() {
    RequestContext rc = RequestContext.getCurrentInstance();
    rc.execute("PF('dlgModify').hide()");
}
Run Code Online (Sandbox Code Playgroud)