jQuery ui datepicker の change イベントを Wicket で捕捉して処理する。

表題に挙げた Wicket で捕捉して処理する前に、そもそも jQuery ui Datepicker の change イベントは
通常の change イベントハンドラでは処理できず、オプション onSelect でハンドラ指定するのはマニュアルに書いてあるとおり有名である。
onSelect で指定する function で、$(this).change(); を実行すれば change イベント発火すると思ってたが、
どうやらそうではないらしい。

そこで考えた方法は、datepicker . settings に任意の変更前を格納する変数を作って、
beforeShow でセットして、onSelect で、チェックして原始的な JavaScript で発火させる。

<input wicket:id="reqdate" id="reqdate" type="text">
$("#reqdate").datepicker({
   beforedate: $(this).val(),
   beforeShow: function(input, inst){
      inst.settings.beforedate =  $(this).val();
   },
   onSelect: function(date, inst){
      if (inst.settings.beforedate != date){
         if (document.createEvent){
            // not IE
            var evt = document.createEvent("HTMLEvents");
            evt.initEvent("change", true, true );
            return document.getElementById("reqdate").dispatchEvent(evt);
         }else{
            // for IE
            return document.getElementById("reqdate")
                       .fireEvent("onchange", document.createEventObject());
         }
      }
   },
});

他に記述する JavaScript の変数と衝突させないために、beforedate を datepicker { } の中で、
宣言とともに、 $(this).val() で input の value を格納しておくbeforeShowで格納するのだが、
あえて宣言させている。
onSelect でこれを比較して changeイベントを発火する。document.getElementById でしか書けない。

この準備ができて、やっと Wikcet の記述。。

org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior を継承した
org.apache.wicket.ajax.form.OnChangeAjaxBehavior


を使う。

final TextField<String> reqdateField = new TextField<String>("reqdate", new Model<>());
reqdate.add(OnChangeAjaxBehavior.onChange(t->{
   String changeDateStr = reqdateField.getModelObject();
   // 
}));
queue(reqdate);

これで、Datepicker で、日付を変更の選択をした時だけのイベントを捕まえて
選択した日付を OnChangeAjaxBehavior の onChange で処理できる。

この OnChangeAjaxBehavior は、datepicket だけでなく他のコンポーネントでも使えるから
この書き方を憶えておくと良いかも。