TiddlyWiki (切り替え可能なカレンダー)

TiddlyWikiの切り替え可能なカレンダーを作ってみた。
しかし、ちょっと不具合がある、、、。


何か変更がある状態で、月を変えると、警告メッセージが表示されてしまうのだ、、、。
なぜこうなるかは、未調査。
ま、変更したら保存する習慣をつければよいのだけど。
また、パラメータを少し変えた。

使い方

<>

パラメータ 備考
対象月の1日 Date.parse可能な日付フォーマットで。日本語環境だと、YYYY/MM/DDかな。2007/05/01とか。"-"等不正にすると当月になります
特別日 特別に背景色を設定したい日付。適当区切り(ジャーナルフォーマットに使ってない文字で区切ること)・1〜9日はゼロ補填。初期は""(なし)。"2007/05/03,2007/05/04"とか、ジャーナルフォーマット形式で指定
ジャーナルフォーマット 日付のリンク先tiddlerのタイトルフォーマット。初期は"DD MMM YYYY"だけど、日本的には"YYYY/MM/DD"か?
表示フォーマット カレンダーに表示する日付のフォーマット。初期は"DD"。0をつけたい場合は"0DD"
本日表示色 今日の背景色。初期は"#CCFFFF"。"aqua"といった指定も可
特別日表示色 特別日の背景色。初期は日曜表示色に同じ
対象月以外の表示色 週の始まりが1日でない場合、前月も表示するがその時の背景色。初期は"#CCCCCC"
土曜表示色 対象月の土曜の背景色。初期は"#CCCCFF"
日曜表示色 対象月の日曜の背景色。初期は"#FFCCFF"
開始曜日 週の始まりの曜日指定。日曜:0〜土曜:6。初期は「0」(日曜)
ヘッダ表示文字列 ヘッダ表示したい文字列を設定。日曜〜土曜。初期は"SunMonTueWedThuFriSat"。日本語表示なら"日月火水木金土"とか
ヘッダ文字位置 ヘッダのAlign属性。初期は"center"(中央寄せ)
日付文字位置 日付のAlign属性。初期は"right"(右寄せ)

  • 今月を表示する
    • <>
  • 2007年5月を表示する
    • <>
    • 休日を考えると、<>とかすると良いかもしれません。
    • 月曜開始で色も変えるなら、<>とか。

カレンダーコントロール

カレンダーコントロール的な表示も追加。(月を前後に切り替えられるようになるだけだけど)<> → <> とするだけ。
パラメータも全く一緒。

config.macros.viewCalendar = {};
config.macros.viewCalendar.handler = function(place,macroName,params) {
 // read parameters //
 var targetDate = this.getTargetDate(params[0], true);
 var special = params[1] ? params[1] : "";
 var journalFormat = params[2] ? params[2] : "DD MMM YYYY";
 var displayFormat = params[3] ? params[3] : "DD";
 var todayColor = params[4] ? params[4] : "#CCFFFF";
 var diffeMon = params[6] ? params[6] : "#CCCCCC";
 var satColor = params[7] ? params[7] : "#CCCCFF";
 var sunColor = params[8] ? params[8] : "#FFCCFF";
 var speColor = params[5] ? params[5] : sunColor;
 var startDay = params[9] ? Number(params[9]) : 0;
 var headerStr = params[10] ? params[10] : "SunMonTueWedThuFriSat";
 var headerAlign = params[11] ? params[11] : "center";
 var bodyAlign = params[12] ? params[12] : "right";
 var paraLen = params.length;
 var weekNum = 7;

 // init //
 var startDate = new Date();
 startDate.setHours(0);
 startDate.setMinutes(0);
 startDate.setSeconds(0);
 startDate.setMilliseconds(0);
 var nToday = startDate.getTime();
 nTime = targetDate.getTime();
 var nTargetDay = targetDate.getDay();
 if(nTargetDay < startDay) nTargetDay += weekNum;
 startDate.setTime(nTime - (nTargetDay - startDay) * 24 * 3600000);
 var nTargetYear = targetDate.getYear();
 var nTargetMonth = targetDate.getMonth();

 // make header //
 var theTable = createTiddlyElement(place, "table");
 theTable.setAttribute("paraLen", paraLen);
 for(i=0; i < paraLen; i++) {
  theTable.setAttribute("para"+i, params[i]);
 }
 var theTableHead = createTiddlyElement(theTable, "thead");
 theTableHead = createTiddlyElement(theTableHead, "tr");
 var headerLen = headerStr.length / weekNum;
 for(i=startDay; i < startDay + weekNum; i++) {
  var e = createTiddlyElement(theTableHead, "th", null, null, headerStr.substr(headerLen*(i%weekNum),headerLen));
  e.align = headerAlign;
 }

 // make body //
 var reSla = new RegExp("/","g");
 var theTableBody = createTiddlyElement(theTable, "tbody");
 while((startDate.getYear() == nTargetYear && startDate.getMonth() <= nTargetMonth) || startDate.getYear() < nTargetYear) {
  var theTableRecord = createTiddlyElement(theTableBody,"tr");
  for(i=0; i < weekNum; i++) {
   var theElement = createTiddlyElement(theTableRecord,"td");
   theElement.align = bodyAlign;
   var e = createTiddlyLink(theElement, startDate.formatString(journalFormat), false);
   createTiddlyText(e, startDate.formatString(displayFormat));
   // paint backgroundColor //
   var re = new RegExp(startDate.formatString(journalFormat).replace(reSla,"\\/"));
   if(startDate.getMonth() != nTargetMonth) theElement.style.backgroundColor = diffeMon;
   else if(startDate.getTime() == nToday) theElement.style.backgroundColor = todayColor;
   else if(special.match(re)) theElement.style.backgroundColor = speColor;
   else if(startDate.getDay() == 6) theElement.style.backgroundColor = satColor;
   else if(startDate.getDay() == 0) theElement.style.backgroundColor = sunColor;
   startDate.setTime(startDate.getTime() + 24 * 3600000);
  }
 }
}
config.macros.viewCalendar.getTargetDate = function(param, first) {
 // read parameters //
 var targetDate = new Date();
 targetDate.setHours(0);
 targetDate.setMinutes(0);
 targetDate.setSeconds(0);
 targetDate.setMilliseconds(0);
 var targetDateStr = param ? param : targetDate.toString();
 var nTime = Date.parse(targetDateStr);
 if(!isNaN(nTime)) targetDate.setTime(nTime);
 else if(!isNaN(targetDateStr)) targetDate.setTime(targetDateStr);
 if(first) targetDate.setDate(1);
 return targetDate;
}


// Calendar Control //
config.macros.viewCalendarControl = {};
config.macros.viewCalendarControl.handler = function(place,macroName,params) {
 var targetDate = config.macros.viewCalendar.getTargetDate(params[0],false);
 var theTable = createTiddlyElement(place, "table");
 var theTableBody = createTiddlyElement(theTable, "tbody");
 var theTableRecord = createTiddlyElement(theTableBody,"tr");
 var theElement = createTiddlyElement(theTableRecord,"td");
 theElement.align = "right";
 createTiddlyButton(theElement,"<","previous month",this.goPrev);
 theElement = createTiddlyElement(theTableRecord,"td");
 theElement.id = "idNowDate";
 theElement.align = "center";
 createTiddlyButton(theElement,targetDate.formatString("YYYY/0MM"),targetDate.formatString("YYYY/0MM/0DD"),this.goToday);
 theElement = createTiddlyElement(theTableRecord,"td");
 theElement.align = "left";
 createTiddlyButton(theElement,">","next month",this.goNext);
 theTableRecord = createTiddlyElement(theTableBody,"tr");
 theElement = createTiddlyElement(theTableRecord,"td");
 theElement.id = "idMainCalendar";
 theElement.setAttribute("colSpan",3);
 config.macros.viewCalendar.handler(theElement,macroName,params);
}
config.macros.viewCalendarControl.goPrev = function() {
 var theTable = this.parentElement.parentElement.parentElement;
 var theMonth = theTable.childNodes[0].childNodes[1];
 // 前月を取得 //
 var nowFirst = config.macros.viewCalendar.getTargetDate(theMonth.innerText + "/01",false);
 var nMonth = nowFirst.getMonth();
 if(nMonth) {
  nowFirst.setMonth(nMonth - 1);
 } else {
  nowFirst.setYear(nowFirst.getYear() - 1);
  nowFirst.setMonth(11);
 }
 config.macros.viewCalendarControl.goTarget(theTable, nowFirst);
}
config.macros.viewCalendarControl.goToday = function() {
 var theTable = this.parentElement.parentElement.parentElement;
 var theMonth = theTable.childNodes[0].childNodes[1].childNodes[0];
 // 対象日を取得 //
 var nowFirst = config.macros.viewCalendar.getTargetDate(theMonth.getAttribute("title"),true);
 config.macros.viewCalendarControl.goTarget(theTable, nowFirst);
}
config.macros.viewCalendarControl.goNext = function() {
 var theTable = this.parentElement.parentElement.parentElement;
 var theMonth = theTable.childNodes[0].childNodes[1];
 // 次月を取得 //
 var nowFirst = config.macros.viewCalendar.getTargetDate(theMonth.innerText + "/01",false);
 var nMonth = nowFirst.getMonth();
 if(nMonth != 11) {
  nowFirst.setMonth(nMonth + 1);
 } else {
  nowFirst.setYear(nowFirst.getYear() + 1);
  nowFirst.setMonth(0);
 }
 config.macros.viewCalendarControl.goTarget(theTable, nowFirst);
}
config.macros.viewCalendarControl.goTarget = function(theTable, target) {
 // 一番目の子の二番目の子が、月表示 //
 var theMonth = theTable.childNodes[0].childNodes[1];
 // 二番目の子の一番目の子が、カレンダー表示 //
 var theCalendarP = theTable.childNodes[1].childNodes[0];
 var theCalendar = theCalendarP.childNodes[0];

 // 月表示を更新 //
 theMonth.childNodes[0].innerText = target.formatString("YYYY/0MM");
 // カレンダーを更新 //
 var params = new Array(theCalendar.getAttribute("paraLen"));
 for(i = 0; i < params.length; i++) {
  params[i] = theCalendar.getAttribute("para"+i);
 }
 params[0] = target.formatString("YYYY/0MM/0DD");
 theCalendarP.innerHTML = "";
 config.macros.viewCalendar.handler(theCalendarP,"viewCalendarControl",params);
}