言わずと知れた、ASP.NET 2.0 Web アプリケーションに AJAX を統合するライブラリ、
Microsoft ASP.NET AJAX。実践的に利用しているが、いくつか壁にぶつかることも出てきた。
一例としては、RadioButtonList コントロールと (ASP.NET AJAX の)UpdatePanel コントロールの組み合わせ。AutoPostBack=true に設定した RadioButtonList コントロールの SelectedIndexChanged イベントハンドラで、現在選択されたラジオボタン項目の値を Label コントロールの Text に設定して表示する Web アプリを想像してほしい。
ここで、この Label コントロールを UpdatePanel コントロール内に収録し、Triggers の設定をすませておくことで、アラ不思議、ページ全体が再読込されることなく、AJAX の仕組みで、ちゃんと Label コントロールの表示が更新される。
しかし、RadioButtonList コントロールのいずれかのアイテムについて、Selected=true に初期設定されたアイテムが存在すると、うまくいかないケースが出てくる。Selected=true に初期設定
されていないアイテム間を選択変更するごとには、ちゃんとサーバー側で SelectedIndexChanged イベントが発生することが確認できる。
しかし、Selected=true に初期設定されたアイテムを再度選択し直しても、今度は SelectedIndexChanged イベントが発生しないのだ。
なんとなく想像はつかなくもない。
クライアント側 JavaScript で、input type=radio 要素の click イベントを拾っているのだと思うが、その click イベント発生元の input type=radio 要素が、checked 属性を持っていない場合に限り、AsyncPostBack を発生させているのであろう。
そこで、この推測に基づき、RadioButtonList コントロールも UpdatePanel コントロール内に収録してみた。こうすれば、input type=radio 要素の checked 属性の有無も更新されるからうまくいくだろう、という読みだ。
案の定、このように実装を変更することで、先に述べた不具合は解消できた。
ところが、一難去ってまた一難。
今度はキーボードフォーカスについて問題が発生。
RadioButtonList コントロールについて、キーボード操作で選択変更しようとすると、AJAX の仕組みで RadioButtonList コントロール(が吐き出した input type=radio 要素群)も差し変わってしまうため、フォーカスを失ってしまうのだ(ブラウザにとってはそれまでフォーカスを持っていた要素が DOM から削除されるため)。
これらの不具合を実際に体感してもらえるよう、サンプルを作成してみた。
http://gentoo.dev-asp.net/samples/01NoActionWhenSelectedIndexChanged/
今のところ、これといってうまい回避策は思いついていない。
特に、キーボードフォーカスの件は、今回紹介したようなサンプルに限らず、UpdatePanel 内に収録したコントロールには常につきまとう問題である。
もっと ASP.NET AJAX を深く掘り下げる必要があるようだ。そうすれば、おそらく適切なフックを仕掛ける余地がきっと残されているのだと思う。しかし、現時点の自分のスキルではまだまだ踏み込めていないところ。要勉強。