4 * based on jquery fullcalendar
10 * @class Roo.bootstrap.Calendar
11 * @extends Roo.bootstrap.Component
12 * Bootstrap Calendar class
15 * Create a new Container
16 * @param {Object} config The config object
19 Roo.bootstrap.Calendar = function(config){
20 Roo.bootstrap.Calendar.superclass.constructor.call(this, config);
23 Roo.extend(Roo.bootstrap.Calendar, Roo.bootstrap.Component, {
27 getAutoCreate : function(){
30 fc_button = function(name, corner, style, content ) {
33 cls : 'fc-button fc-button-'+name+' fc-state-default ' +
35 'fc-corner-' + corner.split(' ').join(' fc-corner-') :
38 html : '<SPAN class="fc-text-'+style+ '">'+content +'</SPAN>',
53 cls : 'fc-header-left',
55 fc_button('prev', 'left', 'arrow', '‹' ),
56 fc_button('next', 'right', 'arrow', '›' ),
57 { tag: 'span', cls: 'fc-header-space' },
58 fc_button('today', 'left right', '', 'today' ), // neds state disabled..
66 cls : 'fc-header-center',
70 cls: 'fc-header-title',
81 cls : 'fc-header-right',
83 fc_button('month', 'left', '', 'month' ),
84 fc_button('week', '', '', 'week' ),
85 fc_button('day', 'right', '', 'day' )
97 var cal_heads = function() {
99 for (var i =0; i < Date.dayNames.length; i++) {
100 var d = Date.dayNames[i];
103 cls : 'fc-day-header fc-' + d.substring(0,3).toLowerCase() + ' fc-widget-header',
104 html : d.substring(0,3)
108 ret[0].cls += ' fc-first';
109 ret[6].cls += ' fc-last';
112 var cal_cell = function(n) {
115 cls : 'fc-day fc-'+n + ' fc-widget-content', ///fc-other-month fc-past
120 cls: 'fc-day-number',
124 cls: 'fc-day-content',
128 style: 'position: relative;' // height: 17px;
140 var cal_rows = function() {
142 for (var r = 0; r < 6; r++) {
149 for (var i =0; i < Date.dayNames.length; i++) {
150 var d = Date.dayNames[i];
151 row.cn.push(cal_cell(d.substring(0,3).toLowerCase()));
154 row.cn[0].cls+=' fc-first';
155 row.cn[0].cn[0].style = 'min-height:90px';
156 row.cn[6].cls+=' fc-last';
160 ret[0].cls += ' fc-first';
162 ret[5].cls += ' fc-last';
168 cls: 'fc-border-separate',
169 style : 'width:100%',
177 cls : 'fc-first fc-last',
196 style : "position: relative;",
199 cls : 'fc-view fc-view-month fc-grid',
200 style : 'position: relative',
204 cls : 'fc-event-container',
205 style : 'position:absolute;z-index:8;top:0;left:0;'
223 initEvents : function()
226 this.cells = this.el.query('.fc-day');
227 this.textNodes = this.el.query('.fc-day-number');
229 this.update(new Date());
236 resize : function() {
237 var sz = this.el.getSize();
239 this.el.select('.fc-day-header',true).setWidth(sz.width / 7);
240 this.el.select('.fc-day-content div',true).setHeight(34);
243 update : function(date)
245 var vd = this.activeDate;
246 this.activeDate = date;
248 var t = date.getTime();
249 if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
250 this.cells.removeClass("fc-state-highlight");
251 this.cells.each(function(c){
252 if(c.dom.firstChild.dateValue == t){
253 c.addClass("fc-state-highlight");
254 setTimeout(function(){
255 try{c.dom.firstChild.focus();}catch(e){}
265 var days = date.getDaysInMonth();
266 var firstOfMonth = date.getFirstDateOfMonth();
267 var startingPos = firstOfMonth.getDay()-this.startDay;
269 if(startingPos <= this.startDay){
273 var pm = date.add("mo", -1);
274 var prevStart = pm.getDaysInMonth()-startingPos;
276 var cells = this.cells.elements;
277 var textEls = this.textNodes;
280 // convert everything to numbers so it's fast
282 var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
283 var today = new Date().clearTime().getTime();
284 var sel = date.clearTime().getTime();
285 var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
286 var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
287 var ddMatch = this.disabledDatesRE;
288 var ddText = this.disabledDatesText;
289 var ddays = this.disabledDays ? this.disabledDays.join("") : false;
290 var ddaysText = this.disabledDaysText;
291 var format = this.format;
293 var setCellClass = function(cal, cell){
296 cell.firstChild.dateValue = t;
298 cell.className += " fc-today";
299 cell.title = cal.todayText;
302 cell.className += " fc-state-highlight";
303 setTimeout(function(){
304 try{cell.firstChild.focus();}catch(e){}
309 cell.className = " fc-state-disabled";
310 cell.title = cal.minText;
314 cell.className = " fc-state-disabled";
315 cell.title = cal.maxText;
319 if(ddays.indexOf(d.getDay()) != -1){
320 cell.title = ddaysText;
321 cell.className = " fc-state-disabled";
324 if(ddMatch && format){
325 var fvalue = d.dateFormat(format);
326 if(ddMatch.test(fvalue)){
327 cell.title = ddText.replace("%0", fvalue);
328 cell.className = " fc-state-disabled";
334 for(; i < startingPos; i++) {
335 textEls[i].innerHTML = (++prevStart);
336 d.setDate(d.getDate()+1);
337 cells[i].className = "x-date-prevday";
338 setCellClass(this, cells[i]);
340 for(; i < days; i++){
341 intDay = i - startingPos + 1;
342 textEls[i].innerHTML = (intDay);
343 d.setDate(d.getDate()+1);
344 cells[i].className = "x-date-active";
345 setCellClass(this, cells[i]);
349 textEls[i].innerHTML = (++extraDays);
350 d.setDate(d.getDate()+1);
351 cells[i].className = "x-date-nextday";
352 setCellClass(this, cells[i]);
355 this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());
356 this.fireEvent('monthchange', this, date);
358 if(!this.internalRender){
359 var main = this.el.dom.firstChild;
360 var w = main.offsetWidth;
361 this.el.setWidth(w + this.el.getBorderWidth("lr"));
362 Roo.fly(main).setWidth(w);
363 this.internalRender = true;
364 // opera does not respect the auto grow header center column
365 // then, after it gets a width opera refuses to recalculate
366 // without a second pass
367 if(Roo.isOpera && !this.secondPass){
368 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
369 this.secondPass = true;
370 this.update.defer(10, this, [date]);