/* RSence * Copyright 2009 Riassence Inc. * http://riassence.com/ * * You should have received a copy of the GNU General Public License along * with this software package. If not, contact licensing@riassence.com */ /*** = Description ** Use HCalendar to display a month calendar that displays days as columns ** and weeks as rows. Its value is a date/time number specified in seconds ** since or before epoch (1970-01-01 00:00:00 UTC). ***/ HCalendar = HControl.extend({ componentName: 'calendar', weekdays_localized: ['Wk','Mon','Tue','Wed','Thu','Fri','Sat','Sun'], defaultEvents: { mouseWheel: true }, /** = Description * Calls HCalendar#nextMonth or HCalendar#prevMonth based on delta * of mouseWheel. * **/ mouseWheel: function(_delta){ if ( _delta < 0 ) { this.nextMonth(); } else { this.prevMonth(); } }, /** = Description * Refreshes weekdays. * **/ refreshLabel: function(){ if(!this['markupElemIds']){ return; } var _weekdays_localized = this.weekdays_localized, _weekdays_width = Math.floor(this.rect.width/_weekdays_localized.length), _weekdays_html = [], i = 0, _weekdays_html_pre = ['
'], _weekdays_html_suf = '
'; for(;i<_weekdays_localized.length;i++){ _weekdays_html.push([ _weekdays_html_pre.join(i*_weekdays_width), _weekdays_localized[i], _weekdays_html_suf ].join('') ); } ELEM.setHTML(this.markupElemIds.label, _weekdays_html.join('')); }, /** = Description * Checks the date range for the month which the date given as input belongs. * * = Parameters * +_date+:: A Date instance to check date range from * * = Returns * Array of [0] first week's date and [1] last week's date. * **/ calendarDateRange: function(_date){ var _date_begin = this.firstDateOfMonth(_date), _date_end = this.lastDateOfMonth(_date), _firstWeeksDate = this.firstDateOfWeek(_date_begin), _lastWeeksDate = this.lastDateOfWeek(_date_end), _week_begin = this.week(_firstWeeksDate), _week_end = this.week(_lastWeeksDate), _weeks = _week_end-_week_begin; if((_weeks===5) && (_firstWeeksDate.getDate() !== 1)){ _lastWeeksDate = new Date( _lastWeeksDate.getTime() + this.msWeek ); } else if((_weeks===5) && (_firstWeeksDate.getDate() === 1)){ _firstWeeksDate = new Date( _firstWeeksDate.getTime() - this.msWeek ); } else if(_weeks===4){ _firstWeeksDate = new Date( _firstWeeksDate.getTime() - this.msWeek ); _lastWeeksDate = new Date( _lastWeeksDate.getTime() + this.msWeek ); } return [ _firstWeeksDate, _lastWeeksDate ]; }, /** = Description * Refreshes the calendar. * **/ refreshValue: function(){ var _date = this.date(); this.drawCalendar(_date); }, /** = Description * Draws the next month on calendar. * **/ nextMonth: function(){ var _date = new Date( this.viewMonth[0], this.viewMonth[1]+1, 1 ); this.drawCalendar( new Date(_date.getTime() - this.tzMs(_date)) ); }, /** = Description * Draws the previous month on calendar. * **/ prevMonth: function(){ var _date = new Date( this.viewMonth[0], this.viewMonth[1]-1, 1 ); this.drawCalendar( new Date(_date.getTime() - this.tzMs(_date)) ); }, viewMonth: [1970,0], /** = Description * Draws the calendar with the date open given as input. * * = Parameters * +_date+:: The date on which calendar UI is opened at. * **/ drawCalendar: function(_date){ _date = (_date instanceof Date)?_date:this.date(); var _calendarDateRange = this.calendarDateRange(_date), _monthFirst = this.firstDateOfMonth(_date), _monthLast = this.lastDateOfMonth(_date), _firstDate = _calendarDateRange[0], _lastDate = _calendarDateRange[1], _column_count = this.weekdays_localized.length, _column_width = Math.floor((this.rect.width-1)/_column_count), _row_height = Math.floor((this.rect.height-1-35)/6), _week_html_pre = ['
'], _week_html_suf = '
', _col_html_pre = [''], _col_html_suf = '', _col_week_pre = '
', _col_week_suf = '
', _month_html = [], _week_html, _col_html, _row = 0, _col, _colMs, _colSecs, _colDate, _extraCssClass; for(; _row<6; _row++){ _week_html = []; for(_col = 0; _col<8; _col++){ _colDate = new Date(_firstDate.getTime()+((_row*this.msWeek)+((_col-1)*this.msDay))); _colMs = _colDate.getTime(); if(_col===0){ _col_html = [ _col_week_pre, this.week(_colDate), _col_week_suf ].join(''); } else { _colSecs = Math.round(_colMs/1000); if((this.value >= _colSecs) && (this.value < (_colSecs+86400))){ _extraCssClass = '_'+'sel'; } else{ _extraCssClass = (_colDate<_monthFirst || _colDate > _monthLast)?'_'+'no':'_'+'yes'; } _col_html = [ _col_html_pre[0], _colSecs, _col_html_pre[1], _extraCssClass, _col_html_pre[2], (_col*_column_width), _col_html_pre[3], this.mday(_colDate), _col_html_suf ].join(''); } _week_html.push(_col_html); } _month_html.push([ _week_html_pre.join(_row*_row_height), _week_html.join(''), _week_html_suf ].join('') ); } ELEM.setHTML(this.markupElemIds.value, _month_html.join('')); ELEM.setHTML(this.markupElemIds.state, this.monthName(_date)+' '+this.year(_date)); this.viewMonth = [_monthFirst.getUTCFullYear(),_monthFirst.getUTCMonth()]; } }); HCalendar.implement(HDateTime);