投稿日:

Twitter Bootstrap上でJQuery UI Datepickerを使用する際の問題

Twitter Bootstrapは単純なデザイン性から一歩進んだコンポーネントまで提供してくれる、WEBアプリケーション開発者にとって心強いフロントエンドフレームワークです。

Twitter Bootstrap
http://getbootstrap.com/

個人的にはTwitter Bootstrap + JQueryを使用すればかなり柔軟なUIを構築できると感じていますが、ひとつ大きな問題があります。
それは、

JQuery UIとの共存が難しい

ということです。
Bootstrapはcssだけでなくコンポーネント等の機能はJQueryで作成された基本ライブラリの読み込みが必須ですので、Bootstrapを使用する場合はTabやDialogといった機能はできるだけ最初からBootstrap標準のものを使用するのが良いと思われます。

ただ、datepickerに関してはJQuery UIのものが高機能で実績もあるのでできたらそっちを使いたい、というのが本音です。

JQuery UI datepickerをBootstrap上で使用する際にもっとも問題になるのは、

1.datepickerが他のエレメントの陰に隠れてしまう

この問題が最も多く発生すると思われます。
Bootstrapで生成されたエレメントのz-indexがdatepickerよりも上位に来た場合に発生する現象です。
この現象は以下のcssコードで解決します。

#ui-datepicker-div {z-index:10000;}

z-indexには必要に応じて大きな値を設定してください。
大体これで解決するのですが、たまに次のような厄介な状況に遭遇します。

2.ブラウザがFirefoxで、BootstrapのModal Dialog上でdatepickerのchangeYear、changeMonthを使用すると、月日のセレクトボックスが表示されない

この現象の原因は以下の通りです。
BootstrapではDialogのModal機能を使用するとフォーカスがそのDialogのdiv内のエレメントにしか当たらないように強制されるのですが、Firefoxの場合、その機能を果たしているbootstrap.min.jsのenforceFocusという関数の標準の判定文ではdatepicker上で生成されたセレクトボックスをDialogのdiv内にあると返してくれないことにあります。(IEとChromeでは問題ありません)

この問題は、以下のようなJQuery(Javascript)のコードで解決できます。

$('#myModal').on('show', function () {
$(this).append($("#ui-datepicker-div"));
});
$('#myModal').on('hide', function () {
$("body").append($("#ui-datepicker-div"));
});

myModalはModal DialogのIDです。
この方法ではModal Dialogが表示される際にそのDialog内にdatepickerの領域が付加されます。
フォーカスがそのDialogのdiv内のエレメントにしか当たらないように強制されるのであれば、datepickerをDialogの中に入れちゃえばいいじゃない、フォーカス当たるじゃない、という逆転の発想から生まれた解決法です。

今回はJQuery UIとBootstrapとの間の整合性を取るまでの過渡期の混乱の中でこのような解決法になりました。
今後はさらに矛盾のないライブラリが整備されていくと思われますので(たとえばJQuery UI Bootstrapやdatepicker for Bootstrapの機能の充実)、期待したいです。