web-dev-qa-db-ja.com

送信後に検証エラーが発生した場合、p:dialogを開いたままにします

最小限のダイアログ例:

<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を使用して、何らかの問題が発生した場合にダイアログが閉じないようにし、growlを介してのみメッセージを出力することです。これは、バックエンドサーバーに保存が送信されるまでsomeValueが有効かどうかを判断する方法がないため、バリデーターが役に立たない場合です。現在、可視属性を使用してこれを行い、mbeanのブールフィールドをポイントしています。それは機能しますが、ダイアログをポップアップまたはダウンするにはサーバーにアクセスする必要があるため、ユーザーインターフェイスが遅くなります。

63
JOTN

onsuccessは、アクションメソッドが正常に呼び出された場合ではなく、ajaxリクエスト自体が成功した場合(つまり、ネットワークエラー、キャッチされていない例外などがない場合)に実行されます。

<p:dialog widgetVar="testDialog">を指定すると、onsuccessを削除して、RequestContext#execute()内のPrimeFaces saveMethod()に置き換えることができます。

if (success) {
    RequestContext.getCurrentInstance().execute("PF('testDialog').hide()");
}

注:PF()はPrimeFaces 4.0で導入されました。古いPrimeFacesバージョンでは、代わりにtestDialog.hide()が必要です。

ビュー固有のスクリプトでコントローラーを散らかしたくない場合は、ブール値のoncompleteプロパティを持つargsオブジェクトを提供する代わりにvalidationFailedを使用できます。

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

if (args)チェックが必要なのは、ajaxエラーが発生したときに存在しないため、validationFailedを取得しようとすると新しいJSエラーが発生する可能性があるためです。 &amp;の代わりに&は、 この回答 で説明されている理由により必須です。必要に応じて、oncomplete="hideDialogOnSuccess(args, testDialog)"のように呼び出すJS関数にリファクタリングします 検証が失敗したときに<p:dialog>を開いたままにしてください

後者のソリューション(少し書き直し)は、プレーンなjsf h:commandButtonf:ajaxの組み合わせで機能するはずです。


PrimeFacesがRichFacesが既にサポートしているものをサポートしていないのは残念です:on*属性のELのリクエスト時の再評価。そうでなければ、これだけを行うこともできます:

<p:commandButton ...
    oncomplete="if (#{not facesContext.validationFailed}) PF('testDialog').hide()" /> 
148
BalusC

私はちょうどグーグルアップしました このソリューション 。基本的には、ボタンのアクションの代わりにactionListenerを使用し、バッキングBeanでコールバックパラメーターを追加して、ボタンのoncompleteメソッドをチェックインするという考え方です。サンプルの部分コード:

JSFファースト:

<p:commandButton actionListener="#{myBean.doAction}"
   oncomplete="if (!args.validationFailed &amp;&amp; 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);
    }
}

これが誰かを助けることを願っています:)

16
soltysh

コマンドボタンの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>
15

私はこのソリューションを使用します:

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()");
}
7
Antaeus

これが最もクリーンなソリューションだと思います。これを行うボタンのコードを変更する必要はありません。このソリューションは、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)}" />
3
Luís Soares

最も簡単な解決策は、「widget.hide」、onclick、oncompleteを使用しないことです。非表示機能を削除し、単に置く

visible="#{facesContext.validationFailed}" 

ダイアログタグ用

1
makkasi