JSF 2.0 Ajaxの通信監視 と jQuery

JSF 2.0がAjaxを手軽に行えるようになったのは今までの説明でわかってくれたと思う。

でも、scriptとの連携がしたい場合もあるはずだ。

たとえばボタンが2度押しにならないよう押した直後にdisabledにして推せないようにする、といったことも必要になるかもしれない。

Webはシングルクリックでいいのに、いろいろとお客さんを見ていると意外とダブルクリックする人が多いのだ。たぶん癖になっているのだろう。


ただし、JSF2はMojarraの動きを見る限り全てのAjaxはシリアル動作にしてあるようだ。デフォルトがDWRは並列動作なのとは対極的。したがって連打しても順番に処理されるだけで一応すむ。



先にコードを見せよう。とりあえず軽くjQueryつかってあったり。こっちのほうが見やすいかなと。

<script type="text/javascript">
            $(document).ready(function(){

                jsf.ajax.addOnEvent(function(event){

                    if(event.source.type == "submit"){
                        switch(event.status){
                            case "begin":
                                $(event.source).attr("disabled", "disabled");
                                break;
                            case "complete":
                                $(event.source).removeAttr("disabled");
                                break;
                            case "success":
                                alert(event.source.id+"ボタンのAjax成功");
                                break;
                        }
                    }

                });

            });
</script>

jsf.ajax.addOnEventというのがすべてのAjaxの監視をする命令。

ここでJSFAjaxの3つの動作に応じて処理が可能だ。3つのコールバックは

  • begin
  • complete
  • success

となる。


beginはAjaxを開始する前に呼ばれる。この辞典ではサーバーに処理が言っていない。このサンプルではここでまずボタンを押せないようにした。

complateはAjaxのリクエストが終わり結果を返すタイミング。この時点ではこの戻り値はパースされておらず、画面に反映されていません。

successは完全に終了した直後。エラーがある場合はこれは呼ばれない。jsf.ajax.addOnError()でエラーのハンドリングが出来るのでこれを組み合わせるといいだろう。


ここではまず対象がsubmitボタンに絞った上で、処理をしている。実際はID等で絞ったほうがいいだろう。completeのタイミングで復旧しているので何らかのサーバーエラーが発生した場合でもボタンが押せるようになっている。実際はサーバーエラーが発生している場合、本当に押せる状態に戻す必要があるかはわからないけど。


以下のように例外を出すコードを書いて動きを把握してみよう。あとThread.sleep()いれて3つのタイミングをしっかり把握してみたりしてもよい。

public String void action(){
  if(true) throw new RuntimeException();
  return null;
}


ちなみにcompleteのタイミングでパーシャルデータを見ることが出来る。プロパティは「responseText」だ。以下のようにして値を表示してみた。

                    case "complete":
                        $(event.source).removeAttr("disabled");
                        alert(event.responseText);
                        break;

http://shin.cside.com/diary/2009/1105-01.png
このレスポンス形式までちゃんと定義されているかどうかまでは確認していないが、確認しておけばどこが更新されるかデバッグするとき最便利かもしれない。


わざと例外出した場合はこちら。
http://shin.cside.com/diary/2009/1105-02.png
まぁそのまんまだね。