業務系システムではよく日付けの入力というものが行われますが、手動で年月日を入力するのを嫌がりカレンダーを表示させてそこから選択できるようにしてほしいという要望が多くあります。
今回はその日付け入力に便利な jQuery UI の datepicker を使ってみます。
Datepickerを設置する
サンプル
フォーム内をクリックしてみてください。
html
<input id="date1" type="text" />
jQuery
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js"></script> <script> jQuery(function($) { $("#date1").datepicker(); }); </script>
カレンダーにデザインが付いていないので以下から好みのテーマのスタイルを読み込んでください。
例として以下をヘッダに追記してみてください
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/redmond/jquery-ui.css" >
いかがですか、こんな簡単にカレンダーが使えます。
datepickerを複数フォームで使用する
複数フォームでdatepickerを使ってみます
サンプル
html
<input class="date2" type="text" /> <input class="date2" type="text" />
jQuery
<script> jQuery(function($) { $(".date2").datepicker(); }); </script>
フォームに class を指定し、そのclassに対してdatepickerを行うだけで使えます。
追加フォームにdatepicker使用するが正常に動かない
「jQueryによるフォームテーブル行の追加・削除」で紹介したテーブルにdatepickerを使ってみます。
サンプル
名前 | メールアドレス | 期限 |
---|---|---|
html
<input id="btnAdd3" type="button" value="行追加" /> <table id="tblForm3"> <thead> <tr> <th>名前</th> <th>メールアドレス</th> <th>期限</th> </tr> </thead> <tbody> <tr> <td><input class="name3" style="width: 150px;" name="name[]" type="text" /></td> <td><input class="email3" style="width: 150px;" name="email[]" type="text" /></td> <td><input class="date3" style="width: 150px;" name="date[]" type="text" /></td> </tr> </tbody> </table>
jQuery
<script> jQuery(function($) { $("#btnAdd3").on("click", function() { $("#tblForm3 tbody tr:last-child").clone(true).appendTo("#tblForm3 tbody"); $("#tblForm3 tbody tr:last-child input").val(""); }); $(".date3").datepicker(); }); </script>
カレンダーが出るので上手く行ったと思いきや動きが変ですね。
何行追加しても一番上のフォームに入ってしまいます。
表示後にjQueryなどで動的にフォームを追加した場合、datepickerのイベントを付け直す必要があります。
行をcloneで複製して追加すると、複製元のdatepickerイベントをそのままコピーしてしまうためです。
追加フォームにdatepickerを使用する
修正ポイントと以下の通り
・カレンダーのフォームに付与された class=”datepicker ” を削除する
・カレンダーのフォームにユニークなidを付与する
サンプル
名前 | メールアドレス | 期限 |
---|---|---|
html
<input id="btnAdd4" type="button" value="行追加" /> <table id="tblForm4"> <thead> <tr> <th>名前</th> <th>メールアドレス</th> <th>期限</th> </tr> </thead> <tbody> <tr data-row="1"> <td><input id="name4_1" class="name4" style="width: 150px;" name="name[]" type="text" /></td> <td><input id="email4_1" class="email4" style="width: 150px;" name="email[]" type="text" /></td> <td><input id="date4_1" class="date4" style="width: 150px;" name="date[]" type="text" /></td> </tr> </tbody> </table>
trタグに data-row という行番号の値を設定します。
これは、後にカレンダーフォームにidを付与する時に使用します。
datepickerを表示させるinputフォームに id=”date4_1″の様にidを付与します、この最後の 1 を行追加時に変更させます。
jQuery
<script> jQuery(function($) { $("#btnAdd4").on("click", function() { $("#tblForm4 tbody tr:last-child").clone(true).appendTo("#tblForm4 tbody"); $("#tblForm4 tbody tr:last-child input").val(""); // idに付与するための行番号を取得 row = parseInt($("#tblForm4 tbody tr:last-child").attr("data-row"))+1; // 行番号を更新 $("#tblForm4 tbody tr:last-child").attr("data-row", row); // カレンダーフォームにidを設定 $("#tblForm4 tbody tr:last-child input.date4").attr("id", "date4_"+row); // カレンダーイベントの再設定 $("#date4_"+row).removeClass("hasDatepicker").off("focusin").on("focusin", function(e) { $(this).datepicker(); }); }); $(".date4").datepicker(); }); </script>
7行目で、trタグに設定した行番号を取得して +1 します。
9行目で、trタグの行番号idを +1 した新しい行番号に変更します
11行目で、カレンダーのフォームのidを +1 した新しい行番号に変更します
idを付与しないと、カレンダーのフォームにフォーカスが入りdatepickerで自動的にidが付与されます、行を追加するとidもコピーされてしまうので何行目でdatepickerを開いても最初のカレンダーフォームに値が入ってしまいます
13行目で、datepickerのイベントを付与し直します。
カレンダーのフォームにフォーカスが入るとdatepickerで自動的に hasDatepicker というクラスが付与されてしまいますので removeClass で削除します。
これを削除しないと何行目でdatepickerを開こうとしても最初の行でdatepickerが開いてしまいます。
off() でイベントを削除して、on() でdatepickerイベントを付け直します。
その他の設定
datepicker の紹介は多くのサイトでも紹介されていますので、オプションなどはそちらのサイトなどを参照してください。
http://js.studio-kingdom.com/jqueryui/widgets/datepicker
まとめ
datepicker はカレンダーから日付け選択できるとても便利なものです、ぜひ使ってみてください。
1ページで単一のdatepickerを複数のフォームに使おうとして上手く動かなかったのでこの記事で助かりました。