zui.calendar.js 26.0 KB
Newer Older
C
Catouse 已提交
1
/*!
C
Catouse 已提交
2
 * ZUI: 日历 - v1.9.1 - 2020-05-11
C
Catouse 已提交
3
 * http://openzui.com
C
Catouse 已提交
4
 * GitHub: https://github.com/easysoft/zui.git 
C
Catouse 已提交
5
 * Copyright (c) 2020 cnezsoft.com; Licensed MIT
C
Catouse 已提交
6 7
 */

8 9
/* ========================================================================
 * ZUI: calendar.js
C
Catouse 已提交
10
 * http://openzui.com
11
 * ========================================================================
C
Catouse 已提交
12
 * Copyright 2014-2020 cnezsoft.com; Licensed MIT
13 14
 * ======================================================================== */

C
Catouse 已提交
15
(function($, window) {
C
Catouse 已提交
16
    'use strict';
C
Catouse 已提交
17
    var NAME = 'zui.calendar';
C
Catouse 已提交
18 19 20 21
    var NUMBER_TYPE_NAME = 'number';
    var STRING_TYPE_NAME = 'string';
    var UNDEFINED_TYPE_NAME = 'undefined';
    var presetColors = {
C
Catouse 已提交
22 23 24 25 26 27 28
        "primary": 1,
        "green": 2,
        "red": 3,
        "blue": 4,
        "yellow": 5,
        "brown": 6,
        "purple": 7
C
Catouse 已提交
29
    };
C
Catouse 已提交
30

C
Catouse 已提交
31
    var getNearbyLastWeekDay = function(date, lastWeek) {
C
Catouse 已提交
32 33 34
            lastWeek = lastWeek || 1;

            var d = date.clone();
C
Catouse 已提交
35
            while(d.getDay() != lastWeek) {
C
Catouse 已提交
36 37
                d.addDays(-1);
            }
C
Catouse 已提交
38
            d.clearTime();
C
Catouse 已提交
39 40 41
            return d;
        },

C
Catouse 已提交
42
        getFirstDayOfMonth = function(date) {
C
Catouse 已提交
43 44 45
            var d = date.clone();
            d.setDate(1);
            return d;
C
Catouse 已提交
46 47 48 49 50
        },

        calculateDays = function(start, end) {
            var s = start.clone().clearTime();
            var e = end.clone().clearTime();
C
Catouse 已提交
51
            return Math.round((e.getTime() - s.getTime()) / Date.ONEDAY_TICKS) + 1;
C
Catouse 已提交
52 53 54 55 56 57 58 59 60
        },

        everyDayTo = function(start, end, callback) {
            var a = start.clone();
            var i = 0;
            while(a <= end) {
                callback(a.clone(), i++);
                a.addDays(1);
            }
C
Catouse 已提交
61
        };
C
Catouse 已提交
62

C
Catouse 已提交
63
    var Calendar = function(element, options) {
C
Catouse 已提交
64
        this.name = NAME;
65
        this.$ = $(element);
C
Catouse 已提交
66
        this.id = this.$.attr('id') || (NAME + $.zui.uuid());
C
Catouse 已提交
67
        this.$.attr('id', this.id);
C
Catouse 已提交
68
        this.storeName = NAME + '.' + this.id;
C
Catouse 已提交
69

C
Catouse 已提交
70
        options = this.getOptions(options);
C
Catouse 已提交
71 72
        this.getLang();

C
Catouse 已提交
73
        this.resetData(options.data);
C
Catouse 已提交
74

C
Catouse 已提交
75
        this.storeData = $.zui.store.pageGet(this.storeName, {
76 77 78
            date: 'today',
            view: 'month'
        });
C
Catouse 已提交
79

C
Catouse 已提交
80 81
        this.date = options.startDate || 'today';
        this.view = options.startView || 'month';
C
Catouse 已提交
82

C
Catouse 已提交
83 84
        this.$.toggleClass('limit-event-title', options.limitEventTitle);

C
Catouse 已提交
85
        if(options.withHeader) {
C
Catouse 已提交
86
            var $header = this.$.children('.calender-header');
C
Catouse 已提交
87
            if(!$header.length) {
C
Catouse 已提交
88
                $header = $('<header class="calender-header"><div class="btn-toolbar"><div class="btn-group"><button type="button" class="btn btn-today">{today}</button></div><div class="btn-group"><button type="button" class="btn btn-prev"><i class="icon-chevron-left"></i></button><button type="button" class="btn btn-next"><i class="icon-chevron-right"></i></button></div><div class="btn-group"><span class="calendar-caption"></span></div></div></header>'.format(this.lang));
C
Catouse 已提交
89 90 91 92 93 94 95 96
                this.$.append($header);
            }
            this.$caption = $header.find('.calendar-caption');
            this.$todayBtn = $header.find('.btn-today');
            this.$header = $header;
        }

        var $views = this.$.children('.calendar-views');
C
Catouse 已提交
97
        if(!$views.length) {
C
Catouse 已提交
98 99 100 101 102 103 104 105 106 107 108
            $views = $('<div class="calendar-views"></div>');
            this.$.append($views);
        }
        this.$views = $views;

        this.display();

        this.bindEvents();
    };

    // default options
109
    Calendar.DEFAULTS = {
C
Catouse 已提交
110 111
        langs: {
            zh_cn: {
C
Catouse 已提交
112 113 114 115 116 117
                weekNames: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
                monthNames: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
                today: '今天',
                year: '{0}年',
                month: '{0}月',
                yearMonth: '{0}年{1}月'
C
Catouse 已提交
118
            },
C
Catouse 已提交
119
            zh_tw: {
C
Catouse 已提交
120 121 122 123 124 125 126
                weekNames: ['週一', '週二', '週三', '週四', '週五', '週六', '週日'],
                monthNames: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
                today: '今天',
                year: '{0}年',
                month: '{0}月',
                yearMonth: '{0}年{1}月'
            },
C
Catouse 已提交
127
            en: {
C
Catouse 已提交
128 129 130 131 132 133
                weekNames: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
                monthNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
                today: 'Today',
                year: '{0}',
                month: '{0}',
                yearMonth: '{2}, {0}'
C
Catouse 已提交
134 135
            }
        },
C
Catouse 已提交
136 137 138
        data: {
            calendars: {
                defaultCal: {
139 140
                    color: '#229F24'
                }
C
Catouse 已提交
141
            },
142
            events: []
C
Catouse 已提交
143 144 145 146 147 148
        },
        // startView: "month",  // default view when load complete
        // startDate: 'today',  // default date when load complete
        limitEventTitle: true,
        storage: true,
        withHeader: true,
C
Catouse 已提交
149
        dragThenDrop: true, // drag an event and drop at another day,
C
Catouse 已提交
150 151
        // hideEmptyWeekends: false // Auto hide empty weekends,
        // hideFirstDayNumber: false // Hide first day number in every month
C
Catouse 已提交
152 153
    };

C
Catouse 已提交
154 155 156 157 158 159 160 161 162 163 164 165 166 167
    Calendar.prototype.resetData = function(data) {
        var that = this;
        that.data = data = data || that.data;
        if (data.calendars) {
            this.calendars = {};
            that.addCalendars(data.calendars, true);
        }
        if (data.events) {
            this.events = [];
            that.addEvents(data.events, true);
        }
        that.sortEvents();
    };

C
Catouse 已提交
168
    // Sort events by start datetime
C
Catouse 已提交
169
    Calendar.prototype.sortEvents = function() {
C
Catouse 已提交
170 171
        var that = this;
        var events = that.events;
C
Catouse 已提交
172
        if(!$.isArray(events)) {
C
Catouse 已提交
173 174 175
            events = [];
        }

C
Catouse 已提交
176 177 178 179 180 181 182 183 184 185 186
        events.sort(that.options.eventSorter || function(a, b) {
            if (a.allDay) {
                return 1;
            } else if (b.allDay) {
                return -1;
            }
            var result = a.start > b.start ? 1 : (a.start < b.start ? (-1) : 0);
            if (result === 0) {
                result = a.id < b.id ? (-1) : 1;
            }
            return result;
C
Catouse 已提交
187
        });
C
Catouse 已提交
188

C
Catouse 已提交
189
        that.events = events;
C
Catouse 已提交
190
    };
C
Catouse 已提交
191

C
Catouse 已提交
192
    Calendar.prototype.bindEvents = function() {
C
Catouse 已提交
193
        var $e = this.$,
C
Catouse 已提交
194
            that = this;
C
Catouse 已提交
195

C
Catouse 已提交
196
        $e.on('click', '.btn-today', function() {
C
Catouse 已提交
197 198 199
            that.date = new Date();
            that.display();
            $e.callComEvent(that, 'clickTodayBtn');
C
Catouse 已提交
200
        }).on('click', '.btn-next', function() {
C
Catouse 已提交
201 202
            if(that.view === 'month') {
                that.date.addMonths(1);
C
Catouse 已提交
203
            }
C
Catouse 已提交
204 205
            that.display();
            $e.callComEvent(that, 'clickNextBtn');
C
Catouse 已提交
206
        }).on('click', '.btn-prev', function() {
C
Catouse 已提交
207 208
            if(that.view === 'month') {
                that.date.addMonths(-1);
C
Catouse 已提交
209
            }
C
Catouse 已提交
210 211
            that.display();
            $e.callComEvent(that, 'clickPrevBtn');
C
Catouse 已提交
212
        }).on('click', '.event', function(event) {
C
Catouse 已提交
213 214 215 216
            event.stopPropagation();
            if ($(event.target).closest('.event-btn').length) {
                return;
            }
C
Catouse 已提交
217
            $e.callComEvent(that, 'clickEvent', {
C
Catouse 已提交
218
                element: this,
219
                event: $(this).data('event'),
C
Catouse 已提交
220
                events: that.events
C
Catouse 已提交
221 222
            }, event);
        }).on('click', '.cell-day', function(e) {
C
Catouse 已提交
223
            $e.callComEvent(that, 'clickCell', {
C
Catouse 已提交
224
                element: this,
C
Catouse 已提交
225
                view: that.view,
C
Catouse 已提交
226
                date: new Date($(this).children('.day').attr('data-date')),
C
Catouse 已提交
227
                events: that.events
C
Catouse 已提交
228
            }, e);
C
Catouse 已提交
229 230 231
        });
    };

C
Catouse 已提交
232
    Calendar.prototype.addCalendars = function(calendars, silence) {
233
        var that = this;
C
Catouse 已提交
234 235
        if(!that.calendars) that.calendars = {};

C
Catouse 已提交
236
        if($.isPlainObject(calendars)) {
C
Catouse 已提交
237 238
            calendars = [calendars];
        }
C
Catouse 已提交
239
        $.each(calendars, function(index, cal) {
C
Catouse 已提交
240
            if(!silence && false === that.$.callComEvent(this, 'beforeAddCalendars', {
C
Catouse 已提交
241 242 243
                    newCalendar: cal,
                    data: that.data
                })) {
C
Catouse 已提交
244
                return;
C
Catouse 已提交
245 246
            }

C
Catouse 已提交
247 248 249 250 251 252 253 254
            if(!cal.color) cal.color = 'primary';
            if(!presetColors[cal.color.toLowerCase()]) {
                var c = new $.zui.Color(cal.color);
                cal.textColor = c.contrast().hexStr();
            } else {
                cal.presetColor = true;
            }
            that.calendars[cal.name] = cal;
255
        });
C
Catouse 已提交
256 257 258

        if(!silence) {
            that.display();
C
Catouse 已提交
259
            that.$.callComEvent(that, 'addCalendars', {
C
Catouse 已提交
260 261 262 263
                newCalendars: calendars,
                data: that.data
            });
        }
C
Catouse 已提交
264 265
    };

C
Catouse 已提交
266
    Calendar.prototype.addEvents = function(events, silence) {
267
        var that = this;
C
Catouse 已提交
268 269
        if(!that.events) that.events = [];

C
Catouse 已提交
270
        if($.isPlainObject(events)) {
C
Catouse 已提交
271 272
            events = [events];
        }
C
Catouse 已提交
273
        $.each(events, function(index, e) {
C
Catouse 已提交
274
            if(!silence && false === that.$.callComEvent(that, 'beforeAddEvent', {
C
Catouse 已提交
275 276 277
                    newEvent: e,
                    data: that.data
                })) {
C
Catouse 已提交
278 279 280 281 282
                return;
            }

            var startType = typeof e.start;
            var endType = typeof e.end;
C
Catouse 已提交
283
            if(startType === NUMBER_TYPE_NAME || startType === STRING_TYPE_NAME) {
C
Catouse 已提交
284 285
                e.start = new Date(e.start);
            }
C
Catouse 已提交
286
            if(endType === NUMBER_TYPE_NAME || endType === STRING_TYPE_NAME) {
C
Catouse 已提交
287 288
                e.end = new Date(e.end);
            }
C
Catouse 已提交
289
            if(typeof e.id === UNDEFINED_TYPE_NAME) {
C
Catouse 已提交
290
                e.id = $.zui.uuid();
C
Catouse 已提交
291 292
            }

C
Catouse 已提交
293 294
            if(e.allDay) {
                e.start.clearTime();
C
Catouse 已提交
295 296 297
                if (!e.end) {
                    e.end = e.start.clone();
                }
C
Catouse 已提交
298 299 300 301 302 303
                e.end.clearTime().addDays(1).addMilliseconds(-1);
            }

            e.days = calculateDays(e.start, e.end);

            that.events.push(e);
304
        });
C
Catouse 已提交
305 306 307 308

        if(!silence) {
            that.sortEvents();
            that.display();
C
Catouse 已提交
309
            that.$.callComEvent(that, 'addEvents', {
C
Catouse 已提交
310 311 312 313
                newEvents: events,
                data: that.data
            });
        }
C
Catouse 已提交
314 315
    };

C
Catouse 已提交
316
    Calendar.prototype.getEvent = function(id) {
C
Catouse 已提交
317
        var events = this.events;
C
Catouse 已提交
318 319
        for(var i = 0; i < events.length; i++) {
            if(events[i].id == id) {
C
Catouse 已提交
320 321 322
                return events[i];
            }
        }
C
Catouse 已提交
323
        return null;
C
Catouse 已提交
324 325
    };

C
Catouse 已提交
326
    Calendar.prototype.updateEvents = function(events) {
327
        var eventsParams = {
C
Catouse 已提交
328 329 330 331
                data: this.data,
                changes: []
            },
            that = this;
C
Catouse 已提交
332

C
Catouse 已提交
333
        if($.isPlainObject(events)) {
C
Catouse 已提交
334 335 336
            events = [events];
        }
        var event, chgs, eventParam;
C
Catouse 已提交
337
        $.each(events, function(index, changes) {
C
Catouse 已提交
338 339
            event = changes.event;
            chgs = changes.changes;
340 341 342 343
            eventParam = {
                event: event,
                changes: []
            };
C
Catouse 已提交
344
            if(typeof event === STRING_TYPE_NAME) {
345
                event = that.getEvent(event);
C
Catouse 已提交
346
            }
C
Catouse 已提交
347 348
            if(event) {
                if($.isPlainObject(chgs)) {
C
Catouse 已提交
349 350
                    chgs = [chgs];
                }
C
Catouse 已提交
351
                $.each(changes, function(idx, chge) {
C
Catouse 已提交
352 353 354 355 356 357
                    if(false !== that.$.callComEvent(that, 'beforeChange', {
                        event: event,
                        change: chge.change,
                        to: chge.to,
                        from: event[chge.change]
                    })) {
C
Catouse 已提交
358
                        eventParam.changes.push($.extend(true, {}, chge, {
359 360
                            from: event[chge.change]
                        }));
C
Catouse 已提交
361 362 363 364 365 366 367
                        event[chge.change] = chge.to;
                    }
                });
            }
            eventsParams.changes.push(eventParam);
        });

368 369
        that.sortEvents();
        that.display();
C
Catouse 已提交
370
        that.$.callComEvent(that, 'change', eventsParams);
C
Catouse 已提交
371 372
    };

C
Catouse 已提交
373 374
    Calendar.prototype.removeEvents = function(events) {
        if(!$.isArray(events)) {
C
Catouse 已提交
375 376
            events = [events];
        }
C
Catouse 已提交
377 378
        var id, event, idx, evts = this.events,
            that = this,
379
            removedEvents = [];
C
Catouse 已提交
380
        $.each(events, function(index, value) {
C
Catouse 已提交
381 382
            id = $.isPlainObject(value) ? value.id : value;
            idx = -1;
C
Catouse 已提交
383 384
            for(var i = 0; i < evts.length; i++) {
                if(evts[i].id == id) {
C
Catouse 已提交
385 386 387 388 389 390
                    idx = i;
                    event = evts[i];
                    break;
                }
            }

J
JIMhackKING 已提交
391
            if(idx >= 0 && false !== that.$.callComEvent(that, 'beforeRemoveEvent', {
C
Catouse 已提交
392 393 394
                    event: event,
                    eventId: id,
                    data: that.data
C
Catouse 已提交
395
                })) {
C
Catouse 已提交
396 397 398 399 400
                evts.splice(idx, 1);
                removedEvents.push(event);
            }
        });

401 402
        that.sortEvents();
        that.display();
C
Catouse 已提交
403
        that.$.callComEvent(that, 'removeEvents', {
404
            removedEvents: removedEvents,
405
            data: that.data
406
        });
C
Catouse 已提交
407 408
    };

C
Catouse 已提交
409
    Calendar.prototype.getOptions = function(options) {
C
Catouse 已提交
410
        this.options = $.extend(true, {}, Calendar.DEFAULTS, this.$.data(), options, true);
C
Catouse 已提交
411
        return this.options;
C
Catouse 已提交
412 413
    };

C
Catouse 已提交
414
    Calendar.prototype.getLang = function() {
C
Catouse 已提交
415 416
        this.langName = this.options.lang || $.zui.clientLang();
        this.lang = $.zui.getLangData(NAME, this.langName, this.options.langs);
C
Catouse 已提交
417 418
    };

C
Catouse 已提交
419
    Calendar.prototype.display = function(view, date) {
420
        var that = this;
C
Catouse 已提交
421 422 423
        var viewType = typeof view;
        var dateType = typeof date;

C
Catouse 已提交
424
        if(viewType === UNDEFINED_TYPE_NAME) {
425
            view = that.view;
C
Catouse 已提交
426
        } else {
427
            that.view = view;
C
Catouse 已提交
428 429
        }

C
Catouse 已提交
430
        if(dateType === UNDEFINED_TYPE_NAME) {
431
            date = that.date;
C
Catouse 已提交
432
        } else {
433
            that.date = date;
C
Catouse 已提交
434 435
        }

C
Catouse 已提交
436
        if(date === 'today') {
C
Catouse 已提交
437
            date = new Date();
438
            that.date = date;
C
Catouse 已提交
439
        }
C
Catouse 已提交
440

C
Catouse 已提交
441
        if(typeof date === STRING_TYPE_NAME) {
C
Catouse 已提交
442
            date = new Date(date);
443
            that.date = date;
C
Catouse 已提交
444 445
        }

C
Catouse 已提交
446 447
        if(that.options.storage) {
            $.zui.store.pageSet(that.storeName, {
448 449 450
                date: date,
                view: view
            });
C
Catouse 已提交
451 452
        }

453 454 455 456
        var eventPramas = {
            view: view,
            date: date
        };
C
Catouse 已提交
457 458

        var doDisplay = function() {
C
Catouse 已提交
459
            switch(view) {
C
Catouse 已提交
460
                case 'month':
461
                    that.displayMonth(date);
C
Catouse 已提交
462 463 464
                    break;
            }

C
Catouse 已提交
465 466 467 468 469 470
            that.$.callComEvent(that, 'display', eventPramas);
        };

        var beforeDisplayResult = that.$.callComEvent(that, 'beforeDisplay', [eventPramas, doDisplay]);
        if (beforeDisplayResult !== false) {
            doDisplay();
C
Catouse 已提交
471 472 473
        }
    };

C
Catouse 已提交
474
    Calendar.prototype.displayMonth = function(date) {
475
        var that = this;
C
Catouse 已提交
476
        date = date || that.date;
477 478
        var options = that.options,
            lang = that.lang,
C
Catouse 已提交
479
            i,
480 481
            $views = that.$views,
            $e = that.$;
C
Catouse 已提交
482

C
Catouse 已提交
483
        var $view = that.$monthView;
C
Catouse 已提交
484
        if(!$view || !$view.length) {
C
Catouse 已提交
485 486 487 488 489 490
            $view = $('<div class="calendar-view month"><table class="table table-bordered"><thead><tr class="week-head"></tr></thead><tbody class="month-days"></tbody></table></div>');

            var $weekHead = $view.find('.week-head'),
                $monthDays = $view.find('.month-days'),
                $tr;

C
Catouse 已提交
491
            for(i = 0; i < 7; i++) {
C
Catouse 已提交
492
                $('<th>' + lang.weekNames[i] + '</th>').toggleClass('weekend-head', i >= 5).appendTo($weekHead);
C
Catouse 已提交
493 494
            }

C
Catouse 已提交
495
            for(i = 0; i < 6; i++) {
C
Catouse 已提交
496
                $tr = $('<tr class="week-days"></tr>');
C
Catouse 已提交
497
                for(var j = 0; j < 7; j++) {
C
Catouse 已提交
498
                    $('<td class="cell-day"><div class="day"><div class="heading"><span class="month"></span> <span class="number"></span></div><div class="content"><div class="events"></div></div></div></td>').toggleClass('weekend-day', j >= 5).appendTo($tr);
C
Catouse 已提交
499 500 501 502 503
                }
                $monthDays.append($tr);
            }

            $views.append($view);
C
Catouse 已提交
504
            that.$monthView = $view;
C
Catouse 已提交
505 506 507 508 509 510 511 512 513 514 515 516
        }

        var $weeks = $view.find('.week-days'),
            firstDayOfMonth = getFirstDayOfMonth(date),
            $week,
            $day,
            $cell,
            year,
            day,
            month,
            today = new Date();
        var firstDay = getNearbyLastWeekDay(firstDayOfMonth),
517 518
            thisYear = date.getFullYear(),
            thisMonth = date.getMonth(),
C
Catouse 已提交
519
            todayMonth = today.getMonth(),
520 521
            todayYear = today.getFullYear(),
            todayDate = today.getDate();
C
Catouse 已提交
522 523
        var lastDay = firstDay.clone().addDays(6 * 7).addMilliseconds(-1),
            printDate = firstDay.clone().addDays(1).addMilliseconds(-1);
C
Catouse 已提交
524
        var events = that.getEvents(firstDay, lastDay),
C
Catouse 已提交
525 526
            calendars = that.calendars,
            printDateId, isFirstDayOfWeek, $event, cal, $dayEvents;
C
Catouse 已提交
527

C
Catouse 已提交
528
        var isEmptyWeekends = true;
C
Catouse 已提交
529
        $weeks.each(function(weekIdx) {
C
Catouse 已提交
530
            $week = $(this);
C
Catouse 已提交
531
            $week.find('.day').each(function(dayIndex) {
C
Catouse 已提交
532
                isFirstDayOfWeek = dayIndex === 0;
C
Catouse 已提交
533 534 535 536 537
                $day = $(this);
                $cell = $day.closest('.cell-day');
                year = printDate.getFullYear();
                day = printDate.getDate();
                month = printDate.getMonth();
C
Catouse 已提交
538
                printDateId = printDate.toDateString();
C
Catouse 已提交
539
                $day.attr('data-date', printDateId).data('date', printDate.clone());
C
Catouse 已提交
540
                $day.find('.heading > .number').text(day).toggle(!options.hideFirstDayNumber || day !== 1);
C
Catouse 已提交
541 542 543 544 545 546
                $day.find('.heading > .month')
                    .toggle((weekIdx === 0 && dayIndex === 0) || day === 1)
                    .text(((month === 0 && day === 1) ? (lang.year.format(year) + ' ') : '') + lang.monthNames[month]);
                $cell.toggleClass('current-month', month === thisMonth);
                $cell.toggleClass('current', (day === todayDate && month === todayMonth && year === todayYear));
                $cell.toggleClass('past', printDate < today);
C
Catouse 已提交
547
                $cell.toggleClass('first-day', day === 1);
C
Catouse 已提交
548
                $cell.toggleClass('future', printDate > today);
C
Catouse 已提交
549 550 551
                $dayEvents = $day.find('.events').empty();

                var dayEvents = events[printDateId];
C
Catouse 已提交
552
                if(dayEvents) {
C
Catouse 已提交
553
                    var eventsMap = dayEvents.events,
C
Catouse 已提交
554 555 556
                        stripCount = 0,
                        e;
                    for(i = 0; i <= dayEvents.maxPos; ++i) {
C
Catouse 已提交
557 558 559 560 561
                        e = eventsMap[i];
                        if(!e || (e.placeholder && !isFirstDayOfWeek)) {
                            stripCount++;
                            continue;
                        }
C
Catouse 已提交
562 563 564
                        if (isEmptyWeekends && dayIndex >= 5) {
                            isEmptyWeekends = false;
                        }
C
Catouse 已提交
565 566 567 568 569 570 571 572 573
                        if (options.eventCreator) {
                            $event = options.eventCreator(e, $cell, that);
                        } else {
                            $event = $('<div data-id="' + e.id + '" class="event" title="' + e.desc + '"><span class="time">' + e.start.format('hh:mm') + '</span> <span class="title">' + e.title + '</span></div>');
                            $event.find('.time').toggle(!e.allDay);
                            $event.data('event', e);
                            $event.attr('data-days', e.days);
                        }
                        $event.toggleClass('event-all-day', !!e.allDay).data('event', e).attr('data-days', e.days);
C
Catouse 已提交
574

C
Catouse 已提交
575
                        if(e.calendar) {
C
Catouse 已提交
576
                            cal = calendars[e.calendar];
C
Catouse 已提交
577
                            if(cal) {
C
Catouse 已提交
578 579 580
                                if(cal.presetColor) {
                                    $event.addClass('color-' + cal.color);
                                } else {
C
Catouse 已提交
581 582 583 584
                                    $event.css({
                                        'background-color': cal.color,
                                        color: cal.textColor
                                    });
C
Catouse 已提交
585 586 587 588
                                }
                            }
                        }

C
Catouse 已提交
589 590
                        if(e.days) {
                            if(!e.placeholder) {
C
Catouse 已提交
591
                                $event.css('width', Math.min(7 - dayIndex, e.days) + '00%');
C
Catouse 已提交
592
                            } else if(isFirstDayOfWeek) {
C
Catouse 已提交
593 594 595 596 597 598 599 600 601 602 603 604
                                $event.css('width', Math.min(7, e.days - e.holderPos) + '00%');
                            }
                        }

                        if(stripCount > 0) {
                            $event.css('margin-top', stripCount * 22);
                            stripCount = 0;
                        }

                        $dayEvents.append($event);
                    }
                }
C
Catouse 已提交
605

C
Catouse 已提交
606 607
                $cell.toggleClass('empty', !$day.find('.events').length);

C
Catouse 已提交
608 609 610 611
                if (options.dayFormater) {
                    options.dayFormater($cell, printDate, dayEvents, that);
                }

C
Catouse 已提交
612 613 614
                printDate.addDays(1);
            });
        });
C
Catouse 已提交
615 616 617
        if (options.hideEmptyWeekends) {
            $view.toggleClass('weekends-empty', isEmptyWeekends);
        }
C
Catouse 已提交
618

C
Catouse 已提交
619
        if(options.withHeader) {
C
Catouse 已提交
620
            that.$caption.text(lang.yearMonth.format(thisYear, thisMonth + 1, lang.monthNames[thisMonth]));
C
Catouse 已提交
621
            that.$todayBtn.toggleClass('disabled', thisMonth === todayMonth && thisYear === todayYear);
C
Catouse 已提交
622 623
        }

C
Catouse 已提交
624
        if(options.dragThenDrop) {
C
Catouse 已提交
625 626 627 628
            if(!$.fn.droppable) {
                return console.error('Calendar dragThenDrop option requires droppable.js');
            }
            if(!$view.data('zui.droppable')) {
C
Catouse 已提交
629 630
                $view.droppable($.extend({
                    target: '.cell-day',
C
Catouse 已提交
631
                    selector: '.event',
C
Catouse 已提交
632 633
                    flex: true,
                    start: function() {
C
Catouse 已提交
634
                        that.$.addClass('event-dragging');
C
Catouse 已提交
635 636 637
                    },
                    drop: function(e) {
                        var et = e.element.data('event'),
C
Catouse 已提交
638
                            newDate = e.target.children('.day').attr('data-date');
C
Catouse 已提交
639 640 641 642 643 644 645 646
                        if(!et || !newDate) return;
                        var startDate = et.start.clone();
                        if(startDate.toDateString() != newDate) {
                            newDate = new Date(newDate);
                            newDate.setHours(startDate.getHours());
                            newDate.setMinutes(startDate.getMinutes());
                            newDate.setSeconds(startDate.getSeconds());

C
Catouse 已提交
647
                            if(false !== that.$.callComEvent(that, 'beforeChange', {
648
                                    event: et,
C
Catouse 已提交
649 650 651 652 653 654 655 656 657 658
                                    change: 'start',
                                    to: newDate
                                })) {
                                var oldEnd = et.end.clone();

                                et.end.addMilliseconds(et.end.getTime() - startDate.getTime());
                                et.start = newDate;

                                that.display();

C
Catouse 已提交
659
                                that.$.callComEvent(that, 'change', {
C
Catouse 已提交
660
                                    data: that.data,
C
Catouse 已提交
661
                                    changes: [{
C
Catouse 已提交
662 663 664 665 666 667 668 669 670 671
                                        event: et,
                                        changes: [{
                                            change: 'start',
                                            from: startDate,
                                            to: et.start
                                        }, {
                                            change: 'end',
                                            from: oldEnd,
                                            to: et.end
                                        }]
672
                                    }]
C
Catouse 已提交
673 674
                                });
                            }
C
Catouse 已提交
675
                        }
C
Catouse 已提交
676 677
                    },
                    finish: function() {
C
Catouse 已提交
678
                        that.$.removeClass('event-dragging');
C
Catouse 已提交
679
                    }
C
Catouse 已提交
680
                }, ($.isPlainObject(options.dragThenDrop)) ? options.dragThenDrop : null));
C
Catouse 已提交
681
            }
C
Catouse 已提交
682 683 684
        }
    };

C
Catouse 已提交
685
    Calendar.prototype.getEvents = function(start, end) {
C
Catouse 已提交
686 687
        var events = {};
        var calendars = this.calendars;
C
Catouse 已提交
688
        var addEventToDay = function(day, event, position) {
C
Catouse 已提交
689 690
            var dayId = day.toDateString();
            var dayEvents = events[dayId];
C
Catouse 已提交
691 692 693 694 695
            if(!dayEvents) {
                dayEvents = {
                    maxPos: -1,
                    events: {}
                };
C
Catouse 已提交
696 697
            }

C
Catouse 已提交
698 699 700
            if(typeof position === 'undefined') {
                for(var i = 0; i < 100; ++i) {
                    if(!dayEvents.events[i]) {
C
Catouse 已提交
701 702 703 704 705 706 707 708 709 710 711
                        position = i;
                        break;
                    }
                }
            }

            dayEvents.maxPos = Math.max(position, dayEvents.maxPos);
            dayEvents.events[position] = event;
            events[dayId] = dayEvents;
            return position;
        };
C
Catouse 已提交
712 713
        $.each(this.events, function(index, e) {
            if(e.start >= start && e.start <= end) {
C
Catouse 已提交
714
                var position = addEventToDay(e.start, e);
C
Catouse 已提交
715 716 717 718 719 720 721 722
                if(e.days > 1) {
                    var placeholder = $.extend({
                        placeholder: true
                    }, e);
                    everyDayTo(e.start.clone().addDays(1), e.end, function(thisDay, i) {
                        addEventToDay(thisDay.clone(), $.extend({
                            holderPos: i
                        }, placeholder), position);
C
Catouse 已提交
723 724 725 726 727 728 729
                    });
                }
            }
        });
        return events;
    };

C
Catouse 已提交
730 731
    $.fn.calendar = function(option) {
        return this.each(function() {
732
            var $this = $(this);
C
Catouse 已提交
733
            var data = $this.data(NAME);
C
Catouse 已提交
734 735
            var options = typeof option == 'object' && option;

C
Catouse 已提交
736
            if(!data) $this.data(NAME, (data = new Calendar(this, options)));
C
Catouse 已提交
737

C
Catouse 已提交
738
            if(typeof option == STRING_TYPE_NAME) data[option]();
C
Catouse 已提交
739 740 741 742
        });
    };

    $.fn.calendar.Constructor = Calendar;
C
Catouse 已提交
743
}(jQuery, window));