1 2(function ($) { 3 /* "YYYY-MM[-DD]" => Date */ 4 function strToDate(str) { 5 try { 6 var array = str.split('-'); 7 var year = parseInt(array[0]); 8 var month = parseInt(array[1]); 9 var day = array.length > 2? parseInt(array[2]): 1 ; 10 if (year > 0 && month >= 0) { 11 return new Date(year, month - 1, day); 12 } else { 13 return null; 14 } 15 } catch (err) {}; // just throw any illegal format 16 }; 17 18 /* Date => "YYYY-MM-DD" */ 19 function dateToStr(d) { 20 /* fix month zero base */ 21 var year = d.getFullYear(); 22 var month = d.getMonth(); 23 return year + "-" + (month + 1) + "-" + d.getDate(); 24 }; 25 26 $.fn.calendar = function (options) { 27 var _this = this; 28 var opts = $.extend({}, $.fn.calendar.defaults, options); 29 var week = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; 30 var tHead = week.map(function (day) { 31 return "<th>" + day + "</th>"; 32 }).join(""); 33 34 _this.init = function () { 35 var tpl = '<table class="cal">' + 36 '<caption>' + 37 ' <span class="prev"><a href="javascript:void(0);">←</a></span>' + 38 ' <span class="next"><a href="javascript:void(0);">→</a></span>' + 39 ' <span class="month"><span>' + 40 "</caption>" + 41 "<thead><tr>" + 42 tHead + 43 "</tr></thead>" + 44 "<tbody>" + 45 "</tbody>" + "</table>"; 46 var html = $(tpl); 47 _this.append(html); 48 }; 49 50 function daysInMonth(d) { 51 var newDate = new Date(d); 52 newDate.setMonth(newDate.getMonth() + 1); 53 newDate.setDate(0); 54 return newDate.getDate(); 55 } 56 57 _this.update = function (date) { 58 var mDate = new Date(date); 59 mDate.setDate(1); /* start of the month */ 60 var day = mDate.getDay(); /* value 0~6: 0 -- Sunday, 6 -- Saturday */ 61 mDate.setDate(mDate.getDate() - day) /* now mDate is the start day of the table */ 62 63 function dateToTag(d) { 64 var tag = $('<td><a href="javascript:void(0);"></a></td>'); 65 var a = tag.find('a'); 66 a.text(d.getDate()); 67 a.data('date', dateToStr(d)); 68 if (date.getMonth() != d.getMonth()) { // the bounday month 69 tag.addClass('off'); 70 } else if (_this.data('date') == a.data('date')) { // the select day 71 tag.addClass('active'); 72 _this.data('date', dateToStr(d)); 73 } 74 return tag; 75 }; 76 77 var tBody = _this.find('tbody'); 78 tBody.empty(); /* clear previous first */ 79 var cols = Math.ceil((day + daysInMonth(date))/7); 80 for (var i = 0; i < cols; i++) { 81 var tr = $('<tr></tr>'); 82 for (var j = 0; j < 7; j++, mDate.setDate(mDate.getDate() + 1)) { 83 tr.append(dateToTag(mDate)); 84 } 85 tBody.append(tr); 86 } 87 88 /* set month head */ 89 var monthStr = dateToStr(date).replace(/-\d+$/, ''); 90 _this.find('.month').text(monthStr) 91 }; 92 93 _this.getCurrentDate = function () { 94 return _this.data('date'); 95 } 96 97 _this.init(); 98 /* in date picker mode, and input date is empty, 99 * should not update 'data-date' field (no selected). 100 */ 101 var initDate = opts.date? opts.date: new Date(); 102 if (opts.date || !opts.picker) { 103 _this.data('date', dateToStr(initDate)); 104 } 105 _this.update(initDate); 106 107 /* event binding */ 108 _this.delegate('tbody td', 'click', function () { 109 var $this = $(this); 110 _this.find('.active').removeClass('active'); 111 $this.addClass('active'); 112 _this.data('date', $this.find('a').data('date')); 113 /* if the 'off' tag become selected, switch to that month */ 114 if ($this.hasClass('off')) { 115 _this.update(strToDate(_this.data('date'))); 116 } 117 if (opts.picker) { /* in picker mode, when date selected, panel hide */ 118 _this.hide(); 119 } 120 }); 121 122 function updateTable(monthOffset) { 123 var date = strToDate(_this.find('.month').text()); 124 date.setMonth(date.getMonth() + monthOffset); 125 _this.update(date); 126 }; 127 128 _this.find('.next').click(function () { 129 updateTable(1); 130 131 }); 132 133 _this.find('.prev').click(function () { 134 updateTable(-1); 135 }); 136 137 return this; 138 }; 139 140 $.fn.calendar.defaults = { 141 date: new Date(), 142 startDate: '2015-07-01', 143 picker: false, 144 }; 145 146 $.fn.datePicker = function () { 147 var _this = this; 148 var picker = $('<div></div>') 149 .addClass('picker-container') 150 .hide() 151 .calendar({'date': strToDate(_this.val()),startDate: '2015-07-01' , 'picker': true}); 152 153 _this.after(picker); 154 155 /* event binding */ 156 // click outside area, make calendar disappear 157 $('body').click(function () { 158 picker.hide(); 159 }); 160 161 // click input should make calendar appear 162 _this.click(function () { 163 picker.show(); 164 return false; // stop sending event to docment 165 }); 166 167 // click on calender, update input 168 picker.click(function () { 169 _this.val(picker.getCurrentDate()); 170 171 return false;
172 }); 173 174 return this; 175 }; 176 177 $(window).load(function () { 178 $('.jquery-calendar').each(function () { 179 $(this).calendar(); 180 }); 181 $('.date-picker:text').each(function () { 182 $(this).datePicker() 183 .on('changeDate', function(ev){ 184 alert("Hi") 185 }); 186 }); 187 }); 188}($));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.