「カレンダー」のカスタムバインディング:ko
- <!DOCTYPE html>
- <html lang="ja">
- <head>
- <meta charset="UTF-8">
- <title>「カレンダー」のカスタムバインディング:ko</title>
- <script type="text/javascript" src="jquery-1.5.1.min.js"></script>
- <script type="text/javascript" src="knockout-2.1.0beta.js"></script>
- <script type="text/javascript">
- // (週単位で)日にち
- function makeTbodyOfCalendar(DayArray, today, nameClass)
- {
- calendar = "";
- for (i=0; i<DayArray.length; i++)
- {
- if (i == 0)
- {
- calendar += '<tr>';
- }
- else if (i%7 == 0)
- {
- calendar += '</tr>' + "\n" + '<tr>';
- }
-
- // 「今日」の場合はclassを追加。
- todayClass = "";
- if (today != "" && today == DayArray[i])
- {
- todayClass = ' class="' + nameClass + '"';
- }
- calendar += '<td' + todayClass + '>' + DayArray[i] + '</td>';
- }
- calendar += '</tr>';
- return calendar;
- }
- // 年月のチェック
- function checkDate(date)
- {
- need = date.split("/");
- if (need.length == 2)
- {
- if (1900<parseFloat(need[0]) && 1<=parseFloat(need[1]) && parseFloat(need[1])<=12)
- {
- return true;
- }
- }
- return false;
- }
-
- /**
- * 年月日に指定された数値を足して返す
- * ymdDate:日付データ
- * 追加する項目:年月日のどれか(ymd)
- * 追加する数値
- */
- function addDate(ymdDate, target, add)
- {
- addNum = parseFloat(add);
-
- yea = ymdDate.getFullYear();
- mon = ymdDate.getMonth();
- day = ymdDate.getDate();
-
- if(target == "y")
- {
- yea += addNum;
- }
- else if(target == "m")
- {
- mon += addNum;
- }
- else if(target == "d")
- {
- day += addNum;
- }
- return new Date(yea, mon, day);
- }
- /**
- * カレンダー用に日曜から1日、月末から土曜までを何かで埋め、配列にして返す
- * year 表示するカレンダーの年
- * month 表示するカレンダーの月
- * Fill 日曜から1日まで、月末から土曜まで埋める文字
- */
- function convertDayOfCalendar(year, month, Fill)
- {
- // 月初と月末
- var startMonth = new Date(year + "/" + month + "/1");
- var endMonth = addDate(new Date(year, month, 1), "d", -1);
-
- // カレンダー用に日にちを配列化:
- DayArray = new Array();
-
- // 日曜~1日の空白を埋める。
- for (i=0; i<startMonth.getDay(); i++)
- {
- DayArray.push(Fill);
- }
-
- // 月初め(1日)~月末までを埋める
- for (i=0; i<endMonth.getDate(); i++)
- {
- DayArray.push(i+1);
- }
-
- // 月末~土曜の空白を埋める
- if (endMonth.getDay() != 6)
- {
- startWeek = parseFloat(endMonth.getDay()) + 1;
- for (i=startWeek; i<7; i++)
- {
- DayArray.push(Fill);
- }
- }
- return DayArray;
- }
- // カレンダーバインディング
- // サブプロパティ:
- // koCalendarFill (指定なし:"") // 空白箇所を埋める文字
- // koCalendarToday (指定なし:"today") // 今日のclass名
- ko.bindingHandlers.koCalendar = {
- update: function(element, valueAccessor, allBindingsAccessor)
- {
- // 現状の値と、サブプロパティ一覧の取得
- var value = valueAccessor(), allBindings = allBindingsAccessor();
- var valueUnwrapped = ko.utils.unwrapObservable(value);
-
- // 各サブプロパティの取得
- var koCalendarFill = allBindings.koCalendarFill || ""; // 空白箇所を埋める文字
- var koCalendarToday = allBindings.koCalendarToday || "today"; // 今日のclass名
-
- var calendar = "";
-
- // 今日
- var now = new Date();
- var nowY = now.getFullYear(); // 現在の年
- var nowM = now.getMonth() + 1; // 現在の月
- var nowD = now.getDate(); // 現在の日
-
- // 年月が正常かチェック
- if (checkDate(valueUnwrapped) == true)
- {
- need = valueUnwrapped.split("/");
-
- y = parseFloat(need[0]);
- m = parseFloat(need[1]);
- }
- else
- {
- // 年月が異常なら今月にする
- y = nowY;
- m = nowD;
- }
-
- // 今月かチェック
- today = "";
- if (("" + nowY + nowM) == ("" + y + m))
- {
- today = nowD;
- }
-
- // カレンダー用に日を配列化(日曜から1日までを何かで埋める)
- DayArray = convertDayOfCalendar(y, m, koCalendarFill);
-
- // カレンダー用にタグを生成
- var htmltagWeek = makeTbodyOfCalendar(DayArray, today, koCalendarToday);
-
- calendar = htmltagWeek;
-
- // 処理
- if (calendar != "")
- {
- $(element).html(calendar);
- }
- else
- {
- $(element).html("");
- }
- }
- };
- $(document).ready(function () {
- ko.applyBindings(new ViewModel());
- });
- function ViewModel() {
- var self = this;
- self.valYearMonth = ko.observable("2012/06");
-
- // 前月
- self.prefCal = function()
- {
- pref = self.valYearMonth().split("/");
- if (parseFloat(pref[1]) == 1)
- {
- prefY = parseFloat(pref[0]) - 1
- prefM = "12";
- }
- else
- {
- prefY = parseFloat(pref[0]);
- prefM = parseFloat(pref[1]) - 1;
- }
- if (prefM<10)
- {
- prefM = "0" + prefM;
- }
- self.valYearMonth(prefY + "/" + prefM);
- };
-
- // 翌月
- self.nextCal = function()
- {
- next = self.valYearMonth().split("/");
- if (parseFloat(next[1]) == 12)
- {
- nextY = "" + (parseFloat(next[0]) + 1);
- nextM = "1";
- }
- else
- {
- nextY = parseFloat(next[0]);
- nextM = parseFloat(next[1]) + 1;
- }
- if (nextM<10)
- {
- nextM = "0" + nextM;
- }
- self.valYearMonth(nextY + "/" + nextM);
- };
-
- // 今月
- self.nowCal = function()
- {
- var now = new Date();
- var nowY = now.getFullYear(); // 現在の年
- var nowM = now.getMonth() + 1; // 現在の月
- if (nowM<10)
- {
- nowM = "0" + nowM;
- }
- self.valYearMonth(nowY + "/" + nowM);
- };
-
- }
- </script>
- <style type="text/css">
- th, td
- {
- border:1px solid #ccc;
- padding:3px;
- text-align:center;
- }
- .koCalendarToday
- {
- font-weight:bold;
- }
- .moveCal
- {
- color:#0000ff;
- cursor:pointer;
- }
- .moveCal:hover, .nowCal:hover
- {
- color:#ff0000;
- cursor:pointer;
- }
- .nowCal
- {
- position:absolute;
- bottom:0;
- left:3px;
- color:#0000ff;
- cursor:pointer;
- font-size:10pt;
- }
- </style>
- </head>
- <body>
- <h1>「カレンダー」のカスタムバインディング:ko</h1>
- <table>
- <caption>
- <div style="position:relative;top:0;left:0;">
- <span class="moveCal" data-bind="click: prefCal">«</span>
- <span data-bind="text: valYearMonth"></span>
- <span class="moveCal" data-bind="click: nextCal">»</span>
- <span class="nowCal" data-bind="click: nowCal">[今月]</span>
- </div>
- </caption>
- <thead>
- <th>日</th>
- <th>月</th>
- <th>火</th>
- <th>水</th>
- <th>木</th>
- <th>金</th>
- <th>土</th>
- </thead>
- <tbody data-bind="koCalendar: valYearMonth, koCalendarToday: 'koCalendarToday'"></tbody>
- </table>
- <div style="font-size:10pt;text-align:right;margin-top:0.5em;">
- <a href="//tips.recatnap.info/" target="_top">PCスキルの小技・忘却防止メモ</a> -
- <a href="//tips.recatnap.info/wiki/" target="_top">PCスキルの小技・忘却防止メモのまとめ(wiki)</a>
- </div>
- <div style="font-size:10pt;text-align:center;margin-top:0.5em;padding:0.5em;border-top:1px solid #ccc;">
- Copyright © 2009 by PCスキルの小技・忘却防止メモ. All rights reserved.
- </div>
- </body>
- </html>