Mercurial > hg > index.fcgi > www > www-1
comparison bootstrap-year-calendar/bootstrap-year-calendar.js @ 103:4043aaa41075
add bootstrap-year-calendar
author | paulo |
---|---|
date | Thu, 07 Mar 2019 00:52:02 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:742015a86bba |
---|---|
1 /* ========================================================= | |
2 * Bootstrap year calendar v1.1.0 | |
3 * Repo: https://github.com/Paul-DS/bootstrap-year-calendar | |
4 * ========================================================= | |
5 * Created by Paul David-Sivelle | |
6 * | |
7 * Licensed under the Apache License, Version 2.0 (the "License"); | |
8 * you may not use this file except in compliance with the License. | |
9 * You may obtain a copy of the License at | |
10 * | |
11 * http://www.apache.org/licenses/LICENSE-2.0 | |
12 * | |
13 * Unless required by applicable law or agreed to in writing, software | |
14 * distributed under the License is distributed on an "AS IS" BASIS, | |
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
16 * See the License for the specific language governing permissions and | |
17 * limitations under the License. | |
18 * ========================================================= */ | |
19 | |
20 (function($) { | |
21 var Calendar = function(element, options) { | |
22 this.element = element; | |
23 this.element.addClass('calendar'); | |
24 | |
25 this._initializeEvents(options); | |
26 this._initializeOptions(options); | |
27 this._render(); | |
28 }; | |
29 | |
30 Calendar.prototype = { | |
31 constructor: Calendar, | |
32 _initializeOptions: function(opt) { | |
33 if(opt == null) { | |
34 opt = []; | |
35 } | |
36 | |
37 this.options = { | |
38 startYear: !isNaN(parseInt(opt.startYear)) ? parseInt(opt.startYear) : new Date().getFullYear(), | |
39 minDate: opt.minDate instanceof Date ? opt.minDate : null, | |
40 maxDate: opt.maxDate instanceof Date ? opt.maxDate : null, | |
41 language: (opt.language != null && dates[opt.language] != null) ? opt.language : 'en', | |
42 allowOverlap: opt.allowOverlap != null ? opt.allowOverlap : true, | |
43 displayWeekNumber: opt.displayWeekNumber != null ? opt.displayWeekNumber : false, | |
44 alwaysHalfDay: opt.alwaysHalfDay != null ? opt.alwaysHalfDay : false, | |
45 enableRangeSelection: opt.enableRangeSelection != null ? opt.enableRangeSelection : false, | |
46 disabledDays: opt.disabledDays instanceof Array ? opt.disabledDays : [], | |
47 roundRangeLimits: opt.roundRangeLimits != null ? opt.roundRangeLimits : false, | |
48 dataSource: opt.dataSource instanceof Array != null ? opt.dataSource : [], | |
49 style: opt.style == 'background' || opt.style == 'border' || opt.style == 'custom' ? opt.style : 'border', | |
50 enableContextMenu: opt.enableContextMenu != null ? opt.enableContextMenu : false, | |
51 contextMenuItems: opt.contextMenuItems instanceof Array ? opt.contextMenuItems : [], | |
52 customDayRenderer : $.isFunction(opt.customDayRenderer) ? opt.customDayRenderer : null, | |
53 customDataSourceRenderer : $.isFunction(opt.customDataSourceRenderer) ? opt.customDataSourceRenderer : null | |
54 }; | |
55 | |
56 this._initializeDatasourceColors(); | |
57 }, | |
58 _initializeEvents: function(opt) { | |
59 if(opt == null) { | |
60 opt = []; | |
61 } | |
62 | |
63 if(opt.renderEnd) { this.element.bind('renderEnd', opt.renderEnd); } | |
64 if(opt.clickDay) { this.element.bind('clickDay', opt.clickDay); } | |
65 if(opt.dayContextMenu) { this.element.bind('dayContextMenu', opt.dayContextMenu); } | |
66 if(opt.selectRange) { this.element.bind('selectRange', opt.selectRange); } | |
67 if(opt.mouseOnDay) { this.element.bind('mouseOnDay', opt.mouseOnDay); } | |
68 if(opt.mouseOutDay) { this.element.bind('mouseOutDay', opt.mouseOutDay); } | |
69 }, | |
70 _initializeDatasourceColors: function() { | |
71 for(var i in this.options.dataSource) { | |
72 if(this.options.dataSource[i].color == null) { | |
73 this.options.dataSource[i].color = colors[i % colors.length]; | |
74 } | |
75 } | |
76 }, | |
77 _render: function() { | |
78 this.element.empty(); | |
79 | |
80 this._renderHeader(); | |
81 this._renderBody(); | |
82 this._renderDataSource(); | |
83 | |
84 this._applyEvents(); | |
85 this.element.find('.months-container').fadeIn(500); | |
86 | |
87 this._triggerEvent('renderEnd', { currentYear: this.options.startYear }); | |
88 }, | |
89 _renderHeader: function() { | |
90 var header = $(document.createElement('div')); | |
91 header.addClass('calendar-header panel panel-default'); | |
92 | |
93 var headerTable = $(document.createElement('table')); | |
94 | |
95 var prevDiv = $(document.createElement('th')); | |
96 prevDiv.addClass('prev'); | |
97 | |
98 if(this.options.minDate != null && this.options.minDate > new Date(this.options.startYear - 1, 11, 31)) { | |
99 prevDiv.addClass('disabled'); | |
100 } | |
101 | |
102 var prevIcon = $(document.createElement('span')); | |
103 prevIcon.addClass('glyphicon glyphicon-chevron-left'); | |
104 | |
105 prevDiv.append(prevIcon); | |
106 | |
107 headerTable.append(prevDiv); | |
108 | |
109 var prev2YearDiv = $(document.createElement('th')); | |
110 prev2YearDiv.addClass('year-title year-neighbor2 hidden-sm hidden-xs'); | |
111 prev2YearDiv.text(this.options.startYear - 2); | |
112 | |
113 if(this.options.minDate != null && this.options.minDate > new Date(this.options.startYear - 2, 11, 31)) { | |
114 prev2YearDiv.addClass('disabled'); | |
115 } | |
116 | |
117 headerTable.append(prev2YearDiv); | |
118 | |
119 var prevYearDiv = $(document.createElement('th')); | |
120 prevYearDiv.addClass('year-title year-neighbor hidden-xs'); | |
121 prevYearDiv.text(this.options.startYear - 1); | |
122 | |
123 if(this.options.minDate != null && this.options.minDate > new Date(this.options.startYear - 1, 11, 31)) { | |
124 prevYearDiv.addClass('disabled'); | |
125 } | |
126 | |
127 headerTable.append(prevYearDiv); | |
128 | |
129 var yearDiv = $(document.createElement('th')); | |
130 yearDiv.addClass('year-title'); | |
131 yearDiv.text(this.options.startYear); | |
132 | |
133 headerTable.append(yearDiv); | |
134 | |
135 var nextYearDiv = $(document.createElement('th')); | |
136 nextYearDiv.addClass('year-title year-neighbor hidden-xs'); | |
137 nextYearDiv.text(this.options.startYear + 1); | |
138 | |
139 if(this.options.maxDate != null && this.options.maxDate < new Date(this.options.startYear + 1, 0, 1)) { | |
140 nextYearDiv.addClass('disabled'); | |
141 } | |
142 | |
143 headerTable.append(nextYearDiv); | |
144 | |
145 var next2YearDiv = $(document.createElement('th')); | |
146 next2YearDiv.addClass('year-title year-neighbor2 hidden-sm hidden-xs'); | |
147 next2YearDiv.text(this.options.startYear + 2); | |
148 | |
149 if(this.options.maxDate != null && this.options.maxDate < new Date(this.options.startYear + 2, 0, 1)) { | |
150 next2YearDiv.addClass('disabled'); | |
151 } | |
152 | |
153 headerTable.append(next2YearDiv); | |
154 | |
155 var nextDiv = $(document.createElement('th')); | |
156 nextDiv.addClass('next'); | |
157 | |
158 if(this.options.maxDate != null && this.options.maxDate < new Date(this.options.startYear + 1, 0, 1)) { | |
159 nextDiv.addClass('disabled'); | |
160 } | |
161 | |
162 var nextIcon = $(document.createElement('span')); | |
163 nextIcon.addClass('glyphicon glyphicon-chevron-right'); | |
164 | |
165 nextDiv.append(nextIcon); | |
166 | |
167 headerTable.append(nextDiv); | |
168 | |
169 header.append(headerTable); | |
170 | |
171 this.element.append(header); | |
172 }, | |
173 _renderBody: function() { | |
174 var monthsDiv = $(document.createElement('div')); | |
175 monthsDiv.addClass('months-container'); | |
176 | |
177 for(var m = 0; m < 12; m++) { | |
178 /* Container */ | |
179 var monthDiv = $(document.createElement('div')); | |
180 monthDiv.addClass('month-container'); | |
181 monthDiv.data('month-id', m); | |
182 | |
183 var firstDate = new Date(this.options.startYear, m, 1); | |
184 | |
185 var table = $(document.createElement('table')); | |
186 table.addClass('month'); | |
187 | |
188 /* Month header */ | |
189 var thead = $(document.createElement('thead')); | |
190 | |
191 var titleRow = $(document.createElement('tr')); | |
192 | |
193 var titleCell = $(document.createElement('th')); | |
194 titleCell.addClass('month-title'); | |
195 titleCell.attr('colspan', this.options.displayWeekNumber ? 8 : 7); | |
196 titleCell.text(dates[this.options.language].months[m]); | |
197 | |
198 titleRow.append(titleCell); | |
199 thead.append(titleRow); | |
200 | |
201 var headerRow = $(document.createElement('tr')); | |
202 | |
203 if(this.options.displayWeekNumber) { | |
204 var weekNumberCell = $(document.createElement('th')); | |
205 weekNumberCell.addClass('week-number'); | |
206 weekNumberCell.text(dates[this.options.language].weekShort); | |
207 headerRow.append(weekNumberCell); | |
208 } | |
209 | |
210 var d = dates[this.options.language].weekStart; | |
211 do | |
212 { | |
213 var headerCell = $(document.createElement('th')); | |
214 headerCell.addClass('day-header'); | |
215 headerCell.text(dates[this.options.language].daysMin[d]); | |
216 | |
217 headerRow.append(headerCell); | |
218 | |
219 d++; | |
220 if(d >= 7) | |
221 d = 0; | |
222 } | |
223 while(d != dates[this.options.language].weekStart) | |
224 | |
225 thead.append(headerRow); | |
226 table.append(thead); | |
227 | |
228 /* Days */ | |
229 var currentDate = new Date(firstDate.getTime()); | |
230 var lastDate = new Date(this.options.startYear, m + 1, 0); | |
231 | |
232 var weekStart = dates[this.options.language].weekStart | |
233 | |
234 while(currentDate.getDay() != weekStart) | |
235 { | |
236 currentDate.setDate(currentDate.getDate() - 1); | |
237 } | |
238 | |
239 while(currentDate <= lastDate) | |
240 { | |
241 var row = $(document.createElement('tr')); | |
242 | |
243 if(this.options.displayWeekNumber) { | |
244 var weekNumberCell = $(document.createElement('td')); | |
245 weekNumberCell.addClass('week-number'); | |
246 weekNumberCell.text(this.getWeekNumber(currentDate)); | |
247 row.append(weekNumberCell); | |
248 } | |
249 | |
250 do | |
251 { | |
252 var cell = $(document.createElement('td')); | |
253 cell.addClass('day'); | |
254 | |
255 if(currentDate < firstDate) { | |
256 cell.addClass('old'); | |
257 } | |
258 else if(currentDate > lastDate) { | |
259 cell.addClass('new'); | |
260 } | |
261 else { | |
262 if((this.options.minDate != null && currentDate < this.options.minDate) || (this.options.maxDate != null && currentDate > this.options.maxDate)) | |
263 { | |
264 cell.addClass('disabled'); | |
265 } | |
266 else if(this.options.disabledDays.length > 0) { | |
267 for(var d in this.options.disabledDays){ | |
268 if(currentDate.getTime() == this.options.disabledDays[d].getTime()) { | |
269 cell.addClass('disabled'); | |
270 break; | |
271 } | |
272 } | |
273 } | |
274 | |
275 var cellContent = $(document.createElement('div')); | |
276 cellContent.addClass('day-content'); | |
277 cellContent.text(currentDate.getDate()); | |
278 cell.append(cellContent); | |
279 | |
280 if(this.options.customDayRenderer) { | |
281 this.options.customDayRenderer(cellContent, currentDate); | |
282 } | |
283 } | |
284 | |
285 row.append(cell); | |
286 | |
287 currentDate.setDate(currentDate.getDate() + 1); | |
288 } | |
289 while(currentDate.getDay() != weekStart) | |
290 | |
291 table.append(row); | |
292 } | |
293 | |
294 monthDiv.append(table); | |
295 | |
296 monthsDiv.append(monthDiv); | |
297 } | |
298 | |
299 this.element.append(monthsDiv); | |
300 }, | |
301 _renderDataSource: function() { | |
302 var _this = this; | |
303 if(this.options.dataSource != null && this.options.dataSource.length > 0) { | |
304 this.element.find('.month-container').each(function() { | |
305 var month = $(this).data('month-id'); | |
306 | |
307 var firstDate = new Date(_this.options.startYear, month, 1); | |
308 var lastDate = new Date(_this.options.startYear, month + 1, 0); | |
309 | |
310 if((_this.options.minDate == null || lastDate >= _this.options.minDate) && (_this.options.maxDate == null || firstDate <= _this.options.maxDate)) | |
311 { | |
312 var monthData = []; | |
313 | |
314 for(var i in _this.options.dataSource) { | |
315 if(!(_this.options.dataSource[i].startDate > lastDate) || (_this.options.dataSource[i].endDate < firstDate)) { | |
316 monthData.push(_this.options.dataSource[i]); | |
317 } | |
318 } | |
319 | |
320 if(monthData.length > 0) { | |
321 $(this).find('.day-content').each(function() { | |
322 var currentDate = new Date(_this.options.startYear, month, $(this).text()); | |
323 | |
324 var dayData = []; | |
325 | |
326 if((_this.options.minDate == null || currentDate >= _this.options.minDate) && (_this.options.maxDate == null || currentDate <= _this.options.maxDate)) | |
327 { | |
328 for(var i in monthData) { | |
329 if(monthData[i].startDate <= currentDate && monthData[i].endDate >= currentDate) { | |
330 dayData.push(monthData[i]); | |
331 } | |
332 } | |
333 | |
334 if(dayData.length > 0) | |
335 { | |
336 _this._renderDataSourceDay($(this), currentDate, dayData); | |
337 } | |
338 } | |
339 }); | |
340 } | |
341 } | |
342 }); | |
343 } | |
344 }, | |
345 _renderDataSourceDay: function(elt, currentDate, events) { | |
346 switch(this.options.style) | |
347 { | |
348 case 'border': | |
349 var weight = 0; | |
350 | |
351 if(events.length == 1) { | |
352 weight = 4; | |
353 } | |
354 else if(events.length <= 3) { | |
355 weight = 2; | |
356 } | |
357 else { | |
358 elt.parent().css('box-shadow', 'inset 0 -4px 0 0 black'); | |
359 } | |
360 | |
361 if(weight > 0) | |
362 { | |
363 var boxShadow = ''; | |
364 | |
365 for(var i in events) | |
366 { | |
367 if(boxShadow != '') { | |
368 boxShadow += ","; | |
369 } | |
370 | |
371 boxShadow += 'inset 0 -' + (parseInt(i) + 1) * weight + 'px 0 0 ' + events[i].color; | |
372 } | |
373 | |
374 elt.parent().css('box-shadow', boxShadow); | |
375 } | |
376 break; | |
377 | |
378 case 'background': | |
379 elt.parent().css('background-color', events[events.length - 1].color); | |
380 | |
381 var currentTime = currentDate.getTime(); | |
382 | |
383 if(events[events.length - 1].startDate.getTime() == currentTime) | |
384 { | |
385 elt.parent().addClass('day-start'); | |
386 | |
387 if(events[events.length - 1].startHalfDay || this.options.alwaysHalfDay) { | |
388 elt.parent().addClass('day-half'); | |
389 | |
390 // Find color for other half | |
391 var otherColor = 'transparent'; | |
392 for(var i = events.length - 2; i >= 0; i--) { | |
393 if(events[i].startDate.getTime() != currentTime || (!events[i].startHalfDay && !this.options.alwaysHalfDay)) { | |
394 otherColor = events[i].color; | |
395 break; | |
396 } | |
397 } | |
398 | |
399 elt.parent().css('background', 'linear-gradient(-45deg, ' + events[events.length - 1].color + ', ' + events[events.length - 1].color + ' 49%, ' + otherColor + ' 51%, ' + otherColor + ')'); | |
400 } | |
401 else if(this.options.roundRangeLimits) { | |
402 elt.parent().addClass('round-left'); | |
403 } | |
404 } | |
405 else if(events[events.length - 1].endDate.getTime() == currentTime) | |
406 { | |
407 elt.parent().addClass('day-end'); | |
408 | |
409 if(events[events.length - 1].endHalfDay || this.options.alwaysHalfDay) { | |
410 elt.parent().addClass('day-half'); | |
411 | |
412 // Find color for other half | |
413 var otherColor = 'transparent'; | |
414 for(var i = events.length - 2; i >= 0; i--) { | |
415 if(events[i].endDate.getTime() != currentTime || (!events[i].endHalfDay && !this.options.alwaysHalfDay)) { | |
416 otherColor = events[i].color; | |
417 break; | |
418 } | |
419 } | |
420 | |
421 elt.parent().css('background', 'linear-gradient(135deg, ' + events[events.length - 1].color + ', ' + events[events.length - 1].color + ' 49%, ' + otherColor + ' 51%, ' + otherColor + ')'); | |
422 } | |
423 else if(this.options.roundRangeLimits) { | |
424 elt.parent().addClass('round-right'); | |
425 } | |
426 } | |
427 break; | |
428 | |
429 case 'custom': | |
430 if(this.options.customDataSourceRenderer) { | |
431 this.options.customDataSourceRenderer.call(this, elt, currentDate, events); | |
432 } | |
433 break; | |
434 } | |
435 }, | |
436 _applyEvents: function () { | |
437 var _this = this; | |
438 | |
439 /* Header buttons */ | |
440 this.element.find('.year-neighbor, .year-neighbor2').click(function() { | |
441 if(!$(this).hasClass('disabled')) { | |
442 _this.setYear(parseInt($(this).text())); | |
443 } | |
444 }); | |
445 | |
446 this.element.find('.calendar-header .prev').click(function() { | |
447 if(!$(this).hasClass('disabled')) { | |
448 _this.element.find('.months-container').animate({'margin-left':'100%'},100, function() { | |
449 _this.element.find('.months-container').hide(); | |
450 _this.element.find('.months-container').css('margin-left', '0'); | |
451 setTimeout(function() { _this.setYear(_this.options.startYear - 1) }, 50); | |
452 }); | |
453 } | |
454 }); | |
455 | |
456 this.element.find('.calendar-header .next').click(function() { | |
457 if(!$(this).hasClass('disabled')) { | |
458 _this.element.find('.months-container').animate({'margin-left':'-100%'},100, function() { | |
459 _this.element.find('.months-container').hide(); | |
460 _this.element.find('.months-container').css('margin-left', '0'); | |
461 setTimeout(function() { _this.setYear(_this.options.startYear + 1) }, 50); | |
462 }); | |
463 } | |
464 }); | |
465 | |
466 var cells = this.element.find('.day:not(.old, .new, .disabled)'); | |
467 | |
468 /* Click on date */ | |
469 cells.click(function(e) { | |
470 e.stopPropagation(); | |
471 var date = _this._getDate($(this)); | |
472 _this._triggerEvent('clickDay', { | |
473 element: $(this), | |
474 which: e.which, | |
475 date: date, | |
476 events: _this.getEvents(date) | |
477 }); | |
478 }); | |
479 | |
480 /* Click right on date */ | |
481 | |
482 cells.bind('contextmenu', function(e) { | |
483 if(_this.options.enableContextMenu) | |
484 { | |
485 e.preventDefault(); | |
486 if(_this.options.contextMenuItems.length > 0) | |
487 { | |
488 _this._openContextMenu($(this)); | |
489 } | |
490 } | |
491 | |
492 var date = _this._getDate($(this)); | |
493 _this._triggerEvent('dayContextMenu', { | |
494 element: $(this), | |
495 date: date, | |
496 events: _this.getEvents(date) | |
497 }); | |
498 }); | |
499 | |
500 /* Range selection */ | |
501 if(this.options.enableRangeSelection) { | |
502 cells.mousedown(function (e) { | |
503 if(e.which == 1) { | |
504 var currentDate = _this._getDate($(this)); | |
505 | |
506 if(_this.options.allowOverlap || _this.getEvents(currentDate).length == 0) | |
507 { | |
508 _this._mouseDown = true; | |
509 _this._rangeStart = _this._rangeEnd = currentDate; | |
510 _this._refreshRange(); | |
511 } | |
512 } | |
513 }); | |
514 | |
515 cells.mouseenter(function (e) { | |
516 if (_this._mouseDown) { | |
517 var currentDate = _this._getDate($(this)); | |
518 | |
519 if(!_this.options.allowOverlap) | |
520 { | |
521 var newDate = new Date(_this._rangeStart.getTime()); | |
522 | |
523 if(newDate < currentDate) { | |
524 var nextDate = new Date(newDate.getFullYear(), newDate.getMonth(), newDate.getDate() + 1); | |
525 while(newDate < currentDate) { | |
526 if(_this.getEvents(nextDate).length > 0) | |
527 { | |
528 break; | |
529 } | |
530 | |
531 newDate.setDate(newDate.getDate() + 1); | |
532 nextDate.setDate(nextDate.getDate() + 1); | |
533 } | |
534 } | |
535 else { | |
536 var nextDate = new Date(newDate.getFullYear(), newDate.getMonth(), newDate.getDate() - 1); | |
537 while(newDate > currentDate) { | |
538 if(_this.getEvents(nextDate).length > 0) | |
539 { | |
540 break; | |
541 } | |
542 | |
543 newDate.setDate(newDate.getDate() - 1); | |
544 nextDate.setDate(nextDate.getDate() - 1); | |
545 } | |
546 } | |
547 | |
548 currentDate = newDate; | |
549 } | |
550 | |
551 var oldValue = _this._rangeEnd; | |
552 _this._rangeEnd = currentDate; | |
553 | |
554 if (oldValue.getTime() != _this._rangeEnd.getTime()) { | |
555 _this._refreshRange(); | |
556 } | |
557 } | |
558 }); | |
559 | |
560 $(window).mouseup(function (e) { | |
561 if (_this._mouseDown) { | |
562 _this._mouseDown = false; | |
563 _this._refreshRange(); | |
564 | |
565 var minDate = _this._rangeStart < _this._rangeEnd ? _this._rangeStart : _this._rangeEnd; | |
566 var maxDate = _this._rangeEnd > _this._rangeStart ? _this._rangeEnd : _this._rangeStart; | |
567 | |
568 _this._triggerEvent('selectRange', { startDate: minDate, endDate: maxDate }); | |
569 } | |
570 }); | |
571 } | |
572 | |
573 /* Hover date */ | |
574 cells.mouseenter(function(e) { | |
575 if(!_this._mouseDown) | |
576 { | |
577 var date = _this._getDate($(this)); | |
578 _this._triggerEvent('mouseOnDay', { | |
579 element: $(this), | |
580 date: date, | |
581 events: _this.getEvents(date) | |
582 }); | |
583 } | |
584 }); | |
585 | |
586 cells.mouseleave(function(e) { | |
587 var date = _this._getDate($(this)); | |
588 _this._triggerEvent('mouseOutDay', { | |
589 element: $(this), | |
590 date: date, | |
591 events: _this.getEvents(date) | |
592 }); | |
593 }); | |
594 | |
595 /* Responsive management */ | |
596 | |
597 setInterval(function() { | |
598 var calendarSize = $(_this.element).width(); | |
599 var monthSize = $(_this.element).find('.month').first().width() + 10; | |
600 var monthContainerClass = 'month-container'; | |
601 | |
602 if(monthSize * 6 < calendarSize) { | |
603 monthContainerClass += ' col-xs-2'; | |
604 } | |
605 else if(monthSize * 4 < calendarSize) { | |
606 monthContainerClass += ' col-xs-3'; | |
607 } | |
608 else if(monthSize * 3 < calendarSize) { | |
609 monthContainerClass += ' col-xs-4'; | |
610 } | |
611 else if(monthSize * 2 < calendarSize) { | |
612 monthContainerClass += ' col-xs-6'; | |
613 } | |
614 else { | |
615 monthContainerClass += ' col-xs-12'; | |
616 } | |
617 | |
618 $(_this.element).find('.month-container').attr('class', monthContainerClass); | |
619 }, 300); | |
620 }, | |
621 _refreshRange: function () { | |
622 var _this = this; | |
623 | |
624 this.element.find('td.day.range').removeClass('range') | |
625 this.element.find('td.day.range-start').removeClass('range-start'); | |
626 this.element.find('td.day.range-end').removeClass('range-end'); | |
627 | |
628 if (this._mouseDown) { | |
629 var beforeRange = true; | |
630 var afterRange = false; | |
631 var minDate = _this._rangeStart < _this._rangeEnd ? _this._rangeStart : _this._rangeEnd; | |
632 var maxDate = _this._rangeEnd > _this._rangeStart ? _this._rangeEnd : _this._rangeStart; | |
633 | |
634 this.element.find('.month-container').each(function () { | |
635 var monthId = $(this).data('month-id'); | |
636 if (minDate.getMonth() <= monthId && maxDate.getMonth() >= monthId) { | |
637 $(this).find('td.day:not(.old, .new)').each(function () { | |
638 var date = _this._getDate($(this)); | |
639 if (date >= minDate && date <= maxDate) { | |
640 $(this).addClass('range'); | |
641 | |
642 if (date.getTime() == minDate.getTime()) { | |
643 $(this).addClass('range-start'); | |
644 } | |
645 | |
646 if (date.getTime() == maxDate.getTime()) { | |
647 $(this).addClass('range-end'); | |
648 } | |
649 } | |
650 }); | |
651 } | |
652 }); | |
653 } | |
654 }, | |
655 _openContextMenu: function(elt) { | |
656 var contextMenu = $('.calendar-context-menu'); | |
657 | |
658 if(contextMenu.length > 0) { | |
659 contextMenu.hide(); | |
660 contextMenu.empty(); | |
661 } | |
662 else { | |
663 contextMenu = $(document.createElement('div')); | |
664 contextMenu.addClass('calendar-context-menu'); | |
665 $('body').append(contextMenu); | |
666 } | |
667 | |
668 var date = this._getDate(elt); | |
669 var events = this.getEvents(date); | |
670 | |
671 for(var i in events) { | |
672 var eventItem = $(document.createElement('div')); | |
673 eventItem.addClass('item'); | |
674 eventItem.css('border-left', '4px solid ' + events[i].color); | |
675 | |
676 var eventItemContent = $(document.createElement('div')); | |
677 eventItemContent.addClass('content'); | |
678 eventItemContent.text(events[i].name); | |
679 | |
680 eventItem.append(eventItemContent); | |
681 | |
682 var icon = $(document.createElement('span')); | |
683 icon.addClass('glyphicon glyphicon-chevron-right'); | |
684 | |
685 eventItem.append(icon); | |
686 | |
687 this._renderContextMenuItems(eventItem, this.options.contextMenuItems, events[i]); | |
688 | |
689 contextMenu.append(eventItem); | |
690 } | |
691 | |
692 if(contextMenu.children().length > 0) | |
693 { | |
694 contextMenu.css('left', elt.offset().left + 25 + 'px'); | |
695 contextMenu.css('top', elt.offset().top + 25 + 'px'); | |
696 contextMenu.show(); | |
697 | |
698 $(window).one('mouseup', function() { | |
699 contextMenu.hide(); | |
700 }); | |
701 } | |
702 }, | |
703 _renderContextMenuItems: function(parent, items, evt) { | |
704 var subMenu = $(document.createElement('div')); | |
705 subMenu.addClass('submenu'); | |
706 | |
707 for(var i in items) { | |
708 if(!items[i].visible || items[i].visible(evt)) { | |
709 var menuItem = $(document.createElement('div')); | |
710 menuItem.addClass('item'); | |
711 | |
712 var menuItemContent = $(document.createElement('div')); | |
713 menuItemContent.addClass('content'); | |
714 menuItemContent.text(items[i].text); | |
715 | |
716 menuItem.append(menuItemContent); | |
717 | |
718 if(items[i].click) { | |
719 (function(index) { | |
720 menuItem.click(function() { | |
721 items[index].click(evt); | |
722 }); | |
723 })(i); | |
724 } | |
725 | |
726 var icon = $(document.createElement('span')); | |
727 icon.addClass('glyphicon glyphicon-chevron-right'); | |
728 | |
729 menuItem.append(icon); | |
730 | |
731 if(items[i].items && items[i].items.length > 0) { | |
732 this._renderContextMenuItems(menuItem, items[i].items, evt); | |
733 } | |
734 | |
735 subMenu.append(menuItem); | |
736 } | |
737 } | |
738 | |
739 if(subMenu.children().length > 0) | |
740 { | |
741 parent.append(subMenu); | |
742 } | |
743 }, | |
744 _getColor: function(colorString) { | |
745 var div = $('<div />'); | |
746 div.css('color', colorString); | |
747 | |
748 }, | |
749 _getDate: function(elt) { | |
750 var day = elt.children('.day-content').text(); | |
751 var month = elt.closest('.month-container').data('month-id'); | |
752 var year = this.options.startYear; | |
753 | |
754 return new Date(year, month, day); | |
755 }, | |
756 _triggerEvent: function(eventName, parameters) { | |
757 var event = $.Event(eventName); | |
758 | |
759 for(var i in parameters) { | |
760 event[i] = parameters[i]; | |
761 } | |
762 | |
763 this.element.trigger(event); | |
764 }, | |
765 getWeekNumber: function(date) { | |
766 var tempDate = new Date(date.getTime()); | |
767 tempDate.setHours(0, 0, 0, 0); | |
768 tempDate.setDate(tempDate.getDate() + 3 - (tempDate.getDay() + 6) % 7); | |
769 var week1 = new Date(tempDate.getFullYear(), 0, 4); | |
770 return 1 + Math.round(((tempDate.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7); | |
771 }, | |
772 getEvents: function(date) { | |
773 var events = []; | |
774 | |
775 if(this.options.dataSource && date) { | |
776 for(var i in this.options.dataSource) { | |
777 if(this.options.dataSource[i].startDate <= date && this.options.dataSource[i].endDate >= date) { | |
778 events.push(this.options.dataSource[i]); | |
779 } | |
780 } | |
781 } | |
782 | |
783 return events; | |
784 }, | |
785 getYear: function() { | |
786 return this.options.startYear; | |
787 }, | |
788 setYear: function(year) { | |
789 var parsedYear = parseInt(year); | |
790 if(!isNaN(parsedYear)) { | |
791 this.options.startYear = parsedYear; | |
792 this._render(); | |
793 } | |
794 }, | |
795 getMinDate: function() { | |
796 return this.options.minDate; | |
797 }, | |
798 setMinDate: function(date) { | |
799 if(date instanceof Date) { | |
800 this.options.minDate = date; | |
801 this._render(); | |
802 } | |
803 }, | |
804 getMaxDate: function() { | |
805 return this.options.maxDate; | |
806 }, | |
807 setMaxDate: function(date) { | |
808 if(date instanceof Date) { | |
809 this.options.maxDate = date; | |
810 this._render(); | |
811 } | |
812 }, | |
813 getStyle: function() { | |
814 return this.options.style; | |
815 }, | |
816 setStyle: function(style) { | |
817 this.options.style = style == 'background' || style == 'border' || style == 'custom' ? style : 'border'; | |
818 this._render(); | |
819 }, | |
820 getAllowOverlap: function() { | |
821 return this.options.allowOverlap; | |
822 }, | |
823 setAllowOverlap: function(allowOverlap) { | |
824 this.options.allowOverlap = allowOverlap; | |
825 }, | |
826 getDisplayWeekNumber: function() { | |
827 return this.options.displayWeekNumber; | |
828 }, | |
829 setDisplayWeekNumber: function(displayWeekNumber) { | |
830 this.options.displayWeekNumber = displayWeekNumber; | |
831 this._render(); | |
832 }, | |
833 getAlwaysHalfDay: function() { | |
834 return this.options.alwaysHalfDay; | |
835 }, | |
836 setAlwaysHalfDay: function(alwaysHalfDay) { | |
837 this.options.alwaysHalfDay = alwaysHalfDay; | |
838 this._render(); | |
839 }, | |
840 getEnableRangeSelection: function() { | |
841 return this.options.enableRangeSelection; | |
842 }, | |
843 setEnableRangeSelection: function(enableRangeSelection) { | |
844 this.options.enableRangeSelection = enableRangeSelection; | |
845 this._render(); | |
846 }, | |
847 getDisabledDays: function() { | |
848 return this.options.disabledDays; | |
849 }, | |
850 setDisabledDays: function(disabledDays) { | |
851 this.options.disabledDays = disabledDays instanceof Array ? disabledDays : []; | |
852 this._render(); | |
853 }, | |
854 getRoundRangeLimits: function() { | |
855 return this.options.roundRangeLimits; | |
856 }, | |
857 setRoundRangeLimits: function(roundRangeLimits) { | |
858 this.options.roundRangeLimits = roundRangeLimits; | |
859 this._render(); | |
860 }, | |
861 getEnableContextMenu: function() { | |
862 return this.options.enableContextMenu; | |
863 }, | |
864 setEnableContextMenu: function(enableContextMenu) { | |
865 this.options.enableContextMenu = enableContextMenu; | |
866 this._render(); | |
867 }, | |
868 getContextMenuItems: function() { | |
869 return this.options.contextMenuItems; | |
870 }, | |
871 setContextMenuItems: function(contextMenuItems) { | |
872 this.options.contextMenuItems = contextMenuItems instanceof Array ? contextMenuItems : []; | |
873 this._render(); | |
874 }, | |
875 getCustomDayRenderer: function() { | |
876 return this.options.customDayRenderer; | |
877 }, | |
878 setCustomDayRenderer: function(customDayRenderer) { | |
879 this.options.customDayRenderer = $.isFunction(customDayRenderer) ? customDayRenderer : null; | |
880 this._render(); | |
881 }, | |
882 getCustomDataSourceRenderer: function() { | |
883 return this.options.customDataSourceRenderer; | |
884 }, | |
885 setCustomDataSourceRenderer: function(customDataSourceRenderer) { | |
886 this.options.customDataSourceRenderer = $.isFunction(customDataSourceRenderer) ? customDataSourceRenderer : null; | |
887 this._render(); | |
888 }, | |
889 getLanguage: function() { | |
890 return this.options.language; | |
891 }, | |
892 setLanguage: function(language) { | |
893 if(language != null && dates[language] != null) { | |
894 this.options.language = language; | |
895 this._render(); | |
896 } | |
897 }, | |
898 getDataSource: function() { | |
899 return this.options.dataSource; | |
900 }, | |
901 setDataSource: function(dataSource) { | |
902 this.options.dataSource = dataSource instanceof Array ? dataSource : []; | |
903 this._initializeDatasourceColors(); | |
904 this._render(); | |
905 }, | |
906 addEvent: function(evt) { | |
907 this.options.dataSource.push(evt); | |
908 this._render(); | |
909 } | |
910 } | |
911 | |
912 $.fn.calendar = function (options) { | |
913 var calendar = new Calendar($(this) ,options); | |
914 $(this).data('calendar', calendar); | |
915 return calendar; | |
916 } | |
917 | |
918 /* Events binding management */ | |
919 $.fn.renderEnd = function(fct) { $(this).bind('renderEnd', fct); } | |
920 $.fn.clickDay = function(fct) { $(this).bind('clickDay', fct); } | |
921 $.fn.dayContextMenu = function(fct) { $(this).bind('dayContextMenu', fct); } | |
922 $.fn.selectRange = function(fct) { $(this).bind('selectRange', fct); } | |
923 $.fn.mouseOnDay = function(fct) { $(this).bind('mouseOnDay', fct); } | |
924 $.fn.mouseOutDay = function(fct) { $(this).bind('mouseOutDay', fct); } | |
925 | |
926 var dates = $.fn.calendar.dates = { | |
927 en: { | |
928 days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], | |
929 daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], | |
930 daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], | |
931 months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], | |
932 monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], | |
933 weekShort: 'W', | |
934 weekStart:0 | |
935 } | |
936 }; | |
937 | |
938 var colors = $.fn.calendar.colors = ['#2C8FC9', '#9CB703', '#F5BB00', '#FF4A32', '#B56CE2', '#45A597']; | |
939 | |
940 $(function(){ | |
941 $('[data-provide="calendar"]').each(function() { | |
942 $(this).calendar(); | |
943 }); | |
944 }); | |
945 }(window.jQuery)); |