2011-01-14

ActiveScaffoldで日付入力でカレンダーを利用する方法

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
RailsのScaffoldを便利にするActiveScaffoldで日付入力をする際にカレンダーを利用する方法です。
calendar_date_select
というのを入れれば勝手にカレンダーを使ってくれるようになります。

インストールは、
gem install calendar_date_select
で。
そして
config/environment.rb

config.gem "calendar_date_select"
を追加すれば、もうOKです。

これだけでカレンダーが使えるようになりました。

calendar_date_selectのインストールは、pluginとしてインストールすることもできるようなのですが、どうもgemで入れないとActiveScaffoldではうまく使えない気配です。

これでカレンダーは使えるようになるのですが、このままだと日付の形式が
August 12, 2007
みたいになっていて、ちょっといまいちです。

これを
2007/08/12
の形式にする方法は以下の通りです。

まず
config/environment.rb
に以下を追加します。
CalendarDateSelect::FORMATS[:japanese] = {
  :date => "%Y/%m/%d",
  :time => " %H:%M",
  :javascript_include => "format_japanese"
}
CalendarDateSelect.format = :japanese

そして
public/javascripts/calendar_date_select/format_japanese.js
というjavascriptを以下の内容で作成します。
Date.prototype.getAMPMHour = function() { hour=Date.padded2(this.
getHours()); return (hour == null) ? 00 : (hour > 24 ? hour - 24 : hour
 ) }
Date.prototype.getAMPM = function() { return (this.getHours() < 12) ? ""
 : ""; }

Date.prototype.toFormattedString = function(include_time){
  str = this.getFullYear() + '/' + Date.padded2(this.getMonth() + 1) + '
/' +Date.padded2(this.getDate());

  if (include_time) { hour=this.getHours(); str += " " + this.
getAMPMHour() + ":" + this.getPaddedMinutes() }
  return str;
}

Date.parseFormattedString = function (string) {
  var regexp = "([0-9]{4})(\/([0-9]{2})(\/([0-9]{2})" +
               "( ([0-9]{1,2}):([0-9]{2})" +
               "?)?)?)?";
  var d = string.match(new RegExp(regexp, "i"));

  if (d==null) {
    return Date.parse(string); // Give javascript a chance to parse it.
  }

  var date = new Date(d[1], 0, 1);
  if (d[3]) { date.setMonth(d[3] - 1); }
  if (d[5]) { date.setDate(d[5]); }
  if (d[7]) {
    hours = parseInt(d[7], 10);
    date.setHours(hours);
  }
  if (d[8]) { date.setMinutes(d[8]); }

  return date;
}
これは、 http://code.google.com/p/calendardateselect/wiki/ChangingDateFormatCustom とか http://blog.champierre.com/archives/822 とかを参考にさせていただきました。 あとは、カレンダーの曜日とかの表示を日本語にしたり、calendar_date_selectで使えるオプションのforceとかをActiveScaffoldでも使えるようにしたいなぁと思っていますが、まだやり方不明です。

2011/1/17追記
カレンダーを日本語にする方法です。
public/javascripts/calendar_date_select/locale/ja.js
というjavaスクリプトを以下の内容で作成します。
文字コードはUTF-8で保存してください。
_translations = {
  "OK": "OK",
  "Now": "現在",
  "Today": "今日",
  "Clear": "閉じる"
}

Date.weekdays = $w("日 月 火 水 木 金 土");

Date.months = $w("1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月" );

そしてlayoutなりActiveScaffoldを使うときに以下のように指定すればOKです。
<%= active_scaffold_includes %>
<%= calendar_date_select_includes :locale => "ja" %>
ポイントは、active_scaffold_includesの後にcalendar_date_select_includesすることです。
active_scaffold_includesを呼べば、内部でcalendar_date_select_includesを呼んでいるので指定しなくても利用できるのですが、内部で呼んでいる時にはlocaleを渡していないので後で再度指定しちゃいました。

あとcalendar_date_selectには、テキストボックスにテキストを直接入力させずに、必ずカレンダーをクリックして入力させるoptionを指定できるのですが、ActiveScaffoldを利用しているときは、以下のようにoptionを渡します。
ちなみにopened_atが日付型のフィールドだと思ってください。
config.columns[:opened_at].options = {:popup => "force"}
コメントを投稿