/**
* Yahho Calendar - Japanized Popup Calendar
* @see http://0-oo.net/sbox/javascript/yahho-calendar
* @version 0.2.3
* @copyright 2008 dgbadmin@gmail.com
* @license http://0-oo.net/pryn/MIT_license.txt (The MIT license)
*/
var YahhoCal = {
/** YUIカレンダー日本語化設定 */
YUI_CAL_CONFIG: {
close: true,
my_label_year_position: 1,
my_label_year_suffix: "年 ",
my_label_month_suffix: "月",
months_long: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
weekdays_short: ["日", "月", "火", "水", "木", "金", "土"],
hide_blank_weeks: true
},
/* 英語版の設定例 */
//YUI_CAL_CONFIG: { close: true, hide_blank_weeks: true },
/** loadYUI()で読み込むYUIのURL(@see http://developer.yahoo.com/yui/articles/hosting/ ) */
YUI_URL: {
SERVER: "http://yui.yahooapis.com/",
VERSION: "2.5.2",
DIR: "/build/"
},
//入力要素をラップするアダプタ
adapters: {}
};
/**
* カレンダーを表示する
* @param String inputId 入力要素のid or 年の入力要素のid
* @param String monthId (optional) 月の入力要素のid
* @param String dateId (optional) 日の入力要素のid
* @return Boolean カレンダーの表示ができたかどうか
*/
YahhoCal.render = function(inputId, monthId, dateId) {
if (!window.YAHOO || !YAHOO.widget.Calendar) { //YUIを読み込んでいない場合
return false;
}
var currentId = (this.currentId = dateId || inputId); //入力要素を特定するID
//アダプタを取得
if (!this.adapters[currentId]) {
this.adapters[currentId] = this.createAdapter(inputId, monthId, dateId);
}
var adapter = this.adapters[currentId];
var cal = this.cal;
if (cal) { //再表示の場合
YAHOO.util.Dom.insertAfter(this.place, currentId);
cal.show();
} else { //初めて表示する場合
cal = this.cal = this.createCalendar(currentId);
}
//入力済みの日付を取得
var val = adapter.getDate();
var y = val[0], m = val[1], d = val[2];
var shown = new Date(y, m - 1, d);
//表示設定
var pagedate = "", selected = "";
if ((shown.getFullYear() == y && shown.getMonth() + 1 == m && shown.getDate() == d)) {
//日付として正しい場合
pagedate = m + "/" + y;
selected = m + "/" + d + "/" + y;
} else {
shown = new Date();
}
cal.cfg.setProperty("pagedate", pagedate); //表示する年月
cal.cfg.setProperty("selected", selected); //選択状態の日付
cal.render();
this.showHolidays(shown);
return true;
};
/**
* 入力要素とカレンダーとのポリモフィズムなアダプタを生成する
*/
YahhoCal.createAdapter = function(inputId, monthId, dateId) {
var adapter = {};
if (!monthId) { //テキストボックス1つの場合
var ymd = document.getElementById(inputId);
adapter.getDate = function() { return ymd.value.split("/"); };
adapter.setDate = function(y, m, d) { ymd.value = y + "/" + m + "/" + d; };
return adapter;
}
//年・月・日が分かれている場合
var ey = document.getElementById(inputId);
var em = document.getElementById(monthId);
var ed = document.getElementById(dateId);
if (ey.tagName == "INPUT") { //テキストボックスの場合
adapter.getDate = function() { return [ey.value, em.value, ed.value]; };
adapter.setDate = function(y, m, d) { ey.value = y; em.value = m; ed.value = d; };
return adapter;
}
//選択リストの場合
var getValue = function(sel) { return sel.options[sel.selectedIndex].text; };
var setValue = function(sel, value) {
for (var i = 0; i < sel.length; i++) {
if (sel.options[i].text == value) {
sel.options[i].selected = true;
return;
}
}
};
adapter.getDate = function() { return [getValue(ey), getValue(em), getValue(ed)]; };
adapter.setDate = function(y, m, d) { setValue(ey, y); setValue(em, m); setValue(ed, d); };
return adapter;
};
/**
* カレンダーを生成する
*/
YahhoCal.createCalendar = function(insertId) {
//YUI skinを適用
YAHOO.util.Dom.addClass(document.getElementsByTagName("body")[0], "yui-skin-sam");
//カレンダーの場所を作る
var place = (this.place = document.createElement("div"));
YAHOO.util.Dom.setStyle(place, "position", "absolute");
YAHOO.util.Dom.insertAfter(place, insertId);
//カレンダー生成
var cal = new YAHOO.widget.Calendar(place, this.YUI_CAL_CONFIG);
//日付を選択された時のイベント
cal.selectEvent.subscribe(function(eventName, date) {
var dateStr = date[0][0];
YahhoCal.adapters[YahhoCal.currentId].setDate(dateStr[0], dateStr[1], dateStr[2]);
cal.hide();
}, cal, true);
//月を移動された時のイベント
cal.changePageEvent.subscribe(function() {
YahhoCal.showHolidays(cal.cfg.getProperty("pagedate"));
}, cal, true);
return cal;
};
/**
* 祝日を表示する
*/
YahhoCal.showHolidays = function(target) {
if (!window.GCalHolidays) { //GCalHolidays.jsを読み込んでいない場合
return;
}
GCalHolidays.get(this.setHolidays, target.getFullYear(), target.getMonth() + 1);
};
/**
* 祝日表示を設定する
*/
YahhoCal.setHolidays = function(holidays) {
if (holidays.length === 0) {
return;
}
//該当年月のままか確認
var first = holidays[0];
var table = YAHOO.util.Dom.getElementsByClassName("y" + first.year, "table", this.place)[0];
var tbody = YAHOO.util.Dom.getElementsByClassName("m" + first.month, "tbody", table)[0];
if (!table || !tbody) {
return;
}
//祝日設定
for (var i in holidays) {
var h = holidays[i];
var td = YAHOO.util.Dom.getElementsByClassName("d" + h.date, "td", tbody)[0];
YAHOO.util.Dom.addClass(td, "holiday");
td.title = h.title; //マウスオーバーで祝日名を表示
}
};
/**
* 必要なYUIのJavaScriptとCSSを読み込む
* @param String yuiBase (optional) yui.yahooapis.comを使わない場合、YUIのベースとなるURL
*/
YahhoCal.loadYUI = function(yuiBase) {
if (!yuiBase) {
yuiBase = this.YUI_URL.SERVER + this.YUI_URL.VERSION + this.YUI_URL.DIR;
}
//YUI Loaderをload
var script = document.createElement("script");
script.type = "text/javascript";
script.src = yuiBase + "yuiloader-dom-event/yuiloader-dom-event.js";
document.getElementsByTagName("head")[0].appendChild(script);
//YUI Loaderがloadされるまで待つ
var limit = 3000, interval = 100, time = 0;
var loadedId = setInterval(function(){
if (window.YAHOO) {
clearInterval(loadedId);
//YUI Calendarをload
new YAHOO.util.YUILoader({ require: ["calendar"], base: yuiBase }).insert();
} else if ((time += interval) > limit) { //タイムアウト
clearInterval(loadedId);
}
}, interval);
};
/**
* 週の初めを月曜日にする
*/
YahhoCal.setMondayAs1st = function() {
this.YUI_CAL_CONFIG.start_weekday = 1;
};