buildSDK/dependancy_bootstrap.txt
[roojs1] / roojs-calendar-debug.js
1 /*
2  * - LGPL
3  *
4  * base class for bootstrap elements.
5  * 
6  */
7
8 Roo.bootstrap = Roo.bootstrap || {};
9 /**
10  * @class Roo.bootstrap.Component
11  * @extends Roo.Component
12  * Bootstrap Component base class
13  * @cfg {String} cls css class
14  * @cfg {String} style any extra css
15  * @cfg {Object} xattr extra attributes to add to 'element' (used by builder to store stuff.)
16  * @cfg {Boolean} can_build_overlaid  True if element can be rebuild from a HTML page
17  * @cfg {string} dataId cutomer id
18  * @cfg {string} name Specifies name attribute
19  * 
20  * @constructor
21  * Do not use directly - it does not do anything..
22  * @param {Object} config The config object
23  */
24
25
26
27 Roo.bootstrap.Component = function(config){
28     Roo.bootstrap.Component.superclass.constructor.call(this, config);
29 };
30
31 Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent,  {
32     
33     
34     allowDomMove : false, // to stop relocations in parent onRender...
35     
36     cls : false,
37     
38     style : false,
39     
40     autoCreate : false,
41     
42     initEvents : function() {  },
43     
44     xattr : false,
45     
46     parentId : false,
47     
48     can_build_overlaid : true,
49     
50     dataId : false,
51     
52     name : false,
53     
54     parent: function() {
55         // returns the parent component..
56         return Roo.ComponentMgr.get(this.parentId)
57         
58         
59     },
60     
61     // private
62     onRender : function(ct, position)
63     {
64        // Roo.log("Call onRender: " + this.xtype);
65         
66         Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
67         
68         if(this.el){
69             if (this.el.attr('xtype')) {
70                 this.el.attr('xtypex', this.el.attr('xtype'));
71                 this.el.dom.removeAttribute('xtype');
72                 
73                 this.initEvents();
74             }
75             
76             return;
77         }
78         
79          
80         
81         var cfg = Roo.apply({},  this.getAutoCreate());
82         cfg.id = Roo.id();
83         
84         // fill in the extra attributes 
85         if (this.xattr && typeof(this.xattr) =='object') {
86             for (var i in this.xattr) {
87                 cfg[i] = this.xattr[i];
88             }
89         }
90         
91         if(this.dataId){
92             cfg.dataId = this.dataId;
93         }
94         
95         if (this.cls) {
96             cfg.cls = (typeof(cfg.cls) == 'undefined') ? this.cls : cfg.cls + ' ' + this.cls;
97         }
98         
99         if (this.style) { // fixme needs to support more complex style data.
100             cfg.style = this.style;
101         }
102         
103         if(this.name){
104             cfg.name = this.name;
105         }
106         
107         this.el = ct.createChild(cfg, position);
108         
109         if(this.tabIndex !== undefined){
110             this.el.dom.setAttribute('tabIndex', this.tabIndex);
111         }
112         this.initEvents();
113         
114         
115     },
116     
117     getChildContainer : function()
118     {
119         return this.el;
120     },
121     
122     
123     addxtype  : function(tree,cntr)
124     {
125         var cn = this;
126         
127         cn = Roo.factory(tree);
128            
129         cn.parentType = this.xtype; //??
130         cn.parentId = this.id;
131         
132         cntr = typeof(cntr == 'undefined' ) ? 'getChildContainer' : cntr;
133         
134         var has_flexy_each =  (typeof(tree['flexy:foreach']) != 'undefined');
135         
136         var has_flexy_if =  (typeof(tree['flexy:if']) != 'undefined');
137         
138         var build_from_html =  Roo.XComponent.build_from_html;
139           
140         var is_body  = (tree.xtype == 'Body') ;
141           
142         var page_has_body = (Roo.get(document.body).attr('xtype') == 'Roo.bootstrap.Body');
143           
144         var self_cntr_el = Roo.get(this[cntr]());
145         
146         if (!has_flexy_each || !build_from_html || is_body || !page_has_body) {
147             if(!has_flexy_if || typeof(tree.name) == 'undefined' || !build_from_html || is_body || !page_has_body){
148                 return this.addxtypeChild(tree,cntr);
149             }
150             
151             var echild =self_cntr_el ? self_cntr_el.child('>*[name=' + tree.name + ']') : false;
152                 
153             if(echild){
154                 return this.addxtypeChild(Roo.apply({}, tree),cntr);
155             }
156             
157             Roo.log('skipping render');
158             return cn;
159             
160         }
161         
162         var ret = false;
163         
164         while (true) {
165             var echild =self_cntr_el ? self_cntr_el.child('>*[xtype]') : false;
166             
167             if (!echild) {
168                 break;
169             }
170             
171             if (echild && echild.attr('xtype').split('.').pop() != cn.xtype) {
172                 break;
173             }
174             
175             ret = this.addxtypeChild(Roo.apply({}, tree),cntr);
176         }
177         return ret;
178     },
179     
180     addxtypeChild : function (tree, cntr)
181     {
182         var cn = this;
183         cntr = typeof(cntr == 'undefined' ) ? 'getChildContainer' : cntr;
184         
185         
186         var has_flexy = (typeof(tree['flexy:if']) != 'undefined') ||
187                     (typeof(tree['flexy:foreach']) != 'undefined');
188           
189         
190         
191         
192         // render the element if it's not BODY.
193         if (tree.xtype != 'Body') {
194             var test = Roo.factory(tree);
195             cn = Roo.factory(tree);
196            
197             cn.parentType = this.xtype; //??
198             cn.parentId = this.id;
199             
200             var build_from_html =  Roo.XComponent.build_from_html;
201             
202             
203             // does the container contain child eleemnts with 'xtype' attributes.
204             // that match this xtype..
205             // note - when we render we create these as well..
206             // so we should check to see if body has xtype set.
207             if (Roo.get(document.body).attr('xtype') == 'Roo.bootstrap.Body') {
208                
209                 var self_cntr_el = Roo.get(this[cntr]());
210                 var echild =self_cntr_el ? self_cntr_el.child('>*[xtype]') : false;
211                 
212                 if (echild && echild.attr('xtype').split('.').pop() == cn.xtype) {
213                   //  Roo.log("found child for " + this.xtype +": " + echild.attr('xtype') );
214                   
215                   
216                   
217                     cn.el = echild;
218                   //  Roo.log("GOT");
219                     //echild.dom.removeAttribute('xtype');
220                 } else {
221                     Roo.log("MISSING " + cn.xtype + " on child of " + (this.el ? this.el.attr('xbuilderid') : 'no parent'));
222                    
223                 }
224             }
225            
226             
227                
228             // if object has flexy:if - then it may or may not be rendered.
229             if (build_from_html && has_flexy && !cn.el &&  cn.can_build_overlaid) {
230                 // skip a flexy if element.
231                 Roo.log('skipping render');
232              } else {
233                  
234                 // actually if flexy:foreach is found, we really want to create 
235                 // multiple copies here...
236                 
237                 cn.render(this[cntr]());
238              }
239             // then add the element..
240         }
241         
242         
243         // handle the kids..
244         
245         var nitems = [];
246         if (typeof (tree.menu) != 'undefined') {
247             tree.menu.parentType = cn.xtype;
248             tree.menu.triggerEl = cn.el;
249             nitems.push(cn.addxtype(Roo.apply({}, tree.menu)));
250             
251         }
252         
253         if (!tree.items || !tree.items.length) {
254             cn.items = nitems;
255             return cn;
256         }
257         var items = tree.items;
258         delete tree.items;
259         
260         //Roo.log(items.length);
261             // add the items..
262         for(var i =0;i < items.length;i++) {
263             nitems.push(cn.addxtype(Roo.apply({}, items[i])));
264         }
265         
266         cn.items = nitems;
267         
268         return cn;
269     }
270     
271     
272     
273     
274 });
275
276  /*
277  * - LGPL
278  *
279  * based on jquery fullcalendar
280  * 
281  */
282
283 Roo.bootstrap = Roo.bootstrap || {};
284 /**
285  * @class Roo.bootstrap.Calendar
286  * @extends Roo.bootstrap.Component
287  * Bootstrap Calendar class
288     
289  * @constructor
290  * Create a new Container
291  * @param {Object} config The config object
292  */
293
294
295
296 Roo.bootstrap.Calendar = function(config){
297     Roo.bootstrap.Calendar.superclass.constructor.call(this, config);
298      this.addEvents({
299         /**
300              * @event select
301              * Fires when a date is selected
302              * @param {DatePicker} this
303              * @param {Date} date The selected date
304              */
305         'select': true,
306         /**
307              * @event monthchange
308              * Fires when the displayed month changes 
309              * @param {DatePicker} this
310              * @param {Date} date The selected month
311              */
312         'monthchange': true,
313         /**
314              * @event evententer
315              * Fires when mouse over an event
316              * @param {Calendar} this
317              * @param {event} Event
318              */
319         'evententer': true,
320         /**
321              * @event eventleave
322              * Fires when the mouse leaves an
323              * @param {Calendar} this
324              * @param {event}
325              */
326         'eventleave': true,
327         /**
328              * @event eventclick
329              * Fires when the mouse click an
330              * @param {Calendar} this
331              * @param {event}
332              */
333         'eventclick': true
334         
335     });
336
337 };
338
339 Roo.extend(Roo.bootstrap.Calendar, Roo.bootstrap.Component,  {
340     
341      /**
342      * @cfg {Number} startDay
343      * Day index at which the week should begin, 0-based (defaults to 0, which is Sunday)
344      */
345     startDay : 0,
346       
347     getAutoCreate : function(){
348         
349         
350         fc_button = function(name, corner, style, content ) {
351             return Roo.apply({},{
352                 tag : 'span',
353                 cls : 'fc-button fc-button-'+name+' fc-state-default ' + 
354                          (corner.length ?
355                             'fc-corner-' + corner.split(' ').join(' fc-corner-') :
356                             ''
357                         ),
358                 html : '<SPAN class="fc-text-'+style+ '">'+content +'</SPAN>',
359                 unselectable: 'on'
360             });
361         };
362         
363         var header = {
364             tag : 'table',
365             cls : 'fc-header',
366             style : 'width:100%',
367             cn : [
368                 {
369                     tag: 'tr',
370                     cn : [
371                         {
372                             tag : 'td',
373                             cls : 'fc-header-left',
374                             cn : [
375                                 fc_button('prev', 'left', 'arrow', '&#8249;' ),
376                                 fc_button('next', 'right', 'arrow', '&#8250;' ),
377                                 { tag: 'span', cls: 'fc-header-space' },
378                                 fc_button('today', 'left right', '', 'today' )  // neds state disabled..
379                                 
380                                 
381                             ]
382                         },
383                         
384                         {
385                             tag : 'td',
386                             cls : 'fc-header-center',
387                             cn : [
388                                 {
389                                     tag: 'span',
390                                     cls: 'fc-header-title',
391                                     cn : {
392                                         tag: 'H2',
393                                         html : 'month / year'
394                                     }
395                                 }
396                                 
397                             ]
398                         },
399                         {
400                             tag : 'td',
401                             cls : 'fc-header-right',
402                             cn : [
403                           /*      fc_button('month', 'left', '', 'month' ),
404                                 fc_button('week', '', '', 'week' ),
405                                 fc_button('day', 'right', '', 'day' )
406                             */    
407                                 
408                             ]
409                         }
410                         
411                     ]
412                 }
413             ]
414         };
415         
416        
417         var cal_heads = function() {
418             var ret = [];
419             // fixme - handle this.
420             
421             for (var i =0; i < Date.dayNames.length; i++) {
422                 var d = Date.dayNames[i];
423                 ret.push({
424                     tag: 'th',
425                     cls : 'fc-day-header fc-' + d.substring(0,3).toLowerCase() + ' fc-widget-header',
426                     html : d.substring(0,3)
427                 });
428                 
429             }
430             ret[0].cls += ' fc-first';
431             ret[6].cls += ' fc-last';
432             return ret;
433         };
434         var cal_cell = function(n) {
435             return  {
436                 tag: 'td',
437                 cls : 'fc-day fc-'+n + ' fc-widget-content', ///fc-other-month fc-past
438                 cn : [
439                     {
440                         cn : [
441                             {
442                                 cls: 'fc-day-number',
443                                 html: 'D'
444                             },
445                             {
446                                 cls: 'fc-day-content',
447                              
448                                 cn : [
449                                      {
450                                         style: 'position: relative;' // height: 17px;
451                                     }
452                                 ]
453                             }
454                             
455                             
456                         ]
457                     }
458                 ]
459                 
460             }
461         };
462         var cal_rows = function() {
463             
464             var ret = []
465             for (var r = 0; r < 6; r++) {
466                 var row= {
467                     tag : 'tr',
468                     cls : 'fc-week',
469                     cn : []
470                 };
471                 
472                 for (var i =0; i < Date.dayNames.length; i++) {
473                     var d = Date.dayNames[i];
474                     row.cn.push(cal_cell(d.substring(0,3).toLowerCase()));
475
476                 }
477                 row.cn[0].cls+=' fc-first';
478                 row.cn[0].cn[0].style = 'min-height:90px';
479                 row.cn[6].cls+=' fc-last';
480                 ret.push(row);
481                 
482             }
483             ret[0].cls += ' fc-first';
484             ret[4].cls += ' fc-prev-last';
485             ret[5].cls += ' fc-last';
486             return ret;
487             
488         };
489         
490         var cal_table = {
491             tag: 'table',
492             cls: 'fc-border-separate',
493             style : 'width:100%',
494             cellspacing  : 0,
495             cn : [
496                 { 
497                     tag: 'thead',
498                     cn : [
499                         { 
500                             tag: 'tr',
501                             cls : 'fc-first fc-last',
502                             cn : cal_heads()
503                         }
504                     ]
505                 },
506                 { 
507                     tag: 'tbody',
508                     cn : cal_rows()
509                 }
510                   
511             ]
512         };
513          
514          var cfg = {
515             cls : 'fc fc-ltr',
516             cn : [
517                 header,
518                 {
519                     cls : 'fc-content',
520                     style : "position: relative;",
521                     cn : [
522                         {
523                             cls : 'fc-view fc-view-month fc-grid',
524                             style : 'position: relative',
525                             unselectable : 'on',
526                             cn : [
527                                 {
528                                     cls : 'fc-event-container',
529                                     style : 'position:absolute;z-index:8;top:0;left:0;'
530                                 },
531                                 cal_table
532                             ]
533                         }
534                     ]
535     
536                 }
537            ] 
538             
539         };
540         
541          
542         
543         return cfg;
544     },
545     
546     
547     initEvents : function()
548     {
549         if(!this.store){
550             throw "can not find store for calendar";
551         }
552         
553         this.store = Roo.factory(this.store, Roo.data);
554         this.store.on('load', this.onLoad, this);
555         
556         this.resize();
557         this.cells = this.el.select('.fc-day',true);
558         
559         this.textNodes = this.el.query('.fc-day-number');
560         this.cells.addClassOnOver('fc-state-hover');
561         
562         this.el.select('.fc-button-prev',true).on('click', this.showPrevMonth, this);
563         this.el.select('.fc-button-next',true).on('click', this.showNextMonth, this);
564         this.el.select('.fc-button-today',true).on('click', this.showToday, this);
565         this.el.select('.fc-button',true).addClassOnOver('fc-state-hover');
566         
567         this.on('monthchange', this.onMonthChange, this);
568         
569         this.update(new Date().clearTime());
570     },
571     
572     resize : function() {
573         var sz  = this.el.getSize();
574         
575         this.el.select('.fc-day-header',true).setWidth(sz.width / 7);
576         this.el.select('.fc-day-content div',true).setHeight(34);
577     },
578     
579     
580     // private
581     showPrevMonth : function(e){
582         this.update(this.activeDate.add("mo", -1));
583     },
584     showToday : function(e){
585         this.update(new Date().clearTime());
586     },
587     // private
588     showNextMonth : function(e){
589         this.update(this.activeDate.add("mo", 1));
590     },
591
592     // private
593     showPrevYear : function(){
594         this.update(this.activeDate.add("y", -1));
595     },
596
597     // private
598     showNextYear : function(){
599         this.update(this.activeDate.add("y", 1));
600     },
601
602     
603    // private
604     update : function(date)
605     {
606         var vd = this.activeDate;
607         this.activeDate = date;
608 //        if(vd && this.el){
609 //            var t = date.getTime();
610 //            if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
611 //                Roo.log('using add remove');
612 //                
613 //                this.fireEvent('monthchange', this, date);
614 //                
615 //                this.cells.removeClass("fc-state-highlight");
616 //                this.cells.each(function(c){
617 //                   if(c.dateValue == t){
618 //                       c.addClass("fc-state-highlight");
619 //                       setTimeout(function(){
620 //                            try{c.dom.firstChild.focus();}catch(e){}
621 //                       }, 50);
622 //                       return false;
623 //                   }
624 //                   return true;
625 //                });
626 //                return;
627 //            }
628 //        }
629         
630         var days = date.getDaysInMonth();
631         
632         var firstOfMonth = date.getFirstDateOfMonth();
633         var startingPos = firstOfMonth.getDay()-this.startDay;
634         
635         if(startingPos < this.startDay){
636             startingPos += 7;
637         }
638         
639         var pm = date.add("mo", -1);
640         var prevStart = pm.getDaysInMonth()-startingPos;
641 //        
642         this.cells = this.el.select('.fc-day',true);
643         this.textNodes = this.el.query('.fc-day-number');
644         this.cells.addClassOnOver('fc-state-hover');
645         
646         var cells = this.cells.elements;
647         var textEls = this.textNodes;
648         
649         Roo.each(cells, function(cell){
650             cell.removeClass([ 'fc-past', 'fc-other-month', 'fc-future', 'fc-state-highlight', 'fc-state-disabled']);
651         });
652         
653         days += startingPos;
654
655         // convert everything to numbers so it's fast
656         var day = 86400000;
657         var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
658         var today = new Date().clearTime().getTime();
659         var sel = date.clearTime().getTime();
660         var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
661         var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
662         var ddMatch = this.disabledDatesRE;
663         var ddText = this.disabledDatesText;
664         var ddays = this.disabledDays ? this.disabledDays.join("") : false;
665         var ddaysText = this.disabledDaysText;
666         var format = this.format;
667         
668         var setCellClass = function(cal, cell){
669             cell.title = "";
670             var t = d.getTime();
671             
672             cell.dateValue = t;
673             if(t == today){
674                 cell.className += " fc-today";
675                 cell.className += " fc-state-highlight";
676                 cell.title = cal.todayText;
677             }
678             if(t == sel){
679                 // disable highlight in other month..
680                 //cell.className += " fc-state-highlight";
681                 
682             }
683             // disabling
684             if(t < min) {
685                 cell.className = " fc-state-disabled";
686                 cell.title = cal.minText;
687                 return;
688             }
689             if(t > max) {
690                 cell.className = " fc-state-disabled";
691                 cell.title = cal.maxText;
692                 return;
693             }
694             if(ddays){
695                 if(ddays.indexOf(d.getDay()) != -1){
696                     cell.title = ddaysText;
697                     cell.className = " fc-state-disabled";
698                 }
699             }
700             if(ddMatch && format){
701                 var fvalue = d.dateFormat(format);
702                 if(ddMatch.test(fvalue)){
703                     cell.title = ddText.replace("%0", fvalue);
704                     cell.className = " fc-state-disabled";
705                 }
706             }
707             
708             if (!cell.initialClassName) {
709                 cell.initialClassName = cell.dom.className;
710             }
711             
712             cell.dom.className = cell.initialClassName  + ' ' +  cell.className;
713         };
714
715         var i = 0;
716         
717         for(; i < startingPos; i++) {
718             textEls[i].innerHTML = (++prevStart);
719             d.setDate(d.getDate()+1);
720             
721             cells[i].className = "fc-past fc-other-month";
722             setCellClass(this, cells[i]);
723         }
724         
725         var intDay = 0;
726         
727         for(; i < days; i++){
728             intDay = i - startingPos + 1;
729             textEls[i].innerHTML = (intDay);
730             d.setDate(d.getDate()+1);
731             
732             cells[i].className = ''; // "x-date-active";
733             setCellClass(this, cells[i]);
734         }
735         var extraDays = 0;
736         
737         for(; i < 42; i++) {
738             textEls[i].innerHTML = (++extraDays);
739             d.setDate(d.getDate()+1);
740             
741             cells[i].className = "fc-future fc-other-month";
742             setCellClass(this, cells[i]);
743         }
744         
745         this.el.select('.fc-header-title h2',true).update(Date.monthNames[date.getMonth()] + " " + date.getFullYear());
746         
747         var totalRows = Math.ceil((date.getDaysInMonth() + date.getFirstDateOfMonth().getDay()) / 7);
748         
749         this.el.select('tr.fc-week.fc-prev-last',true).removeClass('fc-last');
750         this.el.select('tr.fc-week.fc-next-last',true).addClass('fc-last').show();
751         
752         if(totalRows != 6){
753             this.el.select('tr.fc-week.fc-last',true).removeClass('fc-last').addClass('fc-next-last').hide();
754             this.el.select('tr.fc-week.fc-prev-last',true).addClass('fc-last');
755         }
756         
757         this.fireEvent('monthchange', this, date);
758         
759         
760         /*
761         if(!this.internalRender){
762             var main = this.el.dom.firstChild;
763             var w = main.offsetWidth;
764             this.el.setWidth(w + this.el.getBorderWidth("lr"));
765             Roo.fly(main).setWidth(w);
766             this.internalRender = true;
767             // opera does not respect the auto grow header center column
768             // then, after it gets a width opera refuses to recalculate
769             // without a second pass
770             if(Roo.isOpera && !this.secondPass){
771                 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
772                 this.secondPass = true;
773                 this.update.defer(10, this, [date]);
774             }
775         }
776         */
777         
778     },
779     
780     findCell : function(dt) {
781         dt = dt.clearTime().getTime();
782         var ret = false;
783         this.cells.each(function(c){
784             //Roo.log("check " +c.dateValue + '?=' + dt);
785             if(c.dateValue == dt){
786                 ret = c;
787                 return false;
788             }
789             return true;
790         });
791         
792         return ret;
793     },
794     
795     findCells : function(ev) {
796         var s = ev.start.clone().clearTime().getTime();
797         var e= ev.end.clone().clearTime().getTime();
798         var ret = [];
799         this.cells.each(function(c){
800             //Roo.log("check " +c.dateValue + '<' + e + ' > ' + s);
801             
802             if(c.dateValue > e){
803                 return ;
804             }
805             if(c.dateValue < s){
806                 return ;
807             }
808             ret.push(c);
809         });
810         
811         return ret;    
812     },
813     
814     findBestRow: function(cells)
815     {
816         var ret = 0;
817         
818         for (var i =0 ; i < cells.length;i++) {
819             ret  = Math.max(cells[i].rows || 0,ret);
820         }
821         return ret;
822         
823     },
824     
825     
826     addItem : function(ev)
827     {
828         // look for vertical location slot in
829         var cells = this.findCells(ev);
830         
831         ev.row = this.findBestRow(cells);
832         
833         // work out the location.
834         
835         var crow = false;
836         var rows = [];
837         for(var i =0; i < cells.length; i++) {
838             if (!crow) {
839                 crow = {
840                     start : cells[i],
841                     end :  cells[i]
842                 };
843                 continue;
844             }
845             if (crow.start.getY() == cells[i].getY()) {
846                 // on same row.
847                 crow.end = cells[i];
848                 continue;
849             }
850             // different row.
851             rows.push(crow);
852             crow = {
853                 start: cells[i],
854                 end : cells[i]
855             };
856             
857         }
858         
859         rows.push(crow);
860         ev.els = [];
861         ev.rows = rows;
862         ev.cells = cells;
863         for (var i = 0; i < cells.length;i++) {
864             cells[i].rows = Math.max(cells[i].rows || 0 , ev.row + 1 );
865             
866         }
867         
868         this.calevents.push(ev);
869     },
870     
871     clearEvents: function() {
872         
873         if(!this.calevents){
874             return;
875         }
876         
877         Roo.each(this.cells.elements, function(c){
878             c.rows = 0;
879         });
880         
881         Roo.each(this.calevents, function(e) {
882             Roo.each(e.els, function(el) {
883                 el.un('mouseenter' ,this.onEventEnter, this);
884                 el.un('mouseleave' ,this.onEventLeave, this);
885                 el.remove();
886             },this);
887         },this);
888         
889     },
890     
891     renderEvents: function()
892     {   
893         // first make sure there is enough space..
894         
895         this.cells.each(function(c) {
896         
897             c.select('.fc-day-content div',true).first().setHeight(Math.max(34, c.rows * 20));
898         });
899         
900         for (var e = 0; e < this.calevents.length; e++) {
901             var ev = this.calevents[e];
902             var cells = ev.cells;
903             var rows = ev.rows;
904             
905             for(var i =0; i < rows.length; i++) {
906                 
907                  
908                 // how many rows should it span..
909                 
910                 var  cfg = {
911                     cls : 'roo-dynamic fc-event fc-event-hori fc-event-draggable ui-draggable',
912                     style : 'position: absolute', // left: 387px; width: 121px; top: 359px;
913                     
914                     unselectable : "on",
915                     cn : [
916                         {
917                             cls: 'fc-event-inner',
918                             cn : [
919                                 {
920                                   tag:'span',
921                                   cls: 'fc-event-time',
922                                   html : cells.length > 1 ? '' : ev.time
923                                 },
924                                 {
925                                   tag:'span',
926                                   cls: 'fc-event-title',
927                                   html : String.format('{0}', ev.title)
928                                 }
929                                 
930                                 
931                             ]
932                         },
933                         {
934                             cls: 'ui-resizable-handle ui-resizable-e',
935                             html : '&nbsp;&nbsp;&nbsp'
936                         }
937                         
938                     ]
939                 };
940                 if (i == 0) {
941                     cfg.cls += ' fc-event-start';
942                 }
943                 if ((i+1) == rows.length) {
944                     cfg.cls += ' fc-event-end';
945                 }
946                 
947                 var ctr = this.el.select('.fc-event-container',true).first();
948                 var cg = ctr.createChild(cfg);
949                 
950                 cg.on('mouseenter' ,this.onEventEnter, this, ev);
951                 cg.on('mouseleave' ,this.onEventLeave, this, ev);
952                 cg.on('click', this.onEventClick, this, ev);
953                 
954                 ev.els.push(cg);
955                 
956                 var sbox = rows[i].start.select('.fc-day-content',true).first().getBox();
957                 var ebox = rows[i].end.select('.fc-day-content',true).first().getBox();
958                 //Roo.log(cg);
959                 cg.setXY([sbox.x +2, sbox.y +(ev.row * 20)]);    
960                 cg.setWidth(ebox.right - sbox.x -2);
961             }
962             
963             
964         }
965         
966     },
967     
968     onEventEnter: function (e, el,event,d) {
969         this.fireEvent('evententer', this, el, event);
970     },
971     
972     onEventLeave: function (e, el,event,d) {
973         this.fireEvent('eventleave', this, el, event);
974     },
975     
976     onEventClick: function (e, el,event,d) {
977         this.fireEvent('eventclick', this, el, event);
978     },
979     
980     onMonthChange: function () {
981         this.store.load();
982     },
983     
984     onLoad: function () {
985         
986         this.clearEvents();
987         Roo.log('calendar onload');
988 //        
989         this.calevents = [];
990         var cal = this;
991         if(this.store.getCount() > 0){
992             this.store.data.each(function(d){
993                cal.addItem({
994                     id : d.data.id,
995                     start: new Date(d.data.start_dt),
996                     end : new Date(d.data.end_dt),
997                     time : d.data.start_time,
998                     title : d.data.title,
999                     description : d.data.description,
1000                     venue : d.data.venue
1001                 });
1002             });
1003         }
1004         
1005         this.renderEvents();
1006     }
1007 });
1008
1009  
1010  /*
1011  * - LGPL
1012  *
1013  * based on jquery fullcalendar
1014  * 
1015  */
1016
1017
1018 /**
1019  * @class Roo.Calendar
1020  * @extends Roo.Component
1021  * Bootstrap Calendar class
1022     
1023  * @constructor
1024  * Create a new Container
1025  * @param {Object} config The config object
1026  */
1027
1028 Roo.CalendarPanel = function(config){
1029     
1030     Roo.log("cal panel ctr");
1031   
1032     this.wrapper = Roo.DomHelper.append(document.body, // wrapper for IE7 strict & safari scroll issue
1033         {tag: "div", cls: "x-layout-grid-wrapper x-layout-inactive-content"}, true);
1034         
1035     //this.wrapper.dom.appendChild(grid.getGridEl().dom);
1036     
1037     Roo.CalendarPanel.superclass.constructor.call(this, this.wrapper, config);
1038     
1039     Roo.log(this.el);
1040     
1041     if(this.toolbar){
1042         this.toolbar.el.insertBefore(this.wrapper.dom.firstChild);
1043     }
1044     // xtype created footer. - not sure if will work as we normally have to render first..
1045     if (this.footer && !this.footer.el && this.footer.xtype) {
1046         
1047         //this.footer.container = this.grid.getView().getFooterPanel(true);
1048         //this.footer.dataSource = this.grid.dataSource;
1049         //this.footer = Roo.factory(this.footer, Roo);
1050         
1051     }
1052     
1053     this.on('activate', function()
1054     {
1055         Roo.log('activate');
1056          
1057         //console.log('render tree');
1058         this.render();
1059     },this);
1060     
1061     this.addEvents({
1062         /**
1063              * @event select
1064              * Fires when a date is selected
1065              * @param {DatePicker} this
1066              * @param {Date} date The selected date
1067              */
1068         'select': true,
1069         /**
1070              * @event monthchange
1071              * Fires when the displayed month changes 
1072              * @param {DatePicker} this
1073              * @param {Date} date The selected month
1074              */
1075         'monthchange': true,
1076         /**
1077              * @event evententer
1078              * Fires when mouse over an event
1079              * @param {Calendar} this
1080              * @param {event} Event
1081              */
1082         'evententer': true,
1083         /**
1084              * @event eventleave
1085              * Fires when the mouse leaves an
1086              * @param {Calendar} this
1087              * @param {event}
1088              */
1089         'eventleave': true,
1090         /**
1091              * @event eventclick
1092              * Fires when the mouse click an
1093              * @param {Calendar} this
1094              * @param {event}
1095              */
1096         'eventclick': true
1097         
1098     });
1099     
1100     //this.grid = grid;
1101     //this.grid.getGridEl().replaceClass("x-layout-inactive-content", "x-layout-component-panel");
1102 };
1103
1104
1105 Roo.extend(Roo.CalendarPanel, Roo.ContentPanel, {
1106     getId : function(){
1107         return this.id;
1108     },
1109     /*
1110     setSize : function(width, height){
1111         if(!this.ignoreResize(width, height)){
1112             var grid = this.grid;
1113             var size = this.adjustForComponents(width, height);
1114             grid.getGridEl().setSize(size.width, size.height);
1115             grid.autoSize();
1116         }
1117     },
1118     
1119     beforeSlide : function(){
1120         this.grid.getView().scroller.clip();
1121     },
1122     
1123     afterSlide : function(){
1124         this.grid.getView().scroller.unclip();
1125     },
1126     */
1127     destroy : function(){
1128       //  this.grid.destroy();
1129        // delete this.grid;
1130         Roo.GridPanel.superclass.destroy.call(this);
1131          
1132     },
1133     render : function()
1134     {
1135         this.onRender(this.el, false)
1136     },
1137     
1138     onRender : function(ct, position)
1139     {
1140         if (this.rendered) {
1141             return;
1142         }
1143         this.rendered = true;
1144         
1145         Roo.log("render calendar");
1146         
1147         //Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
1148         
1149         
1150         var cfg = Roo.apply({},  this.getAutoCreate());
1151         cfg.id = Roo.id();
1152         
1153         // fill in the extra attributes 
1154         if (this.xattr && typeof(this.xattr) =='object') {
1155             for (var i in this.xattr) {
1156                 cfg[i] = this.xattr[i];
1157             }
1158         }
1159         
1160         if(this.dataId){
1161             cfg.dataId = this.dataId;
1162         }
1163         
1164         if (this.cls) {
1165             cfg.cls = (typeof(cfg.cls) == 'undefined') ? this.cls : cfg.cls + ' ' + this.cls;
1166         }
1167         
1168         if (this.style) { // fixme needs to support more complex style data.
1169             cfg.style = this.style;
1170         }
1171         
1172         if(this.name){
1173             cfg.name = this.name;
1174         }
1175         
1176         this.el = ct.createChild(cfg, position);
1177         
1178         if(this.tabIndex !== undefined){
1179             this.el.dom.setAttribute('tabIndex', this.tabIndex);
1180         }
1181         this.initEvents();
1182     },
1183     
1184     
1185     getAutoCreate : Roo.bootstrap.Calendar.prototype.getAutoCreate,
1186     
1187     initEvents : Roo.bootstrap.Calendar.prototype.initEvents 
1188     
1189     
1190 });
1191
1192
1193
1194 Roo.each([
1195     'getAutoCreate',
1196     'initEvents',
1197     'resize',
1198     'showPrevMonth',
1199     'showToday',
1200     'showNextMonth',
1201     'showPrevYear',
1202     'showNextYear',
1203     'update',
1204     'findCell',
1205     'findCells',
1206     'findBestRow',
1207     'addItem',
1208     'clearEvents',
1209     'renderEvents',
1210     'onEventEnter',
1211     'onEventLeave',
1212     'onEventClick',
1213     'onMonthChange',
1214     'onLoad'
1215
1216     
1217 ], function(p) {
1218     Roo.log('add' + p);
1219     Roo.CalendarPanel.prototype[p] = Roo.bootstrap.Calendar.prototype[p];
1220  
1221 });