“ボウリングの紆余曲折”で、スコア分析をする画面において“○年○月○日~×年×月×日”という日付範囲指定をしたい。

単純にセレクトボックスを使う手もあったが、ここはカレンダーから入力する方がユーザーフレンドリーってなもんだろう。

そこで、カレンダーから日付指定が出来るjQueryのプラグイン “Datepicker”を導入することにした。

まずは、以下のサイトにアクセス。

jQuery UI - ThemeRoller
http://jqueryui.com/themeroller/

jquery-ui_1

このサイト、実はjQueryを利用した様々なリッチユーザーインターフェイスを提供してくれるサイトである。

カレンダーはもちろんのこと、タブやアコーディオン、ボタンといったあらゆる機能をjQueryを利用して実現してくれる。

しかも、配色も自分でカスタマイズできるため、サイトテーマに合ったユーザーインターフェイスに仕上がる。

英語サイトなので生粋のジャパニーズであるボクにとってはなかなか大変であるが、非常に素晴らしい

とりあえず上記サイトで配色を弄りまわし、左上の“Download theme”ボタンを押すと次の画面に切り替わる。

jquery-ui_2

ここで、自分の必要とする機能にだけチェックを入れる。カレンダーの機能だけでよいのであれば“core”と“Datepicker”にだけチェックを入れたらよいが、なんだか今後色々使いそうな予感がするので全部にチェックを入れた

んで、画面右側中段あたりの“Download”ボタンを押すと、ファイル一式がzipファイルとしてダウンロードされる。

解凍すると“jquery-ui-x.x.x.custom”なるフォルダが生成される。(x.x.xはバージョン、ボクの場合は1.8.16)

jquery-ui_3

フォルダ内は上のような構造になっている。

“css”ディレクトリにはその名の通り、自分でカスタマイズしたスタイルに従ったスタイルシート、およびそれに関連した画像が含まれている。

“development-bundle”ディレクトリには様々なファイルが含まれているが、このうち“Datepicker”に必要なのは“ui”ディレクトリの“jquery.effects.core.js”と“jquery.ui.datepicker.js”である。

また、日本語化したい場合は“ui”ディレクトリ内の“i18n”ディレクトリの“jquery.ui.datepicker-ja.js”が必要になる。

ただし、“js”ディレクトリ内の“jquery-ui-x.x.x.custom.min.js”は“ui”ディレクトリ内の全てのjsファイル(“i18n”ディレクトリを除く)を含めて圧縮したファイルなので、めんどくさいもしくは他の機能も使うのであれば“jquery-ui-x.x.x.custom.min.js”ファイルを使用すればよい。

以上を踏まえた上で、次のように作業した。

  • “jquery-ui-x.x.x.custom”というフォルダ名が鬱陶しいので、“jquery-ui”にリネームする。
  • “jquery.ui.datepicker-ja.js”ファイルを“js”ディレクトリに移動する。
  • “js”ディレクトリ内の“jquery-ui-x.x.x.custom.min.js”も鬱陶しいので、“jquery-ui.min.js”にリネームする。
  • “development-bundle”ディレクトリおよび“jquery-ui”直下の“index.html”を削除する。
  • (ボクの場合は既に“jquery-x.x.x.min.js”をインストール済みなので“js”ディレクトリの“jquery-x.x.x.min.js”を削除する。)
  • “css”ディレクトリ内の“custom-theme”ディレクトリを適当な名称にリネームする(ボクの場合は“pop”)
  • リネームしたディレクトリ内の“jquery-ui-x.x.x.custom.css”も鬱陶しいので、“jquery-ui.css”にリネームする。
  • “jquery-ui”フォルダをサーバーの適当なディレクトリにアップロードする。(ボクの場合は“file”ディレクトリ)

次に、htmlのhead内に以下のように記述する。(ボクの場合、phpで書き出しているのでphpのprintで記述、{$path}はルートディレクトリのパス)

print "<link href=\"{$path}files/jquery-ui/css/pop/jquery-ui.css\" rel=\"stylesheet\" type=\"text/css\" media=\"screen\" />\n";
print "<script type=\"text/javascript\" charset=\"utf-8\" src=\"{$path}files/jquery-x.x.x.min.js\"></script>\n";
print "<script type=\"text/javascript\" charset=\"utf-8\" src=\"{$path}files/jquery-ui/js/jquery-ui.min.js\"></script>\n";
print "<script type=\"text/javascript\" charset=\"utf-8\" src=\"{$path}files/jquery-ui/js/jquery.ui.datepicker-ja.js\"></script>\n";

“○年○月○日~×年×月×日”という日付範囲指定をしたいので、後ろで選ぶ年月日は前で選んだ年月日以降に制限したい。

ググったところ、ちゃんとそのようなものを作ってくれているサイトを発見。

jQuery UI の Datepicker のカレンダーによる日付範囲指定フォーム
http://alphasis.info/2011/06/jquery-ui-datepicker-date-range/

上記サイトを参考に、元々用意していた外部JavaScriptファイルに、以下のように記述。

jQuery( function() {
  var dates = jQuery( '#date_from, #date_to' ) . datepicker( {
    showAnim: 'clip',
    changeMonth: true,
    changeYear: true,
    showCurrentAtPos: 1,
    onSelect: function( selectedDate ) {
      var option = this . id == 'date_from' ? 'minDate' : 'maxDate',
        instance = jQuery( this ) . data( 'datepicker' ),
        date = jQuery . datepicker . parseDate(
          instance . settings . dateFormat ||
          jQuery . datepicker . _defaults . dateFormat,
          selectedDate, instance . settings );
      dates . not( this ) . datepicker( 'option', option, date );
    }
  } );
} );

※2011/11/27 追記
上記コードの6行目“showCurrentAtPos: 1”とあるが、これは最初に表示する月を現在の月の1つ前にするオプションだが、4行目“changeMonth: true”にすると、セレクトボックスで選択した“1つ前の月”が表示されるようになり、非常に都合が悪い。デフォルトでは“showCurrentAtPos: 0”なので、この行はそっくりそのまま削除することにした。

※2011/11/30 追記
上記サイト様にコードが書いてあったのだが、あとでよくよく見ると"jQuery UI”の"Demos & Documentations”(↓のURL)にもサンプルコードが掲載されていました。よく見ろよ、オレ、、、orz

jQuery UI - Demos & Documentations - Datepicker
http://jqueryui.com/demos/datepicker/#date-range

で、最後にhtml(php)中に以下のようにテキストボックスを記述。

print "<p>\n";
print "日付範囲\n";
print "<input type=\"text\" id=\"date_from\" name=\"date_from\"/>\n";
print "~\n";
print "<input type=\"text\" id=\"date_to\" name=\"date_to\"/>\n";
print "</p>\n";

ここまででとりあえずは出来上がりだが、実際表示させると日本語化しているため“年”セレクトボックスと“月”セレクトボックスの間に“年”という文字が入った分横幅が長くなり、セレクトボックス間で改行されてしまい不格好である(↓)。

jquery-ui_4

そこで、ちょっと小細工

まず、上記Datepickerの呼び出し関数のパラメータが“changeYear: true”のときに表示される“年”セレクトボックスのoptionタグ内に“年”とあらかじめ記述しておく。

“jquery-ui.min.js”ファイルの548行目(圧縮ファイルなので1行が超長いが)の中頃に

b<=g;b++)a.yearshtml+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"</option>";

とあるので、これを以下のように変更。

b<=g;b++)a.yearshtml+='<option value="'+b+'"'+(b==c?' selected="selected"':"")+">"+b+"年</option>";

ただ、</option>の直前に“年”を書き足しただけ

これでセレクトボックス内に“年”が含まれるようになるが、まだセレクトボックスの後に“年”という文字が残ったままである。

これは“jquery.ui.datepicker-ja.js”の21行目

yearSuffix: '年'};

が表示されるためなので、単純に考えたらこの行の'年'を空にしたらおしまいなのだが、ちょっと待て。

パラメータを“changeYear: false”にしたときに“年”が表示されなくなってしまう(↓)。

jquery-ui_5

そこで、“changeYear: false”のときだけ“yearSuffix”を書き出すようにすればよい。

“jquery-ui.min.js”ファイルの546行目に

l=this._get(a,"changeYear"),

との記述があるので、changeYearがlという変数に代入されていることが分かる。

そこで、“jquery-ui.min.js”ファイルの548行目の先程のコードの少し後に

k+=this._get(a,"yearSuffix");

とあるので、これを以下のように変更。

if(!l)k+=this._get(a,"yearSuffix");

ただ、頭に“if(!l)”を書き足しただけ

で、忘れないようにutf-8で保存

“changeYear: false”で↓

jquery-ui_6

“changeYear: true”で↓

jquery-ui_7

これで、よし。

寝れる。