2015年5月13日 星期三

Bootstrap Datepicker增加民國年顯示

修改bootstrap-datepicker.js

1. 檔案開頭加入pad函數
(function ($, undefined) {

var pad = function (val, len) {

         val = String(val);

         len = len || 2;

         while (val.length < len) val = "0" + val;

         return val;

     };


2. fill字段增加西元年及民國年轉換
fill: function () {
             var d = new Date(this.viewDate),
                 year = d.getUTCFullYear(),
                 month = d.getUTCMonth(),
                 startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
                 startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
                 endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
                 endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
                 todaytxt = dates[this.o.language].today || dates['en'].today || '',
                 cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
                 tooltip;
             if (isNaN(year) || isNaN(month))
                 return;
             this.picker.find('.datepicker-days thead .datepicker-switch')
                         .text(dates[this.o.language].months[month] + ' ' + (year - (this.o.language == "zh-TW" ? 1911 : 0)));
             this.picker.find('tfoot .today')
                         .text(todaytxt)
                         .toggle(this.o.todayBtn !== false);
             this.picker.find('tfoot .clear')
                         .text(cleartxt)
                         .toggle(this.o.clearBtn !== false);
             this.updateNavArrows();
             this.fillMonths();
             var prevMonth = UTCDate(year, month - 1, 28),
                 day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
             prevMonth.setUTCDate(day);
             prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7) % 7);
             var nextMonth = new Date(prevMonth);
             nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
             nextMonth = nextMonth.valueOf();
             var html = [];
             var clsName;
             while (prevMonth.valueOf() < nextMonth) {
                 if (prevMonth.getUTCDay() === this.o.weekStart) {
                     html.push('');
                     if (this.o.calendarWeeks) {
                         // ISO 8601: First week contains first thursday.
                         // ISO also states week starts on Monday, but we can be more abstract here.
                         var
                             // Start of current week: based on weekstart/current date
                             ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
                             // Thursday of this week
                             th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
                             // First Thursday of year, year from thursday
                             yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay()) % 7 * 864e5),
                             // Calendar week: ms between thursdays, div ms per day, div 7 days
                             calWeek = (th - yth) / 864e5 / 7 + 1;
                         html.push('

' + calWeek + '

');

                     }
                 }
                 clsName = this.getClassNames(prevMonth);
                 clsName.push('day');

                 if (this.o.beforeShowDay !== $.noop) {
                     var before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
                     if (before === undefined)
                         before = {};
                     else if (typeof (before) === 'boolean')
                         before = { enabled: before };
                     else if (typeof (before) === 'string')
                         before = { classes: before };
                     if (before.enabled === false)
                         clsName.push('disabled');
                     if (before.classes)
                         clsName = clsName.concat(before.classes.split(/\s+/));
                     if (before.tooltip)
                         tooltip = before.tooltip;
                 }

                 clsName = $.unique(clsName);
                 html.push('' + prevMonth.getUTCDate() + '

');
                 tooltip = null;
                 if (prevMonth.getUTCDay() === this.o.weekEnd) {
                     html.push('');
                 }
                 prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
             }
             this.picker.find('.datepicker-days tbody').empty().append(html.join(''));

             var months = this.picker.find('.datepicker-months')
                         .find('th:eq(1)')
                             .text(year - (this.o.language == "zh-TW" ? 1911 : 0))
                             .end()
                         .find('span').removeClass('active');

             $.each(this.dates, function (i, d) {
                 if (d.getUTCFullYear() === year)
                     months.eq(d.getUTCMonth()).addClass('active');
             });

             if (year < startYear || year > endYear) {
                 months.addClass('disabled');
             }
             if (year === startYear) {
                 months.slice(0, startMonth).addClass('disabled');
             }
             if (year === endYear) {
                 months.slice(endMonth + 1).addClass('disabled');
             }

             if (this.o.beforeShowMonth !== $.noop) {
                 var that = this;
                 $.each(months, function (i, month) {
                     if (!$(month).hasClass('disabled')) {
                         var moDate = new Date(year, i, 1);
                         var before = that.o.beforeShowMonth(moDate);
                         if (before === false)
                             $(month).addClass('disabled');
                     }
                 });
             }

             html = '';
             year = parseInt(year / 10, 10) * 10;
             var yearCont = this.picker.find('.datepicker-years')
                                 .find('th:eq(1)')
                                     .text((year - (this.o.language == "zh-TW" ? 1911 : 0)) + '-' + (year - (this.o.language == "zh-TW" ? 1911 : 0) + 9))
                                     .end()
                                 .find('td');
             year -= 1;
             var years = $.map(this.dates, function (d) {
                 return d.getUTCFullYear();
             }),
                 classes;
             for (var i = -1; i < 11; i++) {
                 classes = ['year'];
                 if (i === -1)
                     classes.push('old');
                 else if (i === 10)
                     classes.push('new');
                 if ($.inArray(year, years) !== -1)
                     classes.push('active');
                 if (year < startYear || year > endYear)
                     classes.push('disabled');
                 html += '' + (year - (this.o.language == "zh-TW" ? 1911 : 0)) + '';
                 year += 1;
             }
             yearCont.html(html);
         },


3. click字段加入西元年及民國年轉換
click: function (e) {
             e.preventDefault();
             var target = $(e.target).closest('span, td, th'),
                 year, month, day;
             if (target.length === 1) {
                 switch (target[0].nodeName.toLowerCase()) {
                     case 'th':
                         switch (target[0].className) {
                             case 'datepicker-switch':
                                 this.showMode(1);
                                 break;
                             case 'prev':
                             case 'next':
                                 var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);
                                 switch (this.viewMode) {
                                     case 0:
                                         this.viewDate = this.moveMonth(this.viewDate, dir);
                                         this._trigger('changeMonth', this.viewDate);
                                         break;
                                     case 1:
                                     case 2:
                                         this.viewDate = this.moveYear(this.viewDate, dir);
                                         if (this.viewMode === 1)
                                             this._trigger('changeYear', this.viewDate);
                                         break;
                                 }
                                 this.fill();
                                 break;
                             case 'today':
                                 var date = new Date();
                                 date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);

                                 this.showMode(-2);
                                 var which = this.o.todayBtn === 'linked' ? null : 'view';
                                 this._setDate(date, which);
                                 break;
                             case 'clear':
                                 this.clearDates();
                                 break;
                         }
                         break;
                     case 'span':
                         if (!target.hasClass('disabled')) {
                             this.viewDate.setUTCDate(1);
                             if (target.hasClass('month')) {
                                 day = 1;
                                 month = target.parent().find('span').index(target);
                                 year = this.viewDate.getUTCFullYear();
                                 this.viewDate.setUTCMonth(month);
                                 this._trigger('changeMonth', this.viewDate);
                                 if (this.o.minViewMode === 1) {
                                     this._setDate(UTCDate(year, month, day));
                                 }
                             }
                             else {
                                 day = 1;
                                 month = 0;
                                 year = (parseInt(target.text(), 10) + (this.o.language == "zh-TW" ? 1911 : 0)) || 0;
                                 this.viewDate.setUTCFullYear(year);
                                 this._trigger('changeYear', this.viewDate);
                                 if (this.o.minViewMode === 2) {
                                     this._setDate(UTCDate(year, month, day));
                                 }
                             }
                             this.showMode(-1);
                             this.fill();
                         }
                         break;
                     case 'td':
                         if (target.hasClass('day') && !target.hasClass('disabled')) {
                             day = parseInt(target.text(), 10) || 1;
                             year = this.viewDate.getUTCFullYear();
                             month = this.viewDate.getUTCMonth();
                             if (target.hasClass('old')) {
                                 if (month === 0) {
                                     month = 11;
                                     year -= 1;
                                 }
                                 else {
                                     month -= 1;
                                 }
                             }
                             else if (target.hasClass('new')) {
                                 if (month === 11) {
                                     month = 0;
                                     year += 1;
                                 }
                                 else {
                                     month += 1;
                                 }
                             }
                             this._setDate(UTCDate(year, month, day));
                         }
                         break;
                 }
             }
             if (this.picker.is(':visible') && this._focused_from) {
                 $(this._focused_from).focus();
             }
             delete this._focused_from;
         },


4. validParts中年份檢查pattern修正
validParts: /dd?|DD?|mm?|MM?|y{2,4}/g,


5. parseDate中加入西元年及民國年轉換
parseDate: function (date, format, language) {
             if (!date)
                 return undefined;
             if (date instanceof Date)
                 return date;
             if (typeof format === 'string')
                 format = DPGlobal.parseFormat(format);
             var part_re = /([\-+]\d+)([dmwy])/,
                 parts = date.match(/([\-+]\d+)([dmwy])/g),
                 part, dir, i;
             if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)) {
                 date = new Date();
                 for (i = 0; i < parts.length; i++) {
                     part = part_re.exec(parts[i]);
                     dir = parseInt(part[1]);
                     switch (part[2]) {
                         case 'd':
                             date.setUTCDate(date.getUTCDate() + dir);
                             break;
                         case 'm':
                             date = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir);
                             break;
                         case 'w':
                             date.setUTCDate(date.getUTCDate() + dir * 7);
                             break;
                         case 'y':
                             date = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir);
                             break;
                     }
                 }
                 return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
             }
             parts = date && date.match(this.nonpunctuation) || [];
             date = new Date();
             var parsed = {},
                 setters_order = ['yyyy', 'yyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
                 setters_map = {
                     yyyy: function (d, v) {
                         return d.setUTCFullYear(v);
                     },
                     yyy: function (d, v) {
                         return d.setUTCFullYear(v + 1911);
                     },
                     yy: function (d, v) {
                         return d.setUTCFullYear(2000 + v);
                     },
                     m: function (d, v) {
                         if (isNaN(d))
                             return d;
                         v -= 1;
                         while (v < 0) v += 12;
                         v %= 12;
                         d.setUTCMonth(v);
                         while (d.getUTCMonth() !== v)
                             d.setUTCDate(d.getUTCDate() - 1);
                         return d;
                     },
                     d: function (d, v) {
                         return d.setUTCDate(v);
                     }
                 },
                 val, filtered;
             setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
             setters_map['dd'] = setters_map['d'];
             date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
             var fparts = format.parts.slice();
             // Remove noop parts
             if (parts.length !== fparts.length) {
                 fparts = $(fparts).filter(function (i, p) {
                     return $.inArray(p, setters_order) !== -1;
                 }).toArray();
             }
             // Process remainder
             function match_part() {
                 var m = this.slice(0, parts[i].length),
                     p = parts[i].slice(0, m.length);
                 return m.toLowerCase() === p.toLowerCase();
             }
             if (parts.length === fparts.length) {
                 var cnt;
                 for (i = 0, cnt = fparts.length; i < cnt; i++) {
                     val = parseInt(parts[i], 10);
                     part = fparts[i];
                     if (isNaN(val)) {
                         switch (part) {
                             case 'MM':
                                 filtered = $(dates[language].months).filter(match_part);
                                 val = $.inArray(filtered[0], dates[language].months) + 1;
                                 break;
                             case 'M':
                                 filtered = $(dates[language].monthsShort).filter(match_part);
                                 val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
                                 break;
                         }
                     }
                     parsed[part] = val;
                 }
                 var _date, s;
                 for (i = 0; i < setters_order.length; i++) {
                     s = setters_order[i];
                     if (s in parsed && !isNaN(parsed[s])) {
                         _date = new Date(date);
                         setters_map[s](_date, parsed[s]);
                         if (!isNaN(_date))
                             date = _date;
                     }
                 }
             }
             return date;
         },


6. formatDate字段加入西元年及民國年轉換
formatDate: function (date, format, language) {
             if (!date)
                 return '';
             if (typeof format === 'string')
                 format = DPGlobal.parseFormat(format);
             var val = {
                 d: date.getUTCDate(),
                 D: dates[language].daysShort[date.getUTCDay()],
                 DD: dates[language].days[date.getUTCDay()],
                 m: date.getUTCMonth() + 1,
                 M: dates[language].monthsShort[date.getUTCMonth()],
                 MM: dates[language].months[date.getUTCMonth()],
                 yy: date.getUTCFullYear().toString().substring(2),
                 yyy: pad(date.getUTCFullYear() - 1911, 3),
                 yyyy: date.getUTCFullYear()
             };
             val.dd = (val.d < 10 ? '0' : '') + val.d;
             val.mm = (val.m < 10 ? '0' : '') + val.m;
             date = [];
             var seps = $.extend([], format.separators);
             for (var i = 0, cnt = format.parts.length; i <= cnt; i++) {
                 if (seps.length)
                     date.push(seps.shift());
                 date.push(val[format.parts[i]]);
             }
             return date.join('');
         },