3 |
3 |
4 Copyright (c) 2007 Marc Grabanski (http://marcgrabanski.com/code/ui-datetimepicker) |
4 Copyright (c) 2007 Marc Grabanski (http://marcgrabanski.com/code/ui-datetimepicker) |
5 Dual licensed under the MIT (MIT-LICENSE.txt) |
5 Dual licensed under the MIT (MIT-LICENSE.txt) |
6 and GPL (GPL-LICENSE.txt) licenses. |
6 and GPL (GPL-LICENSE.txt) licenses. |
7 Date: 09-03-2007 */ |
7 Date: 09-03-2007 */ |
8 /* |
8 /* |
9 * Time functionality added by Stanislav Dobry (stanislav.dobry@datesoft.cz) |
9 * Time functionality added by Stanislav Dobry (stanislav.dobry@datesoft.cz) |
10 * Date: 2008-06-04 |
10 * Date: 2008-06-04 |
11 */ |
11 */ |
12 |
12 |
13 ;(function($) { // hide the namespace |
13 ;(function($) { // hide the namespace |
14 |
14 |
15 /* Date picker manager. |
15 /* Date picker manager. |
16 Use the singleton instance of this class, $.datetimepicker, to interact with the date picker. |
16 Use the singleton instance of this class, $.datetimepicker, to interact with the date picker. |
17 Settings for (groups of) date pickers are maintained in an instance object |
17 Settings for (groups of) date pickers are maintained in an instance object |
78 showOtherMonths: false, // True to show dates in other months, false to leave blank |
78 showOtherMonths: false, // True to show dates in other months, false to leave blank |
79 showWeeks: false, // True to show week of the year, false to omit |
79 showWeeks: false, // True to show week of the year, false to omit |
80 calculateWeek: this.iso8601Week, // How to calculate the week of the year, |
80 calculateWeek: this.iso8601Week, // How to calculate the week of the year, |
81 // takes a Date and returns the number of the week for it |
81 // takes a Date and returns the number of the week for it |
82 shortYearCutoff: '+10', // Short year values < this are in the current century, |
82 shortYearCutoff: '+10', // Short year values < this are in the current century, |
83 // > this are in the previous century, |
83 // > this are in the previous century, |
84 // string value starting with '+' for current year + value |
84 // string value starting with '+' for current year + value |
85 showStatus: false, // True to show status bar at bottom, false to not show it |
85 showStatus: false, // True to show status bar at bottom, false to not show it |
86 statusForDate: this.dateStatus, // Function to provide status text for a date - |
86 statusForDate: this.dateStatus, // Function to provide status text for a date - |
87 // takes date and instance as parameters, returns display text |
87 // takes date and instance as parameters, returns display text |
88 minDate: null, // The earliest selectable date, or null for no limit |
88 minDate: null, // The earliest selectable date, or null for no limit |
111 /* Debug logging (if enabled). */ |
111 /* Debug logging (if enabled). */ |
112 log: function () { |
112 log: function () { |
113 if (this.debug) |
113 if (this.debug) |
114 console.log.apply('', arguments); |
114 console.log.apply('', arguments); |
115 }, |
115 }, |
116 |
116 |
117 /* Register a new date picker instance - with custom settings. */ |
117 /* Register a new date picker instance - with custom settings. */ |
118 _register: function(inst) { |
118 _register: function(inst) { |
119 var id = this._nextId++; |
119 var id = this._nextId++; |
120 this._inst[id] = inst; |
120 this._inst[id] = inst; |
121 return id; |
121 return id; |
124 /* Retrieve a particular date picker instance based on its ID. */ |
124 /* Retrieve a particular date picker instance based on its ID. */ |
125 _getInst: function(id) { |
125 _getInst: function(id) { |
126 return this._inst[id] || id; |
126 return this._inst[id] || id; |
127 }, |
127 }, |
128 |
128 |
129 /* Override the default settings for all instances of the date picker. |
129 /* Override the default settings for all instances of the date picker. |
130 @param settings object - the new settings to use as defaults (anonymous object) |
130 @param settings object - the new settings to use as defaults (anonymous object) |
131 @return the manager object */ |
131 @return the manager object */ |
132 setDefaults: function(settings) { |
132 setDefaults: function(settings) { |
133 extendRemove(this._defaults, settings || {}); |
133 extendRemove(this._defaults, settings || {}); |
134 return this; |
134 return this; |
150 inlineSettings[attrName] = attrValue; |
150 inlineSettings[attrName] = attrValue; |
151 } |
151 } |
152 } |
152 } |
153 } |
153 } |
154 var nodeName = target.nodeName.toLowerCase(); |
154 var nodeName = target.nodeName.toLowerCase(); |
155 var instSettings = (inlineSettings ? |
155 var instSettings = (inlineSettings ? |
156 $.extend(settings || {}, inlineSettings || {}) : settings); |
156 $.extend(settings || {}, inlineSettings || {}) : settings); |
157 if (nodeName == 'input') { |
157 if (nodeName == 'input') { |
158 var inst = (inst && !inlineSettings ? inst : |
158 var inst = (inst && !inlineSettings ? inst : |
159 new DateTimepickerInstance(instSettings, false)); |
159 new DateTimepickerInstance(instSettings, false)); |
160 this._connectDatepicker(target, inst); |
160 this._connectDatepicker(target, inst); |
321 input.focus(this._showDatepicker); |
321 input.focus(this._showDatepicker); |
322 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked |
322 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked |
323 input.wrap('<span class="datetimepicker_wrap">'); |
323 input.wrap('<span class="datetimepicker_wrap">'); |
324 var buttonText = inst._get('buttonText'); |
324 var buttonText = inst._get('buttonText'); |
325 var buttonImage = inst._get('buttonImage'); |
325 var buttonImage = inst._get('buttonImage'); |
326 var trigger = $(inst._get('buttonImageOnly') ? |
326 var trigger = $(inst._get('buttonImageOnly') ? |
327 $('<img>').addClass('datetimepicker_trigger').attr({ src: buttonImage, alt: buttonText, title: buttonText }) : |
327 $('<img>').addClass('datetimepicker_trigger').attr({ src: buttonImage, alt: buttonText, title: buttonText }) : |
328 $('<button>').addClass('datetimepicker_trigger').attr({ type: 'button' }).html(buttonImage != '' ? |
328 $('<button>').addClass('datetimepicker_trigger').attr({ type: 'button' }).html(buttonImage != '' ? |
329 $('<img>').attr({ src:buttonImage, alt:buttonText, title:buttonText }) : buttonText)); |
329 $('<img>').attr({ src:buttonImage, alt:buttonText, title:buttonText }) : buttonText)); |
330 if (isRTL) |
330 if (isRTL) |
331 input.before(trigger); |
331 input.before(trigger); |
332 else |
332 else |
333 input.after(trigger); |
333 input.after(trigger); |
364 |
364 |
365 /* Tidy up after displaying the date picker. */ |
365 /* Tidy up after displaying the date picker. */ |
366 _inlineShow: function(inst) { |
366 _inlineShow: function(inst) { |
367 var numMonths = inst._getNumberOfMonths(); // fix width for dynamic number of date pickers |
367 var numMonths = inst._getNumberOfMonths(); // fix width for dynamic number of date pickers |
368 inst._datetimepickerDiv.width(numMonths[1] * $('.datetimepicker', inst._datetimepickerDiv[0]).width()); |
368 inst._datetimepickerDiv.width(numMonths[1] * $('.datetimepicker', inst._datetimepickerDiv[0]).width()); |
369 }, |
369 }, |
370 |
370 |
371 /* Pop-up the date picker in a "dialog" box. |
371 /* Pop-up the date picker in a "dialog" box. |
372 @param input element - ignored |
372 @param input element - ignored |
373 @param dateText string - the initial date to display (in the current format) |
373 @param dateText string - the initial date to display (in the current format) |
374 @param onSelect function - the function(dateText) to call when a date is selected |
374 @param onSelect function - the function(dateText) to call when a date is selected |
509 inst._datetimepickerDiv.css('top', Math.max(scrollY, |
509 inst._datetimepickerDiv.css('top', Math.max(scrollY, |
510 pos[1] - (this._inDialog ? 0 : inst._datetimepickerDiv.height()) - |
510 pos[1] - (this._inDialog ? 0 : inst._datetimepickerDiv.height()) - |
511 (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0)) + 'px'); |
511 (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0)) + 'px'); |
512 } |
512 } |
513 }, |
513 }, |
514 |
514 |
515 /* Find an object's position on the screen. */ |
515 /* Find an object's position on the screen. */ |
516 _findPos: function(obj) { |
516 _findPos: function(obj) { |
517 while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) { |
517 while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) { |
518 obj = obj.nextSibling; |
518 obj = obj.nextSibling; |
519 } |
519 } |
612 var inst = this._getInst(id); |
612 var inst = this._getInst(id); |
613 inst._selectingMonthYear = false; |
613 inst._selectingMonthYear = false; |
614 inst[period == 'M' ? '_drawMinute' : '_drawHour'] = |
614 inst[period == 'M' ? '_drawMinute' : '_drawHour'] = |
615 select.options[select.selectedIndex].value - 0; |
615 select.options[select.selectedIndex].value - 0; |
616 this._adjustDate(inst); |
616 this._adjustDate(inst); |
617 |
617 |
618 this._doNotHide = true; |
618 this._doNotHide = true; |
619 $('td.datetimepicker_currentDay').each(function(){ |
619 $('td.datetimepicker_currentDay').each(function(){ |
620 $.datetimepicker._selectDay(inst, inst._selectedMonth, inst._selectedYear,$(this)); |
620 $.datetimepicker._selectDay(inst, inst._selectedMonth, inst._selectedYear,$(this)); |
621 }); |
621 }); |
622 this._doNotHide = false; |
622 this._doNotHide = false; |
652 var rangeSelect = inst._get('rangeSelect'); |
652 var rangeSelect = inst._get('rangeSelect'); |
653 if (rangeSelect) { |
653 if (rangeSelect) { |
654 if (!this._stayOpen) { |
654 if (!this._stayOpen) { |
655 $('.datetimepicker td').removeClass('datetimepicker_currentDay'); |
655 $('.datetimepicker td').removeClass('datetimepicker_currentDay'); |
656 $(td).addClass('datetimepicker_currentDay'); |
656 $(td).addClass('datetimepicker_currentDay'); |
657 } |
657 } |
658 this._stayOpen = !this._stayOpen; |
658 this._stayOpen = !this._stayOpen; |
659 } |
659 } |
660 inst._selectedDay = inst._currentDay = $('a', td).html(); |
660 inst._selectedDay = inst._currentDay = $('a', td).html(); |
661 inst._selectedMonth = inst._currentMonth = month; |
661 inst._selectedMonth = inst._currentMonth = month; |
662 inst._selectedYear = inst._currentYear = year; |
662 inst._selectedYear = inst._currentYear = year; |
723 @return [boolean, string] - is this date selectable?, what is its CSS class? */ |
723 @return [boolean, string] - is this date selectable?, what is its CSS class? */ |
724 noWeekends: function(date) { |
724 noWeekends: function(date) { |
725 var day = date.getDay(); |
725 var day = date.getDay(); |
726 return [(day > 0 && day < 6), '']; |
726 return [(day > 0 && day < 6), '']; |
727 }, |
727 }, |
728 |
728 |
729 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. |
729 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. |
730 @param date Date - the date to get the week for |
730 @param date Date - the date to get the week for |
731 @return number - the number of the week within the year that contains this date */ |
731 @return number - the number of the week within the year that contains this date */ |
732 iso8601Week: function(date) { |
732 iso8601Week: function(date) { |
733 var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), (date.getTimezoneOffset() / -60)); |
733 var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), (date.getTimezoneOffset() / -60)); |
744 return $.datetimepicker.iso8601Week(checkDate); |
744 return $.datetimepicker.iso8601Week(checkDate); |
745 } |
745 } |
746 } |
746 } |
747 return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date |
747 return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date |
748 }, |
748 }, |
749 |
749 |
750 /* Provide status text for a particular date. |
750 /* Provide status text for a particular date. |
751 @param date the date to get the status for |
751 @param date the date to get the status for |
752 @param inst the current datetimepicker instance |
752 @param inst the current datetimepicker instance |
753 @return the status display text for this date */ |
753 @return the status display text for this date */ |
754 dateStatus: function(date, inst) { |
754 dateStatus: function(date, inst) { |
799 // Check whether a format character is doubled |
799 // Check whether a format character is doubled |
800 var lookAhead = function(match) { |
800 var lookAhead = function(match) { |
801 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); |
801 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); |
802 if (matches) |
802 if (matches) |
803 iFormat++; |
803 iFormat++; |
804 return matches; |
804 return matches; |
805 }; |
805 }; |
806 // Extract a number from the string value |
806 // Extract a number from the string value |
807 var getNumber = function(match) { |
807 var getNumber = function(match) { |
808 lookAhead(match); |
808 lookAhead(match); |
809 var size = (match == 'y' ? 4 : 2); |
809 var size = (match == 'y' ? 4 : 2); |
856 minute = getNumber('i'); |
856 minute = getNumber('i'); |
857 break; |
857 break; |
858 case 'd': |
858 case 'd': |
859 day = getNumber('d'); |
859 day = getNumber('d'); |
860 break; |
860 break; |
861 case 'D': |
861 case 'D': |
862 getName('D', dayNamesShort, dayNames); |
862 getName('D', dayNamesShort, dayNames); |
863 break; |
863 break; |
864 case 'm': |
864 case 'm': |
865 month = getNumber('m'); |
865 month = getNumber('m'); |
866 break; |
866 break; |
867 case 'M': |
867 case 'M': |
868 month = getName('M', monthNamesShort, monthNames); |
868 month = getName('M', monthNamesShort, monthNames); |
869 break; |
869 break; |
870 case 'y': |
870 case 'y': |
871 year = getNumber('y'); |
871 year = getNumber('y'); |
872 break; |
872 break; |
873 case "'": |
873 case "'": |
924 // Check whether a format character is doubled |
924 // Check whether a format character is doubled |
925 var lookAhead = function(match) { |
925 var lookAhead = function(match) { |
926 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); |
926 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); |
927 if (matches) |
927 if (matches) |
928 iFormat++; |
928 iFormat++; |
929 return matches; |
929 return matches; |
930 }; |
930 }; |
931 // Format a number, with leading zero if necessary |
931 // Format a number, with leading zero if necessary |
932 var formatNumber = function(match, value) { |
932 var formatNumber = function(match, value) { |
933 return (lookAhead(match) && value < 10 ? '0' : '') + value; |
933 return (lookAhead(match) && value < 10 ? '0' : '') + value; |
934 }; |
934 }; |
952 break; |
952 break; |
953 case 'i': |
953 case 'i': |
954 output += formatNumber('i', date.getMinutes()); |
954 output += formatNumber('i', date.getMinutes()); |
955 break; |
955 break; |
956 case 'd': |
956 case 'd': |
957 output += formatNumber('d', date.getDate()); |
957 output += formatNumber('d', date.getDate()); |
958 break; |
958 break; |
959 case 'D': |
959 case 'D': |
960 output += formatName('D', date.getDay(), dayNamesShort, dayNames); |
960 output += formatName('D', date.getDay(), dayNamesShort, dayNames); |
961 break; |
961 break; |
962 case 'm': |
962 case 'm': |
963 output += formatNumber('m', date.getMonth() + 1); |
963 output += formatNumber('m', date.getMonth() + 1); |
964 break; |
964 break; |
965 case 'M': |
965 case 'M': |
966 output += formatName('M', date.getMonth(), monthNamesShort, monthNames); |
966 output += formatName('M', date.getMonth(), monthNamesShort, monthNames); |
967 break; |
967 break; |
968 case 'y': |
968 case 'y': |
969 output += (lookAhead('y') ? date.getFullYear() : |
969 output += (lookAhead('y') ? date.getFullYear() : |
970 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); |
970 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); |
971 break; |
971 break; |
972 case "'": |
972 case "'": |
973 if (lookAhead("'")) |
973 if (lookAhead("'")) |
974 output += "'"; |
974 output += "'"; |
1042 |
1042 |
1043 /* Parse existing date and initialise date picker. */ |
1043 /* Parse existing date and initialise date picker. */ |
1044 _setDateFromField: function(input) { |
1044 _setDateFromField: function(input) { |
1045 this._input = $(input); |
1045 this._input = $(input); |
1046 var dateFormat = this._get('dateFormat')+' '+this._get('timeFormat'); |
1046 var dateFormat = this._get('dateFormat')+' '+this._get('timeFormat'); |
1047 var dates = this._input ? this._input.val().split(this._get('rangeSeparator')) : null; |
1047 var dates = this._input ? this._input.val().split(this._get('rangeSeparator')) : null; |
1048 this._endDay = this._endMonth = this._endYear = null; |
1048 this._endDay = this._endMonth = this._endYear = null; |
1049 var date = defaultDate = this._getDefaultDate(); |
1049 var date = defaultDate = this._getDefaultDate(); |
1050 if (dates.length > 0) { |
1050 if (dates.length > 0) { |
1051 var settings = this._getFormatConfig(); |
1051 var settings = this._getFormatConfig(); |
1052 if (dates.length > 1) { |
1052 if (dates.length > 1) { |
1070 this._currentDay = (dates[0] ? date.getDate() : 0); |
1070 this._currentDay = (dates[0] ? date.getDate() : 0); |
1071 this._currentMonth = (dates[0] ? date.getMonth() : 0); |
1071 this._currentMonth = (dates[0] ? date.getMonth() : 0); |
1072 this._currentYear = (dates[0] ? date.getFullYear() : 0); |
1072 this._currentYear = (dates[0] ? date.getFullYear() : 0); |
1073 this._adjustDate(); |
1073 this._adjustDate(); |
1074 }, |
1074 }, |
1075 |
1075 |
1076 /* Retrieve the default date shown on opening. */ |
1076 /* Retrieve the default date shown on opening. */ |
1077 _getDefaultDate: function() { |
1077 _getDefaultDate: function() { |
1078 var date = this._determineDate('defaultDate', new Date()); |
1078 var date = this._determineDate('defaultDate', new Date()); |
1079 var minDate = this._getMinMaxDate('min', true); |
1079 var minDate = this._getMinMaxDate('min', true); |
1080 var maxDate = this._getMinMaxDate('max'); |
1080 var maxDate = this._getMinMaxDate('max'); |
1101 case 'd' : case 'D' : |
1101 case 'd' : case 'D' : |
1102 day += (matches[1] - 0); break; |
1102 day += (matches[1] - 0); break; |
1103 case 'w' : case 'W' : |
1103 case 'w' : case 'W' : |
1104 day += (matches[1] * 7); break; |
1104 day += (matches[1] * 7); break; |
1105 case 'm' : case 'M' : |
1105 case 'm' : case 'M' : |
1106 month += (matches[1] - 0); |
1106 month += (matches[1] - 0); |
1107 day = Math.min(day, getDaysInMonth(year, month)); |
1107 day = Math.min(day, getDaysInMonth(year, month)); |
1108 break; |
1108 break; |
1109 case 'y': case 'Y' : |
1109 case 'y': case 'Y' : |
1110 year += (matches[1] - 0); |
1110 year += (matches[1] - 0); |
1111 day = Math.min(day, getDaysInMonth(year, month)); |
1111 day = Math.min(day, getDaysInMonth(year, month)); |
1159 today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time |
1159 today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time |
1160 var showStatus = this._get('showStatus'); |
1160 var showStatus = this._get('showStatus'); |
1161 var isRTL = this._get('isRTL'); |
1161 var isRTL = this._get('isRTL'); |
1162 // build the date picker HTML |
1162 // build the date picker HTML |
1163 var clear = (this._get('mandatory') ? '' : |
1163 var clear = (this._get('mandatory') ? '' : |
1164 '<div class="datetimepicker_clear"><a onclick="jQuery.datetimepicker._clearDate(' + this._id + ');"' + |
1164 '<div class="datetimepicker_clear"><a onclick="jQuery.datetimepicker._clearDate(' + this._id + ');"' + |
1165 (showStatus ? this._addStatus(this._get('clearStatus') || ' ') : '') + '>' + |
1165 (showStatus ? this._addStatus(this._get('clearStatus') || ' ') : '') + '>' + |
1166 this._get('clearText') + '</a></div>'); |
1166 this._get('clearText') + '</a></div>'); |
1167 var controls = '<div class="datetimepicker_control">' + (isRTL ? '' : clear) + |
1167 var controls = '<div class="datetimepicker_control">' + (isRTL ? '' : clear) + |
1168 '<div class="datetimepicker_close"><a onclick="jQuery.datetimepicker._hideDatepicker();"' + |
1168 '<div class="datetimepicker_close"><a onclick="jQuery.datetimepicker._hideDatepicker();"' + |
1169 (showStatus ? this._addStatus(this._get('closeStatus') || ' ') : '') + '>' + |
1169 (showStatus ? this._addStatus(this._get('closeStatus') || ' ') : '') + '>' + |
1191 drawYear--; |
1191 drawYear--; |
1192 } |
1192 } |
1193 } |
1193 } |
1194 } |
1194 } |
1195 // controls and links |
1195 // controls and links |
1196 var prev = '<div class="datetimepicker_prev">' + (this._canAdjustMonth(-1, drawYear, drawMonth) ? |
1196 var prev = '<div class="datetimepicker_prev">' + (this._canAdjustMonth(-1, drawYear, drawMonth) ? |
1197 '<a onclick="jQuery.datetimepicker._adjustDate(' + this._id + ', -' + stepMonths + ', \'M\');"' + |
1197 '<a onclick="jQuery.datetimepicker._adjustDate(' + this._id + ', -' + stepMonths + ', \'M\');"' + |
1198 (showStatus ? this._addStatus(this._get('prevStatus') || ' ') : '') + '>' + |
1198 (showStatus ? this._addStatus(this._get('prevStatus') || ' ') : '') + '>' + |
1199 this._get('prevText') + '</a>' : |
1199 this._get('prevText') + '</a>' : |
1200 (hideIfNoPrevNext ? '' : '<label>' + this._get('prevText') + '</label>')) + '</div>'; |
1200 (hideIfNoPrevNext ? '' : '<label>' + this._get('prevText') + '</label>')) + '</div>'; |
1201 var next = '<div class="datetimepicker_next">' + (this._canAdjustMonth(+1, drawYear, drawMonth) ? |
1201 var next = '<div class="datetimepicker_next">' + (this._canAdjustMonth(+1, drawYear, drawMonth) ? |
1215 for (var col = 0; col < numMonths[1]; col++) { |
1215 for (var col = 0; col < numMonths[1]; col++) { |
1216 var selectedDate = new Date(drawYear, drawMonth, this._selectedDay, drawHour, drawMinute); |
1216 var selectedDate = new Date(drawYear, drawMonth, this._selectedDay, drawHour, drawMinute); |
1217 html += '<div class="datetimepicker_oneMonth' + (col == 0 ? ' datetimepicker_newRow' : '') + '">' + |
1217 html += '<div class="datetimepicker_oneMonth' + (col == 0 ? ' datetimepicker_newRow' : '') + '">' + |
1218 this._generateMonthYearHeader(drawMinute,drawHour,drawMonth, drawYear, minDate, maxDate, |
1218 this._generateMonthYearHeader(drawMinute,drawHour,drawMonth, drawYear, minDate, maxDate, |
1219 selectedDate, row > 0 || col > 0) + // draw month headers |
1219 selectedDate, row > 0 || col > 0) + // draw month headers |
1220 '<table class="datetimepicker" cellpadding="0" cellspacing="0"><thead>' + |
1220 '<table class="datetimepicker" cellpadding="0" cellspacing="0"><thead>' + |
1221 '<tr class="datetimepicker_titleRow">' + |
1221 '<tr class="datetimepicker_titleRow">' + |
1222 (showWeeks ? '<td>' + this._get('weekHeader') + '</td>' : ''); |
1222 (showWeeks ? '<td>' + this._get('weekHeader') + '</td>' : ''); |
1223 var firstDay = this._get('firstDay'); |
1223 var firstDay = this._get('firstDay'); |
1224 var changeFirstDay = this._get('changeFirstDay'); |
1224 var changeFirstDay = this._get('changeFirstDay'); |
1225 var dayNames = this._get('dayNames'); |
1225 var dayNames = this._get('dayNames'); |
1230 var status = this._get('dayStatus') || ' '; |
1230 var status = this._get('dayStatus') || ' '; |
1231 status = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) : |
1231 status = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) : |
1232 status.replace(/D/, dayNamesShort[day])); |
1232 status.replace(/D/, dayNamesShort[day])); |
1233 html += '<td' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="datetimepicker_weekEndCell"' : '') + '>' + |
1233 html += '<td' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="datetimepicker_weekEndCell"' : '') + '>' + |
1234 (!changeFirstDay ? '<span' : |
1234 (!changeFirstDay ? '<span' : |
1235 '<a onclick="jQuery.datetimepicker._changeFirstDay(' + this._id + ', ' + day + ');"') + |
1235 '<a onclick="jQuery.datetimepicker._changeFirstDay(' + this._id + ', ' + day + ');"') + |
1236 (showStatus ? this._addStatus(status) : '') + ' title="' + dayNames[day] + '">' + |
1236 (showStatus ? this._addStatus(status) : '') + ' title="' + dayNames[day] + '">' + |
1237 dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</td>'; |
1237 dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</td>'; |
1238 } |
1238 } |
1239 html += '</tr></thead><tbody>'; |
1239 html += '</tr></thead><tbody>'; |
1240 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); |
1240 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); |
1289 drawMonth = 0; |
1289 drawMonth = 0; |
1290 drawYear++; |
1290 drawYear++; |
1291 } |
1291 } |
1292 html += '</tbody></table></div>'; |
1292 html += '</tbody></table></div>'; |
1293 } |
1293 } |
1294 html += (showStatus ? '<div style="clear: both;"></div><div id="datetimepicker_status_' + this._id + |
1294 html += (showStatus ? '<div style="clear: both;"></div><div id="datetimepicker_status_' + this._id + |
1295 '" class="datetimepicker_status">' + (this._get('initStatus') || ' ') + '</div>' : '') + |
1295 '" class="datetimepicker_status">' + (this._get('initStatus') || ' ') + '</div>' : '') + |
1296 (!closeAtTop && !this._inline ? controls : '') + |
1296 (!closeAtTop && !this._inline ? controls : '') + |
1297 '<div style="clear: both;"></div>' + |
1297 '<div style="clear: both;"></div>' + |
1298 ($.browser.msie && parseInt($.browser.version) < 7 && !this._inline ? |
1298 ($.browser.msie && parseInt($.browser.version) < 7 && !this._inline ? |
1299 '<iframe src="javascript:false;" class="datetimepicker_cover"></iframe>' : ''); |
1299 '<iframe src="javascript:false;" class="datetimepicker_cover"></iframe>' : ''); |
1300 return html; |
1300 return html; |
1301 }, |
1301 }, |
1302 |
1302 |
1303 /* Generate the month and year header. */ |
1303 /* Generate the month and year header. */ |
1304 _generateMonthYearHeader: function(drawMinute,drawHour,drawMonth, drawYear, minDate, maxDate, selectedDate, secondary) { |
1304 _generateMonthYearHeader: function(drawMinute,drawHour,drawMonth, drawYear, minDate, maxDate, selectedDate, secondary) { |
1305 minDate = (this._rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate); |
1305 minDate = (this._rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate); |
1306 var showStatus = this._get('showStatus'); |
1306 var showStatus = this._get('showStatus'); |
1307 var html = '<div class="datetimepicker_header">'; |
1307 var html = '<div class="datetimepicker_header">'; |
1308 // month selection |
1308 // month selection |
1309 var monthNames = this._get('monthNames'); |
1309 var monthNames = this._get('monthNames'); |
1310 if (secondary || !this._get('changeMonth')) |
1310 if (secondary || !this._get('changeMonth')) |
1311 html += monthNames[drawMonth] + ' '; |
1311 html += monthNames[drawMonth] + ' '; |
1312 |
1312 |
1313 else { |
1313 else { |
1314 var inMinYear = (minDate && minDate.getFullYear() == drawYear); |
1314 var inMinYear = (minDate && minDate.getFullYear() == drawYear); |
1315 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); |
1315 var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); |
1316 html += '<select class="datetimepicker_newMonth" ' + |
1316 html += '<select class="datetimepicker_newMonth" ' + |
1317 'onchange="jQuery.datetimepicker._selectMonthYear(' + this._id + ', this, \'M\');" ' + |
1317 'onchange="jQuery.datetimepicker._selectMonthYear(' + this._id + ', this, \'M\');" ' + |
1411 this._drawMonth = this._selectedMonth = date.getMonth(); |
1411 this._drawMonth = this._selectedMonth = date.getMonth(); |
1412 this._drawYear = this._selectedYear = date.getFullYear(); |
1412 this._drawYear = this._selectedYear = date.getFullYear(); |
1413 this._drawHour = this._selectedHour = date.getHours(); |
1413 this._drawHour = this._selectedHour = date.getHours(); |
1414 this._drawMinute = this._selectedMinute = date.getMinutes(); |
1414 this._drawMinute = this._selectedMinute = date.getMinutes(); |
1415 }, |
1415 }, |
1416 |
1416 |
1417 /* Determine the number of months to show. */ |
1417 /* Determine the number of months to show. */ |
1418 _getNumberOfMonths: function() { |
1418 _getNumberOfMonths: function() { |
1419 var numMonths = this._get('numberOfMonths'); |
1419 var numMonths = this._get('numberOfMonths'); |
1420 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); |
1420 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); |
1421 }, |
1421 }, |
1459 newMinDate = (newMinDate && this._rangeStart < newMinDate ? this._rangeStart : newMinDate); |
1459 newMinDate = (newMinDate && this._rangeStart < newMinDate ? this._rangeStart : newMinDate); |
1460 var minDate = newMinDate || this._getMinMaxDate('min'); |
1460 var minDate = newMinDate || this._getMinMaxDate('min'); |
1461 var maxDate = this._getMinMaxDate('max'); |
1461 var maxDate = this._getMinMaxDate('max'); |
1462 return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate)); |
1462 return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate)); |
1463 }, |
1463 }, |
1464 |
1464 |
1465 /* Provide the configuration settings for formatting/parsing. */ |
1465 /* Provide the configuration settings for formatting/parsing. */ |
1466 _getFormatConfig: function() { |
1466 _getFormatConfig: function() { |
1467 var shortYearCutoff = this._get('shortYearCutoff'); |
1467 var shortYearCutoff = this._get('shortYearCutoff'); |
1468 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : |
1468 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : |
1469 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); |
1469 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); |
1511 $.datetimepicker._attachDatepicker(this, options); |
1511 $.datetimepicker._attachDatepicker(this, options); |
1512 }); |
1512 }); |
1513 }; |
1513 }; |
1514 |
1514 |
1515 $.datetimepicker = new DateTimepicker(); // singleton instance |
1515 $.datetimepicker = new DateTimepicker(); // singleton instance |
1516 |
1516 |
1517 /* Initialise the date picker. */ |
1517 /* Initialise the date picker. */ |
1518 $(document).ready(function() { |
1518 $(document).ready(function() { |
1519 $(document.body).append($.datetimepicker._datetimepickerDiv) |
1519 $(document.body).append($.datetimepicker._datetimepickerDiv) |
1520 .mousedown($.datetimepicker._checkExternalClick); |
1520 .mousedown($.datetimepicker._checkExternalClick); |
1521 }); |
1521 }); |