ロゴ
HOME > jQuery・Javascript > 仕様上、仕方ないのでデートピッカーを自作してみました

仕様上、仕方ないのでデートピッカーを自作してみました

2014年09月25日

カレンダー表示を簡単に実装出来るjQuery.datepickerですが、とある仕事でどうしてもこれじゃ実現出来ないケースに遭遇しました。いえ、もっとよくマニュアルを読めば出来るのかもしれません。或いはカスタムするか。ただ、それ考えるなら作った方が早いなと思い、作りました(汗

やりたかったこと

・デートピッカーを展開するフォームが無数にあるので、自由に展開させたい
・jQueryで生成したテキストフォームにデートピッカーを展開させたい

デートピッカーの設定は以下のようなものです。

$(function() {
	$( "#datepicker" ).datepicker();
});

サンプル

また、idをclass指定にする事で、複数のフォームで利用可能です。但し、idはユニークにする必要が有ります。

$(function() {
	$( ".datepicker" ).datepicker();
});
      <p><input type="text" name="datepicker" class="datepicker" id="datepicker1"></p>
      <p><input type="text" name="datepicker" class="datepicker" id="datepicker2"></p>
      <p><input type="text" name="datepicker" class="datepicker" id="datepicker3"></p>

サンプル

idごとに発行する必要が無いので、無数に設置する事は可能です。

jQueryで生成したテキストフォームにデートピッカーを展開したい

次に、ブラウザ上でエクセルの表を更新するようなものを作ります。受注した案件ではブラウザからCSVをアップロードし、その内容を<table>で表にし、それを編集したいというものでした。手書きで更新する分には何ら問題は無いのですが、それであればエクセルで編集すれば良い事でして。

このブラウザ上の表を編集する際に、セレクトや日付選択を付けたいというのがご希望でした。当然、エクセルのVBAなんかでマクロ作ってやるって手もあるのですが、選択肢となるマスターがデータベースに有りまして・・・。ならばAccessでDBに繋いでCSV編集を・・と、そんなもの開発してる暇があるならブラウザ更新の方が早いだろうと、以下のようなものを作ってみました。

サンプル

jQuery(document).ready(function(){
  //tableのtdをダブルクリックしたら
    $(document).on('dblclick','#tb table td',function(){
      var cls = $(this).attr('class'); //tdのclass名
      var rnd = Math.round( Math.random()*100 ); //idをユニークにする為の乱数発行
    //input生成
      var $input = $("<input>").attr('id','datepicker'+rnd).attr("type","text").val($(this).text());
    //TDのclassがflag_calendarならinputにclass datepickerを定義
      if(cls == 'flag_calendar'){
        $input.attr('class','datepicker');
      }
      $(this).html($input);
      
        $("input", this).focus().blur(function(){
           save(this, $(this).val() );
           $(this).after($(this).val()).unbind().remove();
        });
    });
    var save = function(elm,val){
      //非同期通信でデータを更新する
    }
});

table内の文字をクリックすると、そこにテキストフォームを挿入し、更新するというものです。そのテキストフォームへclass="datepicker"を設定してやれば、jQuery.datepickerが展開されるだろう!と期待したのですが、ダメでした。datepickerの中身まで確認はしてませんが、ブラウザがロードされた時点で指定要素にdatepickerが定義されるとか、そんな仕様なのかな?と思います。

仕方ないのでdatepickerを自作する

サンプル

作成したデートピッカーのソースはこちら
CSSはこんな感じ

Javascript

   $(function(){
      $().myCalendar({
          week: ["日", "月", "火", "水", "木", "金", "土"] //曜日
         ,format:'yy-mm-dd' //日付フォーマット
         ,mover:true //マウスオーバーでフォームへ日付を入れるかどうか
      });
   });

HTML

    <input type="text" class="mycld" id="day1"> <!-- class mycld を設定 id はユニークに -->
    <input type="text" class="mycld" id="day2"> <!-- class mycld を設定 id はユニークに -->

面倒だろうなぁ・・と考えていたのですが、割と簡単に作れました。テキストフォームにフォーカスした時点で発火させるので、jQueryで生成したテキストフォームにも展開されます。ただ、問題は今回のような表更新の仕様だと、フォーカスが外れた時点で更新処理が行われるので、自作デートピッカーの月移動に手間が掛かってしまいます。テキストフォームを挿入する際に更新ボタンも一緒に挿入し、それを押して更新、という形かなぁ・・と思いますが、ボタンを押すという一手間が掛かってしまいます。

更新するのは日付だけではないので、その他のフォームにまでボタンを付けるのは・・というのが悩みどころですね。デートピッカーの時だけボタンを付けるって仕様が現実的でしょうか。今回はブラウザ上でCSVファイルを更新するというWEBアプリケーション用に急遽作ったものなのですが、機能過多になり過ぎてるjQuery.datepickerの代替として、さくっと使えるような気がします。

以前、jQuery.datepickerに選択させたくない日を設定するという機能を付けた事が有ります。あと、休日を反映させるって事もやった事が有ります。ただ、とっても面倒なのです。今回自作したデートピッカーはシンプルですので、こういった事も簡単に実装出来ますし、ホテル予約カレンダーとして、満室の日にマークをつけたりなども割と簡単に出来そうです。

もちろん、ただ単純に今月のカレンダーを表示して月の移動が出来るだけですので、本家のような高機能では有りません。カスタム前提の素体です。
ちなみに、今回作成したものは受注した案件用ですので、クロスブラウザ対策など全く考えてません。