')
51 | .click(function (e) {
52 | e.stopPropagation();
53 | })
54 | // Use this to prevent accidental text selection.
55 | .mousedown(function (e) {
56 | e.preventDefault();
57 | })
58 | .addClass('weekpicker')
59 | .append($nav, $calendar)
60 | .insertAfter(this.$el);
61 |
62 | this.$el
63 | .focus(this.show)
64 | .click(this.show)
65 | .change($.proxy(function () {
66 | this.selectWeek();
67 | }, this));
68 |
69 | this.selectWeek();
70 | this.hide();
71 | },
72 |
73 | setParams:function () {
74 | var data;
75 |
76 | data = this.$el.attr('data-target');
77 | this.$target = data ? $(data) : this.$el;
78 |
79 | data = parseInt(this.$el.attr('data-months'));
80 | this.months = data ? data : this.months;
81 |
82 | data = parseInt(this.$el.attr('data-week_start'));
83 | this.week_start = data ? data : this.week_start;
84 | },
85 |
86 | selectWeek:function (week) {
87 | if (typeof(week) == "undefined") {
88 | week = this.$target.val();
89 | }
90 |
91 | this.$months.empty();
92 | this.renderView();
93 |
94 | $('.week', this.$months).click($.proxy(function (e) {
95 | this.update($(e.target).parent().attr("date"));
96 | }, this)).hover(function (e) {
97 | $('.highlighted', this.$months).removeClass('highlighted');
98 | $(this).addClass('highlighted');
99 | });
100 |
101 | $('.selected', this.$months).removeClass('selected');
102 | $('[date="' + week + '"]', this.$months).addClass('selected');
103 | },
104 |
105 | renderView:function () {
106 | var dates = [
107 | [this.rangeStart(this.start), this.mid, 999],
108 | [this.mid_next, this.end, 999]
109 | ],
110 | thisDay, prevMonth = -1, weekEnd, tmp,
111 | row, col, label, firstDay, box_class;
112 |
113 | for (var c = 0; c < (this.months <= 1 ? 1 : 2); c++) {
114 | var m = -1, w = 0;
115 |
116 | dates[c][2] = this.daysBetween(dates[c][0], dates[c][1]);
117 |
118 | $col = $('
').addClass('month-col');
119 | $monthDays = $('');
120 |
121 | //Render head
122 | $head = $("").addClass('head');
123 | $head.append($('| '));
124 | for (var i = 0; i < this.shortDayNames.length; i++) {
125 | tmp = $(' | ').addClass('dow');
126 | tmp.text(this.shortDayNames[(i + this.week_start) % 7]);
127 | $head.append(tmp);
128 | }
129 | $monthDays.append($head);
130 |
131 | //Render date cells with month label
132 | for (var d = 0; d <= dates[c][2]; d++) {
133 | thisDay = this.incrementDay(dates[c][0], d);
134 | box_class = 'box' + (thisDay.getMonth() % 2);
135 |
136 | //Creating and append week in to month
137 | if (this.week_start == thisDay.getDay()) {
138 | firstDay = thisDay;
139 | row = $(' | ').addClass('week');
140 |
141 | //Print month label
142 | if (thisDay.getMonth() != prevMonth) {
143 | label = $('| ');
144 |
145 | tmp = this.incrementDay(thisDay, 6);
146 | if (tmp.getMonth() == thisDay.getMonth()) {
147 | tmp = this.incrementDay(thisDay, 28);
148 | tmp = (tmp.getMonth() == thisDay.getMonth() ? 5 : 4);
149 | label.attr('rowspan', tmp);
150 | label.text(this.monthNames[thisDay.getMonth()] + '\n'
151 | + thisDay.getFullYear().toString().substring(2, 4));
152 | label.addClass('week-label ' + box_class.replace('box', 'span'));
153 | }
154 |
155 | row.append(label);
156 | }
157 |
158 | //Set week range
159 | weekEnd = this.incrementDay(thisDay, 6);
160 | row.attr('date', this.formatWeek(thisDay, weekEnd));
161 |
162 | if (prevMonth != thisDay.getMonth()) {
163 | m = m + 1;
164 | prevMonth = thisDay.getMonth();
165 | }
166 | }
167 |
168 | //Append Day in to Week
169 | col = $(' | ').attr('date', this.format(thisDay));
170 | col.text(thisDay.getDate());
171 | col.addClass(box_class);
172 | row.append(col);
173 |
174 | if (d % 7 == 0) {
175 | $monthDays.append(row);
176 | }
177 | }
178 |
179 | $col.append($monthDays);
180 |
181 | this.$months.append($col);
182 | }
183 | },
184 |
185 | proxy:function (meth) {
186 | this[meth] = $.proxy(this[meth], this);
187 | return this;
188 | },
189 |
190 | daysBetween:function (start, end) {
191 | var start = Date.UTC(start.getFullYear(), start.getMonth(), start.getDate());
192 | var end = Date.UTC(end.getFullYear(), end.getMonth(), end.getDate());
193 |
194 | return (end - start) / 86400000;
195 | },
196 |
197 | findClosest:function (dow, date, direction) {
198 | var difference = direction * (Math.abs(date.getDay() - dow - (direction * 7)) % 7);
199 | return new Date(date.getFullYear(), date.getMonth(), date.getDate() + difference);
200 | },
201 |
202 | rangeStart:function (date) {
203 | return this.findClosest(this.week_start,
204 | new Date(date.getFullYear(), date.getMonth()), -1);
205 | },
206 |
207 | rangeEnd:function (date) {
208 | return this.findClosest((this.week_start - 1) % 7,
209 | new Date(date.getFullYear(), date.getMonth() + 1, 0), 1);
210 | },
211 |
212 | update:function (s) {
213 | this.$target.val(s);
214 | this.$el.val(s).change();
215 | },
216 |
217 | show:function (e) {
218 | e && e.stopPropagation();
219 |
220 | clearWeekPickers(this);
221 |
222 | var offset = this.$el.offset();
223 |
224 | this.$picker.css({
225 | top:offset.top + this.$el.outerHeight() + 2,
226 | left:offset.left
227 | }).show();
228 |
229 | $('html').on('keydown', this.keyHandler);
230 | },
231 |
232 | hide:function () {
233 | this.$picker.hide();
234 | $('html').off('keydown', this.keyHandler);
235 | },
236 |
237 | keyHandler:function (e) {
238 | // Keyboard navigation shortcuts.
239 | switch (e.keyCode) {
240 | case 9:
241 | case 27:
242 | case 13:
243 | this.hide();
244 | break;
245 | default:
246 | return;
247 | }
248 | e.preventDefault();
249 | },
250 |
251 | parse:function (s) {
252 | // Parse a partial RFC 3339 string into a Date.
253 | var m;
254 | if ((m = s.match(/^(\d{2,2})\/(\d{2,2})\/(\d{2,2})$/))) {
255 | return new Date(m[0], m[1] - 1, m[2]);
256 | } else {
257 | return null;
258 | }
259 | },
260 |
261 | format:function (date) {
262 | // Format a Date into a string as specified by RFC 3339.
263 | var month = (date.getMonth() + 1).toString(),
264 | dom = date.getDate().toString();
265 | if (month.length === 1) {
266 | month = '0' + month;
267 | }
268 |
269 | if (dom.length === 1) {
270 | dom = '0' + dom;
271 | }
272 |
273 | return month + "/" + dom + '/' + date.getFullYear().toString().substr(2, 2);
274 | },
275 |
276 | formatWeek:function (from, to) {
277 | return this.format(from) + '-' + this.format(to);
278 | },
279 |
280 | nav:function (months) {
281 | var $subnav = $(' ' +
282 | '← Previous | ' +
283 | ' Next →' +
284 | ' ');
285 |
286 | $('.prev', $subnav).click($.proxy(function () {
287 | this.ahead(-months)
288 | }, this));
289 | $('.next', $subnav).click($.proxy(function () {
290 | this.ahead(months)
291 | }, this));
292 |
293 | return $subnav;
294 | },
295 |
296 | incrementDay:function (d, i) {
297 | return new Date(d.getFullYear(), d.getMonth(), d.getDate() + i, 12, 00);
298 | },
299 |
300 | ahead:function (months) {
301 | var date = new Date(this.start.getFullYear(), this.start.getMonth() + months, 1);
302 | this.calculateDates(date);
303 | this.selectWeek();
304 | },
305 |
306 | calculateDates:function (date) {
307 | this.start = date ? date : new Date();
308 | this.mid = this.rangeEnd(new Date(this.start.getFullYear(), this.start.getMonth() + Math.ceil(this.months / 2), 0));
309 | this.mid_next = new Date(this.mid.getFullYear(), this.mid.getMonth(), this.mid.getDate() + 1);
310 | this.end = this.rangeEnd(new Date(this.start.getFullYear(), this.start.getMonth() + this.months, 0));
311 | }
312 | };
313 |
314 | /* WEEK PICKER DEFINITION
315 | * ============================ */
316 | $(document).ready(function () {
317 | $.fn.weekpicker = function (options) {
318 | return this.each(function () {
319 | new WeekPicker(this, options);
320 | });
321 | };
322 |
323 | $(function () {
324 | $(selector).weekpicker();
325 | $('html').click(clearWeekPickers);
326 | });
327 |
328 | $.fn.weekpicker.WeekPicker = WeekPicker;
329 |
330 | $.fn.weekpicker.defaults = {
331 | monthNames:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
332 | shortDayNames:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
333 | week_start:0,
334 | months:6
335 | };
336 |
337 | });
338 | }());
339 |
--------------------------------------------------------------------------------
| |