jQueryのカレンダーツール

Extended-Bort をベースにした Railsで開発しているので、いままで使っていた prototype.jsベースのカレンダーが使えず(使えないわけじゃないんですが、そのためだけに jQueryのほかに prototype.jsも入れるなんてどうよ、ということです)、jQueryベースのカレンダーを探していたところ、よさげなものがあったので簡単に使うための設定を書いておきます。

Date Picker

DatePicker - jQuery plugin がそうです。このページの Downloadから『datepicker.zip (50 kb)』を落っことしてきます。Example用のファイルも入っていますが、最低限必要なファイルはこれだけです。言わずもがなのことですが、cssRAILS_ROOT/public/stylesheetsに、jsは javascriptsに、imagesは imagesへコピーしておきます。

css
  datapicker.css
images
  datapicker_b.png   datapicker_bl.png  datapicker_br.png
  datapicker_l.png   datapicker_r.png   datapicker_t.png
  datapicker_tl.png  datapicker_tr.png
js
  datapicker.js
  eye.js

使い方

どこでもいいですが、stylesheetと javascriptがロードされるようにしておきます。

<%= stylesheet_link_tag 'datepicker', :media => 'screen' %>
<%= javascript_include_tag 'jquery', 'datepicker', 'eye' %>
application.html.erb

これも好き好きですが DatePickerを使うためのヘルパを定義しておきます。

def set_datePicker(tag, format, starts, position)
  "#{tag}.DatePicker({" +
  "  format:'#{format}'," +
  "  date: #{tag}.val()," +
  "  current: #{tag}.val()," +
  "  starts: #{starts}," +
  "  position: '#{position}'," +
  "  prev: '<<'," +
  "  next: '>>'," +
  "  onBeforeShow: function(){ #{tag}.DatePickerSetDate(#{tag}.val(), true); }," +
  "  onChange: function(formated, dates){ #{tag}.val(formated); }" +
  "});"
end
def input_DatePicker(fields, format = 'Y/m/d', starts = 1, position = 'right')
  "<script type='text/javascript'>" +
  "(function($){" +
  "  var initLayout = function() {" + 
  fields.inject("") { |ret,field| ret += set_datePicker("$('##{field}')", format, starts, position) } +
  "  };" +
  "  EYE.register(initLayout, 'init');" +
  "})(jQuery)" +
  "</script>"
end

日付のフォーマット('Y/m/d'='YYYY/MM/DD')と週の開始(1:月曜)、表示位置('right')だけ指定できるようにしています。フォーム中に複数の日付フィールドがあることを考慮して、fieldsは :idの配列を渡します。実際に使うときはフォームの一番下に、こう(↓)いうふうに使いたいIDを列挙して書いておきます。簡単ですね。

<%= input_DatePicker ['user_birthday', 'user_indate'] %>

注意

F's Garage @fshin2000 :jQuery PluginのDate Pickerで、日付が1月なのに、2月になっちゃったりする不具合について。』に書かれているように、いまダウンロードできるバージョンには『初期値が1月の場合、表示が現在月になる』というバグがあります。2009/01/15がセットされている項目にフォーカスが来ると2月時点では、2009/02/15が表示されてしまいます。

parseDate = function (date, format) {
    :
    :
  if (!(0 <= m && m < 12)) m = now.getMonth();
  return new Date(
    y||now.getFullYear(),
    m,/*||now.getMonth(),*/
    d||now.getDate(),
    h||now.getHours(),
    min||now.getMinutes(),
    0
  );
},

parseDate関数の中で mの値が範囲を外れたら現在の月をセットすることにして、returnの方で || しないように修正すればこのバグは直ります。(『if (!(0 <= m && m < 12))』を『if (0 > m || m >= 12)』に修正すると動きませんので注意(isNaN(m)のケースが漏れます))

その他オプション

詳しくはこちら(→ DatePicker - jQuery plugin )をみるか、ソースをみてください。

  • flat 使い方が難しいので falseのままが吉。ただ trueにしただけだとエラー
  • start 週の開始(0:日曜、1:月曜、・・・、6:土曜)
  • prev 前月へ移動するときのマーク('◀':うまく表示されないので'<<'で代用)
  • next 次月へ移動するときのマーク('▶':うまく表示されないので'>>'で代用)
  • mode 'single'以外は難しいのでパス。'multiple'、'range'は必要があれば
  • format 'Y/m/d'以外 'H:M'なども指定できるが '00:00'が戻されるだけ
  • position 表示位置('top'、'left'、'right'、'bottom')
  • locale 月や曜日表示を変更する。Hashで渡せるようだが未確認
  • onBeforeShow 表示前の関数。これがないとデフォルトの日付が選択されない
  • onChange 変更時の関数。これがないとクリックした日付が戻らない
  • onShow  使ったことがない
  • onHide   使ったことがない
  • onRender 使ったことがない