モーダルウィンドウでカレンダーから年月日入力:閉じるボタンとか装飾あり
- <!DOCTYPE html>
- <html lang="ja">
- <head>
- <meta charset="UTF-8">
- <title>モーダルウィンドウでカレンダーから年月日入力:閉じるボタンとか装飾あり</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">
- // さぶるーちんず ===============================================
- // 桁数をそろえるために0を埋める
- function convertNumberDigits(digit, num)
- {
- var src = new String(num);
- var cnt = digit - src.length;
- if (cnt <= 0)
- {
- return "" + src;
- }
- while (cnt-- > 0){
- src = "0" + src;
- }
- return src;
- }
- /**
- * 年月日に指定された数値を足して返す
- * 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;
- }
- // カスタムバインディング ===============================================
- // モーダルウィンドウのマスク
- ko.bindingHandlers.koModalMask = {
- update: function(element, valueAccessor, allBindingsAccessor)
- {
- // 現状の値と、サブプロパティ一覧の取得
- var value = valueAccessor(), allBindings = allBindingsAccessor();
- var valueUnwrapped = ko.utils.unwrapObservable(value);
-
- // サブプロパティ:
- var maskBgColor = allBindings.maskBgColor || "#000"; // maskBgColor:マスクの背景色
- var maskOpacity = allBindings.maskOpacity || "0.3"; // maskOpacity:maskOpacityマスクの不透明度
-
- // DOMをいじる
- if (valueUnwrapped == false)
- {
- $(element).hide();
- }
- else
- {
- $(element).css({'width':$(window).width(), 'height':$(document).height()});
- $(element).css({'backgroundColor': maskBgColor});
- $(element).css({'position': 'absolute', 'left': '0', 'top': '0'});
- $(element).css({'z-index': '9000'});
- $(element).fadeTo(0, maskOpacity);
- }
- }
- };
-
- // モーダルウィンドウ
- ko.bindingHandlers.koModalWindow = {
- update: function(element, valueAccessor, allBindingsAccessor)
- {
- // 現状の値と、サブプロパティ一覧の取得
- var value = valueAccessor(), allBindings = allBindingsAccessor();
- var valueUnwrapped = ko.utils.unwrapObservable(value);
-
- // サブプロパティ:modalBgColorの値をセット
- var modalBgColor = allBindings.modalBgColor || "#fff";
-
- // DOMをいじる
- if (valueUnwrapped == false)
- {
- $(element).hide();
- }
- else
- {
- $(element).css({'backgroundColor': modalBgColor});
- $(element).css({'z-index': '9999'});
- $(element).fadeIn(500);
- }
- }
- };
- // knockout.js ===============================================
- function ViewModel() {
- var self = this;
- self.inputData = ko.observable("");
- self.maskModal = ko.observable(false);
- self.windowModal = ko.observable(false);
- var now = new Date();
- self.year = ko.observable(now.getFullYear());
- self.mont = ko.observable(now.getMonth() + 1);
- // 年月の表示
- self.valYearMonth = ko.computed( function()
- {
- return self.year() + "/" + self.mont();
- }, this);
- // カレンダー用の日にちセット
- self.dateData = ko.computed( function()
- {
- return convertDayOfCalendar(self.year(), self.mont(), "");
- }, this);
- // clickバインディング: 前月
- self.prefCal = function()
- {
- prefDate = addDate(new Date(self.year(), self.mont()-1, 1), "m", -1)
- self.year(prefDate.getFullYear());
- self.mont(prefDate.getMonth()+1);
- };
- // clickバインディング: 翌月
- self.nextCal = function()
- {
- nextDate = addDate(new Date(self.year(), self.mont()-1, 1), "m", 1)
- self.year(nextDate.getFullYear());
- self.mont(nextDate.getMonth()+1);
- };
- // clickバインディング: 今月
- self.nowCal = function()
- {
- var now = new Date();
- self.year(now.getFullYear());
- self.mont(now.getMonth()+1);
- };
- // clickバインディング: 開く
- self.openModal = function(data, event)
- {
- // 今月データの日にちを表示させる
- var now = new Date();
- self.year(now.getFullYear());
- self.mont(now.getMonth()+1);
-
- self.maskModal(true);
- self.windowModal(true);
- }
- // clickバインディング: 閉じる
- self.closeModal = function(data, event)
- {
- self.maskModal(false);
- self.windowModal(false);
- }
- // 値を入力
- self.addData = function(koData)
- {
- // 日にちの無いトコがクリックされたら何もしない。
- if (koData.toString().match(/^[0-9]+$/) != null)
- {
- viewM = convertNumberDigits(2, self.mont());
- viewD = convertNumberDigits(2, parseFloat(koData));
- ymd = self.year() + "/" + viewM + "/" + viewD;
- self.inputData(ymd);
- self.maskModal(false);
- self.windowModal(false);
- }
- }
- // 「今日」だけCSS追加
- self.cToday = function(koData)
- {
- ymd = "";
- if (koData.toString().match(/^[0-9]+$/) != null)
- {
- // 日付のあるトコがクリック:年月日表示(yyyy/mm/dd)
- viewM = convertNumberDigits(2, self.mont());
- viewD = convertNumberDigits(2, parseFloat(koData));
- ymd = self.year() + "/" + viewM + "/" + viewD;
- }
- else
- {
- // 日付のないトコがクリック
- return false;
- }
-
- var now = new Date();
- nowY = now.getFullYear();
- nowM = convertNumberDigits(2, now.getMonth()+1);
- nowD = convertNumberDigits(2, now.getDate());
- today = nowY + "/" + nowM + "/" + nowD;
-
- if (ymd == today)
- {
- return true;
- }
- return false;
- }
- }
- $(document).ready(function () {
- ko.applyBindings(new ViewModel());
- });
- </script>
- <style type="text/css">
- .inData
- {
- position:absolute;
- top:3px;
- left:80px;
- }
- .inData:before{
- content: "";
- position: absolute;
- top: 2px;
- left: 0px;
- border-top: 7px solid transparent;
- border-bottom: 7px solid transparent;
- border-right: 11px solid #999;
- }
- .inDataBox
- {
- background:#f0f0f0;
- border:1px solid #999;
- padding:30px 10px 10px;
- margin-left:10px;
- }
- .closeBtn
- {
- position:absolute;
- top:5px;
- right:5px;
- background:#666;
- color:#fff;
- font-weight:bold;
- cursor:pointer;
- font-size:10px;
- }
- .closeBtn:hover
- {
- background:#ff0000;
- }
- .calendar
- {
- border-collapse:collapse;
- margin:0;
- }
- .calendar th, .calendar td
- {
- border:1px solid #ccc;
- padding:3px;
- text-align:center;
- cursor:pointer;
- font-size:10pt;
- }
- .calendar th
- {
- background:#ffddff;
- }
- .cToday
- {
- font-weight:bold;
- }
- .calendar td:hover
- {
- background:#ffddff;
- }
- .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>
- <div data-bind="koModalMask: maskModal, maskOpacity: 0.15, click: closeModal"></div>
- <h1>モーダルウィンドウでカレンダーから年月日入力:閉じるボタンとか装飾あり</h1>
- <div style="position:relative;top:0;left:0;">
- <input type="text" tabindex="1" data-bind="value: inputData" />
- <button data-bind="click: openModal">モーダル</button><br />
- <div class="inData" data-bind="koModalWindow: windowModal, modalBgColor: 'transparent'">
- <div class="inDataBox">
- <table class="calendar">
- <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><tr><th>日</th><th>月</th><th>火</th><th>水</th><th>木</th><th>金</th><th>土</th></tr></thead>
- <tr>
- <td data-bind="text: dateData()[0], click: function(){addData(dateData()[0]); }, css: {'cToday': cToday(dateData()[0] )}" style="color:#ff0000;"></td>
- <td data-bind="text: dateData()[1], click: function(){addData(dateData()[1]); }, css: {'cToday': cToday(dateData()[1] )}"></td>
- <td data-bind="text: dateData()[2], click: function(){addData(dateData()[2]); }, css: {'cToday': cToday(dateData()[2] )}"></td>
- <td data-bind="text: dateData()[3], click: function(){addData(dateData()[3]); }, css: {'cToday': cToday(dateData()[3] )}"></td>
- <td data-bind="text: dateData()[4], click: function(){addData(dateData()[4]); }, css: {'cToday': cToday(dateData()[4] )}"></td>
- <td data-bind="text: dateData()[5], click: function(){addData(dateData()[5]); }, css: {'cToday': cToday(dateData()[5] )}"></td>
- <td data-bind="text: dateData()[6], click: function(){addData(dateData()[6]); }, css: {'cToday': cToday(dateData()[6] )}"></td>
- </tr><tr>
- <td data-bind="text: dateData()[7], click: function(){addData(dateData()[7]); }, css: {'cToday': cToday(dateData()[7] )}" style="color:#ff0000;"></td>
- <td data-bind="text: dateData()[8], click: function(){addData(dateData()[8]); }, css: {'cToday': cToday(dateData()[8] )}"></td>
- <td data-bind="text: dateData()[9], click: function(){addData(dateData()[9]); }, css: {'cToday': cToday(dateData()[9] )}"></td>
- <td data-bind="text: dateData()[10], click: function(){addData(dateData()[10]);}, css: {'cToday': cToday(dateData()[10])}"></td>
- <td data-bind="text: dateData()[11], click: function(){addData(dateData()[11]);}, css: {'cToday': cToday(dateData()[11])}"></td>
- <td data-bind="text: dateData()[12], click: function(){addData(dateData()[12]);}, css: {'cToday': cToday(dateData()[12])}"></td>
- <td data-bind="text: dateData()[13], click: function(){addData(dateData()[13]);}, css: {'cToday': cToday(dateData()[13])}"></td>
- </tr><tr>
- <td data-bind="text: dateData()[14], click: function(){addData(dateData()[14]);}, css: {'cToday': cToday(dateData()[14])}" style="color:#ff0000;"></td>
- <td data-bind="text: dateData()[15], click: function(){addData(dateData()[15]);}, css: {'cToday': cToday(dateData()[15])}"></td>
- <td data-bind="text: dateData()[16], click: function(){addData(dateData()[16]);}, css: {'cToday': cToday(dateData()[16])}"></td>
- <td data-bind="text: dateData()[17], click: function(){addData(dateData()[17]);}, css: {'cToday': cToday(dateData()[17])}"></td>
- <td data-bind="text: dateData()[18], click: function(){addData(dateData()[18]);}, css: {'cToday': cToday(dateData()[18])}"></td>
- <td data-bind="text: dateData()[19], click: function(){addData(dateData()[19]);}, css: {'cToday': cToday(dateData()[19])}"></td>
- <td data-bind="text: dateData()[20], click: function(){addData(dateData()[20]);}, css: {'cToday': cToday(dateData()[20])}"></td>
- </tr><tr>
- <td data-bind="text: dateData()[21], click: function(){addData(dateData()[21]);}, css: {'cToday': cToday(dateData()[21])}" style="color:#ff0000;"></td>
- <td data-bind="text: dateData()[22], click: function(){addData(dateData()[22]);}, css: {'cToday': cToday(dateData()[22])}"></td>
- <td data-bind="text: dateData()[23], click: function(){addData(dateData()[23]);}, css: {'cToday': cToday(dateData()[23])}"></td>
- <td data-bind="text: dateData()[24], click: function(){addData(dateData()[24]);}, css: {'cToday': cToday(dateData()[24])}"></td>
- <td data-bind="text: dateData()[25], click: function(){addData(dateData()[25]);}, css: {'cToday': cToday(dateData()[25])}"></td>
- <td data-bind="text: dateData()[26], click: function(){addData(dateData()[26]);}, css: {'cToday': cToday(dateData()[26])}"></td>
- <td data-bind="text: dateData()[27], click: function(){addData(dateData()[27]);}, css: {'cToday': cToday(dateData()[27])}"></td>
- </tr><!-- ko if: 28<dateData().length --><tr>
- <td data-bind="text: dateData()[28], click: function(){addData(dateData()[28]);}, css: {'cToday': cToday(dateData()[28])}" style="color:#ff0000;"></td>
- <td data-bind="text: dateData()[29], click: function(){addData(dateData()[29]);}, css: {'cToday': cToday(dateData()[29])}"></td>
- <td data-bind="text: dateData()[30], click: function(){addData(dateData()[30]);}, css: {'cToday': cToday(dateData()[30])}"></td>
- <td data-bind="text: dateData()[31], click: function(){addData(dateData()[31]);}, css: {'cToday': cToday(dateData()[31])}"></td>
- <td data-bind="text: dateData()[32], click: function(){addData(dateData()[32]);}, css: {'cToday': cToday(dateData()[32])}"></td>
- <td data-bind="text: dateData()[33], click: function(){addData(dateData()[33]);}, css: {'cToday': cToday(dateData()[33])}"></td>
- <td data-bind="text: dateData()[34], click: function(){addData(dateData()[34]);}, css: {'cToday': cToday(dateData()[34])}"></td>
- </tr><!-- /ko --><!-- ko if: 35<dateData().length --><tr>
- <td data-bind="text: dateData()[35], click: function(){addData(dateData()[35]);}, css: {'cToday': cToday(dateData()[35])}" style="color:#ff0000;"></td>
- <td data-bind="text: dateData()[36], click: function(){addData(dateData()[36]);}, css: {'cToday': cToday(dateData()[36])}"></td>
- <td data-bind="text: dateData()[37], click: function(){addData(dateData()[37]);}, css: {'cToday': cToday(dateData()[37])}"></td>
- <td data-bind="text: dateData()[38], click: function(){addData(dateData()[38]);}, css: {'cToday': cToday(dateData()[38])}"></td>
- <td data-bind="text: dateData()[39], click: function(){addData(dateData()[39]);}, css: {'cToday': cToday(dateData()[39])}"></td>
- <td data-bind="text: dateData()[40], click: function(){addData(dateData()[40]);}, css: {'cToday': cToday(dateData()[40])}"></td>
- <td data-bind="text: dateData()[41], click: function(){addData(dateData()[41]);}, css: {'cToday': cToday(dateData()[41])}"></td>
- </tr><!-- /ko -->
- </table>
- <span class="closeBtn" data-bind="event: {click: $root.closeModal }, clickBubble: false">×</span>
- </div>
- </div>
- </div>
- <input type="text" tabindex="2" /><br />
- <button tabindex="2" data-bind="click: function(){alert('本来ならココにDBに書き込む処理とかする');}" />登録完了</button><br />
- <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>