major doc changes
[roojs1] / Roo / bootstrap / Calendar.js
1 /*
2  * - LGPL
3  *
4  * based on jquery fullcalendar
5  * 
6  */
7
8 Roo.bootstrap = Roo.bootstrap || {};
9 /**
10  * @class Roo.bootstrap.Calendar
11  * @extends Roo.bootstrap.Component
12  * Bootstrap Calendar class
13  * @cfg {Boolean} loadMask (true|false) default false
14  * @cfg {Object} header generate the user specific header of the calendar, default false
15
16  * @constructor
17  * Create a new Container
18  * @param {Object} config The config object
19  */
20
21
22
23 Roo.bootstrap.Calendar = function(config){
24     Roo.bootstrap.Calendar.superclass.constructor.call(this, config);
25      this.addEvents({
26         /**
27              * @event select
28              * Fires when a date is selected
29              * @param {DatePicker} this
30              * @param {Date} date The selected date
31              */
32         'select': true,
33         /**
34              * @event monthchange
35              * Fires when the displayed month changes 
36              * @param {DatePicker} this
37              * @param {Date} date The selected month
38              */
39         'monthchange': true,
40         /**
41              * @event evententer
42              * Fires when mouse over an event
43              * @param {Calendar} this
44              * @param {event} Event
45              */
46         'evententer': true,
47         /**
48              * @event eventleave
49              * Fires when the mouse leaves an
50              * @param {Calendar} this
51              * @param {event}
52              */
53         'eventleave': true,
54         /**
55              * @event eventclick
56              * Fires when the mouse click an
57              * @param {Calendar} this
58              * @param {event}
59              */
60         'eventclick': true
61         
62     });
63
64 };
65
66 Roo.extend(Roo.bootstrap.Calendar, Roo.bootstrap.Component,  {
67     
68           /**
69      * @cfg {Roo.data.Store} store
70      * The data source for the calendar
71      */
72         store : false,
73      /**
74      * @cfg {Number} startDay
75      * Day index at which the week should begin, 0-based (defaults to 0, which is Sunday)
76      */
77     startDay : 0,
78     
79     loadMask : false,
80     
81     header : false,
82       
83     getAutoCreate : function(){
84         
85         
86         var fc_button = function(name, corner, style, content ) {
87             return Roo.apply({},{
88                 tag : 'span',
89                 cls : 'fc-button fc-button-'+name+' fc-state-default ' + 
90                          (corner.length ?
91                             'fc-corner-' + corner.split(' ').join(' fc-corner-') :
92                             ''
93                         ),
94                 html : '<SPAN class="fc-text-'+style+ '">'+content +'</SPAN>',
95                 unselectable: 'on'
96             });
97         };
98         
99         var header = {};
100         
101         if(!this.header){
102             header = {
103                 tag : 'table',
104                 cls : 'fc-header',
105                 style : 'width:100%',
106                 cn : [
107                     {
108                         tag: 'tr',
109                         cn : [
110                             {
111                                 tag : 'td',
112                                 cls : 'fc-header-left',
113                                 cn : [
114                                     fc_button('prev', 'left', 'arrow', '&#8249;' ),
115                                     fc_button('next', 'right', 'arrow', '&#8250;' ),
116                                     { tag: 'span', cls: 'fc-header-space' },
117                                     fc_button('today', 'left right', '', 'today' )  // neds state disabled..
118
119
120                                 ]
121                             },
122
123                             {
124                                 tag : 'td',
125                                 cls : 'fc-header-center',
126                                 cn : [
127                                     {
128                                         tag: 'span',
129                                         cls: 'fc-header-title',
130                                         cn : {
131                                             tag: 'H2',
132                                             html : 'month / year'
133                                         }
134                                     }
135
136                                 ]
137                             },
138                             {
139                                 tag : 'td',
140                                 cls : 'fc-header-right',
141                                 cn : [
142                               /*      fc_button('month', 'left', '', 'month' ),
143                                     fc_button('week', '', '', 'week' ),
144                                     fc_button('day', 'right', '', 'day' )
145                                 */    
146
147                                 ]
148                             }
149
150                         ]
151                     }
152                 ]
153             };
154         }
155         
156         header = this.header;
157         
158        
159         var cal_heads = function() {
160             var ret = [];
161             // fixme - handle this.
162             
163             for (var i =0; i < Date.dayNames.length; i++) {
164                 var d = Date.dayNames[i];
165                 ret.push({
166                     tag: 'th',
167                     cls : 'fc-day-header fc-' + d.substring(0,3).toLowerCase() + ' fc-widget-header',
168                     html : d.substring(0,3)
169                 });
170                 
171             }
172             ret[0].cls += ' fc-first';
173             ret[6].cls += ' fc-last';
174             return ret;
175         };
176         var cal_cell = function(n) {
177             return  {
178                 tag: 'td',
179                 cls : 'fc-day fc-'+n + ' fc-widget-content', ///fc-other-month fc-past
180                 cn : [
181                     {
182                         cn : [
183                             {
184                                 cls: 'fc-day-number',
185                                 html: 'D'
186                             },
187                             {
188                                 cls: 'fc-day-content',
189                              
190                                 cn : [
191                                      {
192                                         style: 'position: relative;' // height: 17px;
193                                     }
194                                 ]
195                             }
196                             
197                             
198                         ]
199                     }
200                 ]
201                 
202             }
203         };
204         var cal_rows = function() {
205             
206             var ret = [];
207             for (var r = 0; r < 6; r++) {
208                 var row= {
209                     tag : 'tr',
210                     cls : 'fc-week',
211                     cn : []
212                 };
213                 
214                 for (var i =0; i < Date.dayNames.length; i++) {
215                     var d = Date.dayNames[i];
216                     row.cn.push(cal_cell(d.substring(0,3).toLowerCase()));
217
218                 }
219                 row.cn[0].cls+=' fc-first';
220                 row.cn[0].cn[0].style = 'min-height:90px';
221                 row.cn[6].cls+=' fc-last';
222                 ret.push(row);
223                 
224             }
225             ret[0].cls += ' fc-first';
226             ret[4].cls += ' fc-prev-last';
227             ret[5].cls += ' fc-last';
228             return ret;
229             
230         };
231         
232         var cal_table = {
233             tag: 'table',
234             cls: 'fc-border-separate',
235             style : 'width:100%',
236             cellspacing  : 0,
237             cn : [
238                 { 
239                     tag: 'thead',
240                     cn : [
241                         { 
242                             tag: 'tr',
243                             cls : 'fc-first fc-last',
244                             cn : cal_heads()
245                         }
246                     ]
247                 },
248                 { 
249                     tag: 'tbody',
250                     cn : cal_rows()
251                 }
252                   
253             ]
254         };
255          
256          var cfg = {
257             cls : 'fc fc-ltr',
258             cn : [
259                 header,
260                 {
261                     cls : 'fc-content',
262                     style : "position: relative;",
263                     cn : [
264                         {
265                             cls : 'fc-view fc-view-month fc-grid',
266                             style : 'position: relative',
267                             unselectable : 'on',
268                             cn : [
269                                 {
270                                     cls : 'fc-event-container',
271                                     style : 'position:absolute;z-index:8;top:0;left:0;'
272                                 },
273                                 cal_table
274                             ]
275                         }
276                     ]
277     
278                 }
279            ] 
280             
281         };
282         
283          
284         
285         return cfg;
286     },
287     
288     
289     initEvents : function()
290     {
291         if(!this.store){
292             throw "can not find store for calendar";
293         }
294         
295         var mark = {
296             tag: "div",
297             cls:"x-dlg-mask",
298             style: "text-align:center",
299             cn: [
300                 {
301                     tag: "div",
302                     style: "background-color:white;width:50%;margin:250 auto",
303                     cn: [
304                         {
305                             tag: "img",
306                             src: Roo.rootURL + '/images/ux/lightbox/loading.gif' 
307                         },
308                         {
309                             tag: "span",
310                             html: "Loading"
311                         }
312                         
313                     ]
314                 }
315             ]
316         };
317         this.maskEl = Roo.DomHelper.append(this.el.select('.fc-content', true).first(), mark, true);
318         
319         var size = this.el.select('.fc-content', true).first().getSize();
320         this.maskEl.setSize(size.width, size.height);
321         this.maskEl.enableDisplayMode("block");
322         if(!this.loadMask){
323             this.maskEl.hide();
324         }
325         
326         this.store = Roo.factory(this.store, Roo.data);
327         this.store.on('load', this.onLoad, this);
328         this.store.on('beforeload', this.onBeforeLoad, this);
329         
330         this.resize();
331         
332         this.cells = this.el.select('.fc-day',true);
333         //Roo.log(this.cells);
334         this.textNodes = this.el.query('.fc-day-number');
335         this.cells.addClassOnOver('fc-state-hover');
336         
337         this.el.select('.fc-button-prev',true).on('click', this.showPrevMonth, this);
338         this.el.select('.fc-button-next',true).on('click', this.showNextMonth, this);
339         this.el.select('.fc-button-today',true).on('click', this.showToday, this);
340         this.el.select('.fc-button',true).addClassOnOver('fc-state-hover');
341         
342         this.on('monthchange', this.onMonthChange, this);
343         
344         this.update(new Date().clearTime());
345     },
346     
347     resize : function() {
348         var sz  = this.el.getSize();
349         
350         this.el.select('.fc-day-header',true).setWidth(sz.width / 7);
351         this.el.select('.fc-day-content div',true).setHeight(34);
352     },
353     
354     
355     // private
356     showPrevMonth : function(e){
357         this.update(this.activeDate.add("mo", -1));
358     },
359     showToday : function(e){
360         this.update(new Date().clearTime());
361     },
362     // private
363     showNextMonth : function(e){
364         this.update(this.activeDate.add("mo", 1));
365     },
366
367     // private
368     showPrevYear : function(){
369         this.update(this.activeDate.add("y", -1));
370     },
371
372     // private
373     showNextYear : function(){
374         this.update(this.activeDate.add("y", 1));
375     },
376
377     
378    // private
379     update : function(date)
380     {
381         var vd = this.activeDate;
382         this.activeDate = date;
383 //        if(vd && this.el){
384 //            var t = date.getTime();
385 //            if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
386 //                Roo.log('using add remove');
387 //                
388 //                this.fireEvent('monthchange', this, date);
389 //                
390 //                this.cells.removeClass("fc-state-highlight");
391 //                this.cells.each(function(c){
392 //                   if(c.dateValue == t){
393 //                       c.addClass("fc-state-highlight");
394 //                       setTimeout(function(){
395 //                            try{c.dom.firstChild.focus();}catch(e){}
396 //                       }, 50);
397 //                       return false;
398 //                   }
399 //                   return true;
400 //                });
401 //                return;
402 //            }
403 //        }
404         
405         var days = date.getDaysInMonth();
406         
407         var firstOfMonth = date.getFirstDateOfMonth();
408         var startingPos = firstOfMonth.getDay()-this.startDay;
409         
410         if(startingPos < this.startDay){
411             startingPos += 7;
412         }
413         
414         var pm = date.add(Date.MONTH, -1);
415         var prevStart = pm.getDaysInMonth()-startingPos;
416 //        
417         this.cells = this.el.select('.fc-day',true);
418         this.textNodes = this.el.query('.fc-day-number');
419         this.cells.addClassOnOver('fc-state-hover');
420         
421         var cells = this.cells.elements;
422         var textEls = this.textNodes;
423         
424         Roo.each(cells, function(cell){
425             cell.removeClass([ 'fc-past', 'fc-other-month', 'fc-future', 'fc-state-highlight', 'fc-state-disabled']);
426         });
427         
428         days += startingPos;
429
430         // convert everything to numbers so it's fast
431         var day = 86400000;
432         var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
433         //Roo.log(d);
434         //Roo.log(pm);
435         //Roo.log(prevStart);
436         
437         var today = new Date().clearTime().getTime();
438         var sel = date.clearTime().getTime();
439         var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
440         var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
441         var ddMatch = this.disabledDatesRE;
442         var ddText = this.disabledDatesText;
443         var ddays = this.disabledDays ? this.disabledDays.join("") : false;
444         var ddaysText = this.disabledDaysText;
445         var format = this.format;
446         
447         var setCellClass = function(cal, cell){
448             cell.row = 0;
449             cell.events = [];
450             cell.more = [];
451             //Roo.log('set Cell Class');
452             cell.title = "";
453             var t = d.getTime();
454             
455             //Roo.log(d);
456             
457             cell.dateValue = t;
458             if(t == today){
459                 cell.className += " fc-today";
460                 cell.className += " fc-state-highlight";
461                 cell.title = cal.todayText;
462             }
463             if(t == sel){
464                 // disable highlight in other month..
465                 //cell.className += " fc-state-highlight";
466                 
467             }
468             // disabling
469             if(t < min) {
470                 cell.className = " fc-state-disabled";
471                 cell.title = cal.minText;
472                 return;
473             }
474             if(t > max) {
475                 cell.className = " fc-state-disabled";
476                 cell.title = cal.maxText;
477                 return;
478             }
479             if(ddays){
480                 if(ddays.indexOf(d.getDay()) != -1){
481                     cell.title = ddaysText;
482                     cell.className = " fc-state-disabled";
483                 }
484             }
485             if(ddMatch && format){
486                 var fvalue = d.dateFormat(format);
487                 if(ddMatch.test(fvalue)){
488                     cell.title = ddText.replace("%0", fvalue);
489                     cell.className = " fc-state-disabled";
490                 }
491             }
492             
493             if (!cell.initialClassName) {
494                 cell.initialClassName = cell.dom.className;
495             }
496             
497             cell.dom.className = cell.initialClassName  + ' ' +  cell.className;
498         };
499
500         var i = 0;
501         
502         for(; i < startingPos; i++) {
503             textEls[i].innerHTML = (++prevStart);
504             d.setDate(d.getDate()+1);
505             
506             cells[i].className = "fc-past fc-other-month";
507             setCellClass(this, cells[i]);
508         }
509         
510         var intDay = 0;
511         
512         for(; i < days; i++){
513             intDay = i - startingPos + 1;
514             textEls[i].innerHTML = (intDay);
515             d.setDate(d.getDate()+1);
516             
517             cells[i].className = ''; // "x-date-active";
518             setCellClass(this, cells[i]);
519         }
520         var extraDays = 0;
521         
522         for(; i < 42; i++) {
523             textEls[i].innerHTML = (++extraDays);
524             d.setDate(d.getDate()+1);
525             
526             cells[i].className = "fc-future fc-other-month";
527             setCellClass(this, cells[i]);
528         }
529         
530         this.el.select('.fc-header-title h2',true).update(Date.monthNames[date.getMonth()] + " " + date.getFullYear());
531         
532         var totalRows = Math.ceil((date.getDaysInMonth() + date.getFirstDateOfMonth().getDay()) / 7);
533         
534         this.el.select('tr.fc-week.fc-prev-last',true).removeClass('fc-last');
535         this.el.select('tr.fc-week.fc-next-last',true).addClass('fc-last').show();
536         
537         if(totalRows != 6){
538             this.el.select('tr.fc-week.fc-last',true).removeClass('fc-last').addClass('fc-next-last').hide();
539             this.el.select('tr.fc-week.fc-prev-last',true).addClass('fc-last');
540         }
541         
542         this.fireEvent('monthchange', this, date);
543         
544         
545         /*
546         if(!this.internalRender){
547             var main = this.el.dom.firstChild;
548             var w = main.offsetWidth;
549             this.el.setWidth(w + this.el.getBorderWidth("lr"));
550             Roo.fly(main).setWidth(w);
551             this.internalRender = true;
552             // opera does not respect the auto grow header center column
553             // then, after it gets a width opera refuses to recalculate
554             // without a second pass
555             if(Roo.isOpera && !this.secondPass){
556                 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
557                 this.secondPass = true;
558                 this.update.defer(10, this, [date]);
559             }
560         }
561         */
562         
563     },
564     
565     findCell : function(dt) {
566         dt = dt.clearTime().getTime();
567         var ret = false;
568         this.cells.each(function(c){
569             //Roo.log("check " +c.dateValue + '?=' + dt);
570             if(c.dateValue == dt){
571                 ret = c;
572                 return false;
573             }
574             return true;
575         });
576         
577         return ret;
578     },
579     
580     findCells : function(ev) {
581         var s = ev.start.clone().clearTime().getTime();
582        // Roo.log(s);
583         var e= ev.end.clone().clearTime().getTime();
584        // Roo.log(e);
585         var ret = [];
586         this.cells.each(function(c){
587              ////Roo.log("check " +c.dateValue + '<' + e + ' > ' + s);
588             
589             if(c.dateValue > e){
590                 return ;
591             }
592             if(c.dateValue < s){
593                 return ;
594             }
595             ret.push(c);
596         });
597         
598         return ret;    
599     },
600     
601 //    findBestRow: function(cells)
602 //    {
603 //        var ret = 0;
604 //        
605 //        for (var i =0 ; i < cells.length;i++) {
606 //            ret  = Math.max(cells[i].rows || 0,ret);
607 //        }
608 //        return ret;
609 //        
610 //    },
611     
612     
613     addItem : function(ev)
614     {
615         // look for vertical location slot in
616         var cells = this.findCells(ev);
617         
618 //        ev.row = this.findBestRow(cells);
619         
620         // work out the location.
621         
622         var crow = false;
623         var rows = [];
624         for(var i =0; i < cells.length; i++) {
625             
626             cells[i].row = cells[0].row;
627             
628             if(i == 0){
629                 cells[i].row = cells[i].row + 1;
630             }
631             
632             if (!crow) {
633                 crow = {
634                     start : cells[i],
635                     end :  cells[i]
636                 };
637                 continue;
638             }
639             if (crow.start.getY() == cells[i].getY()) {
640                 // on same row.
641                 crow.end = cells[i];
642                 continue;
643             }
644             // different row.
645             rows.push(crow);
646             crow = {
647                 start: cells[i],
648                 end : cells[i]
649             };
650             
651         }
652         
653         rows.push(crow);
654         ev.els = [];
655         ev.rows = rows;
656         ev.cells = cells;
657         
658         cells[0].events.push(ev);
659         
660         this.calevents.push(ev);
661     },
662     
663     clearEvents: function() {
664         
665         if(!this.calevents){
666             return;
667         }
668         
669         Roo.each(this.cells.elements, function(c){
670             c.row = 0;
671             c.events = [];
672             c.more = [];
673         });
674         
675         Roo.each(this.calevents, function(e) {
676             Roo.each(e.els, function(el) {
677                 el.un('mouseenter' ,this.onEventEnter, this);
678                 el.un('mouseleave' ,this.onEventLeave, this);
679                 el.remove();
680             },this);
681         },this);
682         
683         Roo.each(Roo.select('.fc-more-event', true).elements, function(e){
684             e.remove();
685         });
686         
687     },
688     
689     renderEvents: function()
690     {   
691         var _this = this;
692         
693         this.cells.each(function(c) {
694             
695             if(c.row < 5){
696                 return;
697             }
698             
699             var ev = c.events;
700             
701             var r = 4;
702             if(c.row != c.events.length){
703                 r = 4 - (4 - (c.row - c.events.length));
704             }
705             
706             c.events = ev.slice(0, r);
707             c.more = ev.slice(r);
708             
709             if(c.more.length && c.more.length == 1){
710                 c.events.push(c.more.pop());
711             }
712             
713             c.row = (c.row - ev.length) + c.events.length + ((c.more.length) ? 1 : 0);
714             
715         });
716             
717         this.cells.each(function(c) {
718             
719             c.select('.fc-day-content div',true).first().setHeight(Math.max(34, c.row * 20));
720             
721             
722             for (var e = 0; e < c.events.length; e++){
723                 var ev = c.events[e];
724                 var rows = ev.rows;
725                 
726                 for(var i = 0; i < rows.length; i++) {
727                 
728                     // how many rows should it span..
729
730                     var  cfg = {
731                         cls : 'roo-dynamic fc-event fc-event-hori fc-event-draggable ui-draggable',
732                         style : 'position: absolute', // left: 387px; width: 121px; top: 359px;
733
734                         unselectable : "on",
735                         cn : [
736                             {
737                                 cls: 'fc-event-inner',
738                                 cn : [
739     //                                {
740     //                                  tag:'span',
741     //                                  cls: 'fc-event-time',
742     //                                  html : cells.length > 1 ? '' : ev.time
743     //                                },
744                                     {
745                                       tag:'span',
746                                       cls: 'fc-event-title',
747                                       html : String.format('{0}', ev.title)
748                                     }
749
750
751                                 ]
752                             },
753                             {
754                                 cls: 'ui-resizable-handle ui-resizable-e',
755                                 html : '&nbsp;&nbsp;&nbsp'
756                             }
757
758                         ]
759                     };
760
761                     if (i == 0) {
762                         cfg.cls += ' fc-event-start';
763                     }
764                     if ((i+1) == rows.length) {
765                         cfg.cls += ' fc-event-end';
766                     }
767
768                     var ctr = _this.el.select('.fc-event-container',true).first();
769                     var cg = ctr.createChild(cfg);
770
771                     var sbox = rows[i].start.select('.fc-day-content',true).first().getBox();
772                     var ebox = rows[i].end.select('.fc-day-content',true).first().getBox();
773
774                     var r = (c.more.length) ? 1 : 0;
775                     cg.setXY([sbox.x +2, sbox.y + ((c.row - c.events.length - r + e) * 20)]);    
776                     cg.setWidth(ebox.right - sbox.x -2);
777
778                     cg.on('mouseenter' ,_this.onEventEnter, _this, ev);
779                     cg.on('mouseleave' ,_this.onEventLeave, _this, ev);
780                     cg.on('click', _this.onEventClick, _this, ev);
781
782                     ev.els.push(cg);
783                     
784                 }
785                 
786             }
787             
788             
789             if(c.more.length){
790                 var  cfg = {
791                     cls : 'fc-more-event roo-dynamic fc-event fc-event-hori fc-event-draggable ui-draggable fc-event-start fc-event-end',
792                     style : 'position: absolute',
793                     unselectable : "on",
794                     cn : [
795                         {
796                             cls: 'fc-event-inner',
797                             cn : [
798                                 {
799                                   tag:'span',
800                                   cls: 'fc-event-title',
801                                   html : 'More'
802                                 }
803
804
805                             ]
806                         },
807                         {
808                             cls: 'ui-resizable-handle ui-resizable-e',
809                             html : '&nbsp;&nbsp;&nbsp'
810                         }
811
812                     ]
813                 };
814
815                 var ctr = _this.el.select('.fc-event-container',true).first();
816                 var cg = ctr.createChild(cfg);
817
818                 var sbox = c.select('.fc-day-content',true).first().getBox();
819                 var ebox = c.select('.fc-day-content',true).first().getBox();
820                 //Roo.log(cg);
821                 cg.setXY([sbox.x +2, sbox.y +((c.row - 1) * 20)]);    
822                 cg.setWidth(ebox.right - sbox.x -2);
823
824                 cg.on('click', _this.onMoreEventClick, _this, c.more);
825                 
826             }
827             
828         });
829         
830         
831         
832     },
833     
834     onEventEnter: function (e, el,event,d) {
835         this.fireEvent('evententer', this, el, event);
836     },
837     
838     onEventLeave: function (e, el,event,d) {
839         this.fireEvent('eventleave', this, el, event);
840     },
841     
842     onEventClick: function (e, el,event,d) {
843         this.fireEvent('eventclick', this, el, event);
844     },
845     
846     onMonthChange: function () {
847         this.store.load();
848     },
849     
850     onMoreEventClick: function(e, el, more)
851     {
852         var _this = this;
853         
854         this.calpopover.placement = 'right';
855         this.calpopover.setTitle('More');
856         
857         this.calpopover.setContent('');
858         
859         var ctr = this.calpopover.el.select('.popover-content', true).first();
860         
861         Roo.each(more, function(m){
862             var cfg = {
863                 cls : 'fc-event-hori fc-event-draggable',
864                 html : m.title
865             };
866             var cg = ctr.createChild(cfg);
867             
868             cg.on('click', _this.onEventClick, _this, m);
869         });
870         
871         this.calpopover.show(el);
872         
873         
874     },
875     
876     onLoad: function () 
877     {   
878         this.calevents = [];
879         var cal = this;
880         
881         if(this.store.getCount() > 0){
882             this.store.data.each(function(d){
883                cal.addItem({
884                     id : d.data.id,
885                     start: (typeof(d.data.start_dt) === 'string') ? new Date.parseDate(d.data.start_dt, 'Y-m-d H:i:s') : d.data.start_dt,
886                     end : (typeof(d.data.end_dt) === 'string') ? new Date.parseDate(d.data.end_dt, 'Y-m-d H:i:s') : d.data.end_dt,
887                     time : d.data.start_time,
888                     title : d.data.title,
889                     description : d.data.description,
890                     venue : d.data.venue
891                 });
892             });
893         }
894         
895         this.renderEvents();
896         
897         if(this.calevents.length && this.loadMask){
898             this.maskEl.hide();
899         }
900     },
901     
902     onBeforeLoad: function()
903     {
904         this.clearEvents();
905         if(this.loadMask){
906             this.maskEl.show();
907         }
908     }
909 });
910
911  
912