jQuery

Bootstrap4に対応したDatepickerを作成する(和暦対応)〜popover,jQuery

投稿日:2018年2月28日 更新日:

Datepicker

Bootstrap4に対応したDatepickerが見つからなかったので自作した.
基本的な機能は2-3時間くらいでできるので、jQueryの学習題材などとしてもちょうどいいかもしれない.
もちろん、下のコードは完成コードを適当に切り貼りしているだけなので、最初から書くのはもっと骨の部分だけで後で肉付けしたり修正したりした結果.基本的な機能の実装はそんなに難しくない.
あ、CoffeeScriptを使いました.

popovers

Bootstrapのpopoverを使う.

この場合、対象となるDOMに少なくともdata-contentが必要だけど、オプションで指示すればいらない.

triggerオプションでpopoverを開いたり閉じたりできるんだけど、デフォルトのtriggerオプションは’click’なので要素をクリックすれば、popoverが表示されるはず.
ここで、htmlオプションをtrueにすれば、titleとcontentにhtmlを描画できるので、ここにtableタグでカレンダーを描けばdatepickerになるのだよ.

tableタグでカレンダーを作る

theadに曜日を表示して、tbodyに週ごとの日付を表示するカレンダーを作る.
カレンダーの内容は、年と月を与えると決まるので、後でその部分はプログラミングするとして、まずはその枠をtableタグで作る.
カレンダーの内容は月の初めの日(1日)の曜日によって変わるんだけど、最大で6週分くらい枠を作っておけばいい.
そして、セルに1-42までの通し番号をつけて、月の初めの曜日に従って、その分ずらして日の値を割り振ればいい.
枠を作る方法で、一番かんたんなやり方で速度も早そうなのは、そのままhtmlをソースに貼り付けるやり方だけど、jQueryオブジェクトを操作して作ることにした.
jQueryでは、$(‘div’)とかするとdocument内のdiv要素を選択できるけど、 $('<div></div>') とかすると、どこにも属してないdiv要素を新しく作ることができる.

まず、theadから.日曜日には赤、土曜日には青の色をつける.操作するクラスが被るといけないので、jdp_を追加してる.

次に、tbody.同様に日曜日には赤、土曜日には青の色をつける.クリックできるのでcursor:pointerをつける.

title部分を作る

同じようにjQueryオブジェクトを操作して、titleを作る.作りやすいのでtableタグで作った.
table.appendで自動でtbodyの下にくっつけてくれるみたい.

枠table完成

popoverの表示、非表示をマニュアルにする.

datepickerとして使う場合、日をクリックするまで、popoverにはキホン表示されててもらいたい.
そこで、表示非表示をプログラムで操作することにする.

そして、対象のインプット要素にfocusイベントを設定する.

カレンダーを作成

カレンダーは、年と月が決まれば、後は月の最初の日の曜日を確認(startday_of_week)して、その分ずらしてテーブルセルに配置すればよい.
カレンダーのセルは1-42で作成した.曜日は日曜日始まりの0-6で取得できる.そうすると、1日が日曜日の場合は、1+0でjdp_day_1のセルに1を設定すればいい.1日が土曜日の場合には、1+6でjdp_day_7のセルを1に設定すればいい.
こんな感じで、カレンダーを描画するrender_calendar関数を作成する.
ループのために、月の終わりの日(end_of_month)を取得するには、次の月の0日目を取得すると、今月の月末の日が取得できる.(月の末日(最終日)を取得する方法)
dateから取れるmonthは0-11の値を取るので、タイトルなどに表示する際には+1することを忘れない.)

日付をマウスオーバーしたら背景色を変更する

日付をクリックすると対象のテキストインプットに値を書き込みdatepickerを閉じる

前月、翌月に移動する

前の月は、monthを-1する.ただし、0より下にならないので、0より下になるようなら、monthを11(12月)にして、yearを-1する.
翌月はその逆.

ほかのところをクリックしたらdatepickerが消えるようにする

popover自体は、div.popoverで囲まれてできている.
クリックしたところの近くに.popoverが存在していたら(length)があれば消さない.
また、対象のテキストインプットをクリックしても消えないようにする.
クリックした対象は、e.targetで取得できる.e.targetから作るjQueryオブジェクトは保持していた_thisとは、Javascript的には別のオブジェクトなので比較しても等しくなることは決してない.
だけど、get(0)で取得できるDOM要素は同じになりうるので比較ができる.

イベントをきちんとoffする

何度も表示して消してを繰り返していると、イベントが多重に登録されてしまい予期しない動作を起こすことがある.
上の$(‘.date’).popover(‘hide’)は、hide_calendar関数に置き換える.
また、初期操作でevent_off()をする.

和暦部分を実装して完成!

turbolinksでわかるようにRailsのコードの一部.
和暦がまた面倒なんだけど、計算するだけなので、たいしてここに記録する情報はない.
元年とかいう用法も消えればいいのに.
下のコードだと昭和64年とかに対応してないのでまだ不十分.
ここを参考に、出力は正しい日付(昭和64年1月1日)が出力できるようにした.

-jQuery
-, , , , , ,

執筆者:

関連記事

Rails3でajaxでD&Dでまとめてファイルアップロードをスクラッチで~jQueryFileUpload for Rails

参考 Rails3でajaxでD&Dでまとめてファイルアップロード~jQueryFileUpload for Rails Rails3でajaxでD&Dでまとめてファイルアップロード2 …

FullCalendarのagendaViewでselectの場所がずれる問題

  By: Ben Piddington 前回 Rails3.2でGoogle Calendarライクなカレンダーを使う〜fullcalendar-rails   gemは最新の1 …

Rails3.2+jQueryUI1.10でjQuery-UI-Bootstrapのデモ画面を出すところまでやった

なにかいつの間にかかっこいい感じのサイトになってた addyosmani.github.com/jquery-ui-bootstrap/ jquery-ui-bootstrap.github.io/j …

Rails3.2でみたまま編集 〜hallo editor

  By: Fabio Marini – CC BY 2.0 文字をダブルクリックしてそのままフォーム編集するやつのメモ~in place edit 文字をダブルクリックしてその …

軽快なアニメーションでソーティング・フィルタリングできるMixItUpを試してみた

By: Soctech – CC BY 2.0 MixItUpは要素をアニメーションでソーティング・フィルタリングするjQueryプラグイン 前に試してみたときは少し重かったけど、バージョ …