209 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			209 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
/*global gettext, pgettext, get_format, quickElement, removeChildren*/
 | 
						|
/*
 | 
						|
calendar.js - Calendar functions by Adrian Holovaty
 | 
						|
depends on core.js for utility functions like removeChildren or quickElement
 | 
						|
*/
 | 
						|
 | 
						|
(function() {
 | 
						|
    'use strict';
 | 
						|
    // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
 | 
						|
    var CalendarNamespace = {
 | 
						|
        monthsOfYear: [
 | 
						|
            gettext('January'),
 | 
						|
            gettext('February'),
 | 
						|
            gettext('March'),
 | 
						|
            gettext('April'),
 | 
						|
            gettext('May'),
 | 
						|
            gettext('June'),
 | 
						|
            gettext('July'),
 | 
						|
            gettext('August'),
 | 
						|
            gettext('September'),
 | 
						|
            gettext('October'),
 | 
						|
            gettext('November'),
 | 
						|
            gettext('December')
 | 
						|
        ],
 | 
						|
        daysOfWeek: [
 | 
						|
            pgettext('one letter Sunday', 'S'),
 | 
						|
            pgettext('one letter Monday', 'M'),
 | 
						|
            pgettext('one letter Tuesday', 'T'),
 | 
						|
            pgettext('one letter Wednesday', 'W'),
 | 
						|
            pgettext('one letter Thursday', 'T'),
 | 
						|
            pgettext('one letter Friday', 'F'),
 | 
						|
            pgettext('one letter Saturday', 'S')
 | 
						|
        ],
 | 
						|
        firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
 | 
						|
        isLeapYear: function(year) {
 | 
						|
            return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0));
 | 
						|
        },
 | 
						|
        getDaysInMonth: function(month, year) {
 | 
						|
            var days;
 | 
						|
            if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) {
 | 
						|
                days = 31;
 | 
						|
            }
 | 
						|
            else if (month === 4 || month === 6 || month === 9 || month === 11) {
 | 
						|
                days = 30;
 | 
						|
            }
 | 
						|
            else if (month === 2 && CalendarNamespace.isLeapYear(year)) {
 | 
						|
                days = 29;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                days = 28;
 | 
						|
            }
 | 
						|
            return days;
 | 
						|
        },
 | 
						|
        draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999
 | 
						|
            var today = new Date();
 | 
						|
            var todayDay = today.getDate();
 | 
						|
            var todayMonth = today.getMonth() + 1;
 | 
						|
            var todayYear = today.getFullYear();
 | 
						|
            var todayClass = '';
 | 
						|
 | 
						|
            // Use UTC functions here because the date field does not contain time
 | 
						|
            // and using the UTC function variants prevent the local time offset
 | 
						|
            // from altering the date, specifically the day field.  For example:
 | 
						|
            //
 | 
						|
            // ```
 | 
						|
            // var x = new Date('2013-10-02');
 | 
						|
            // var day = x.getDate();
 | 
						|
            // ```
 | 
						|
            //
 | 
						|
            // The day variable above will be 1 instead of 2 in, say, US Pacific time
 | 
						|
            // zone.
 | 
						|
            var isSelectedMonth = false;
 | 
						|
            if (typeof selected !== 'undefined') {
 | 
						|
                isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month);
 | 
						|
            }
 | 
						|
 | 
						|
            month = parseInt(month);
 | 
						|
            year = parseInt(year);
 | 
						|
            var calDiv = document.getElementById(div_id);
 | 
						|
            removeChildren(calDiv);
 | 
						|
            var calTable = document.createElement('table');
 | 
						|
            quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year);
 | 
						|
            var tableBody = quickElement('tbody', calTable);
 | 
						|
 | 
						|
            // Draw days-of-week header
 | 
						|
            var tableRow = quickElement('tr', tableBody);
 | 
						|
            for (var i = 0; i < 7; i++) {
 | 
						|
                quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
 | 
						|
            }
 | 
						|
 | 
						|
            var startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
 | 
						|
            var days = CalendarNamespace.getDaysInMonth(month, year);
 | 
						|
 | 
						|
            var nonDayCell;
 | 
						|
 | 
						|
            // Draw blanks before first of month
 | 
						|
            tableRow = quickElement('tr', tableBody);
 | 
						|
            for (i = 0; i < startingPos; i++) {
 | 
						|
                nonDayCell = quickElement('td', tableRow, ' ');
 | 
						|
                nonDayCell.className = "nonday";
 | 
						|
            }
 | 
						|
 | 
						|
            function calendarMonth(y, m) {
 | 
						|
                function onClick(e) {
 | 
						|
                    e.preventDefault();
 | 
						|
                    callback(y, m, this.textContent);
 | 
						|
                }
 | 
						|
                return onClick;
 | 
						|
            }
 | 
						|
 | 
						|
            // Draw days of month
 | 
						|
            var currentDay = 1;
 | 
						|
            for (i = startingPos; currentDay <= days; i++) {
 | 
						|
                if (i % 7 === 0 && currentDay !== 1) {
 | 
						|
                    tableRow = quickElement('tr', tableBody);
 | 
						|
                }
 | 
						|
                if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) {
 | 
						|
                    todayClass = 'today';
 | 
						|
                } else {
 | 
						|
                    todayClass = '';
 | 
						|
                }
 | 
						|
 | 
						|
                // use UTC function; see above for explanation.
 | 
						|
                if (isSelectedMonth && currentDay === selected.getUTCDate()) {
 | 
						|
                    if (todayClass !== '') {
 | 
						|
                        todayClass += " ";
 | 
						|
                    }
 | 
						|
                    todayClass += "selected";
 | 
						|
                }
 | 
						|
 | 
						|
                var cell = quickElement('td', tableRow, '', 'class', todayClass);
 | 
						|
                var link = quickElement('a', cell, currentDay, 'href', '#');
 | 
						|
                link.addEventListener('click', calendarMonth(year, month));
 | 
						|
                currentDay++;
 | 
						|
            }
 | 
						|
 | 
						|
            // Draw blanks after end of month (optional, but makes for valid code)
 | 
						|
            while (tableRow.childNodes.length < 7) {
 | 
						|
                nonDayCell = quickElement('td', tableRow, ' ');
 | 
						|
                nonDayCell.className = "nonday";
 | 
						|
            }
 | 
						|
 | 
						|
            calDiv.appendChild(calTable);
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    // Calendar -- A calendar instance
 | 
						|
    function Calendar(div_id, callback, selected) {
 | 
						|
        // div_id (string) is the ID of the element in which the calendar will
 | 
						|
        //     be displayed
 | 
						|
        // callback (string) is the name of a JavaScript function that will be
 | 
						|
        //     called with the parameters (year, month, day) when a day in the
 | 
						|
        //     calendar is clicked
 | 
						|
        this.div_id = div_id;
 | 
						|
        this.callback = callback;
 | 
						|
        this.today = new Date();
 | 
						|
        this.currentMonth = this.today.getMonth() + 1;
 | 
						|
        this.currentYear = this.today.getFullYear();
 | 
						|
        if (typeof selected !== 'undefined') {
 | 
						|
            this.selected = selected;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    Calendar.prototype = {
 | 
						|
        drawCurrent: function() {
 | 
						|
            CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected);
 | 
						|
        },
 | 
						|
        drawDate: function(month, year, selected) {
 | 
						|
            this.currentMonth = month;
 | 
						|
            this.currentYear = year;
 | 
						|
 | 
						|
            if(selected) {
 | 
						|
                this.selected = selected;
 | 
						|
            }
 | 
						|
 | 
						|
            this.drawCurrent();
 | 
						|
        },
 | 
						|
        drawPreviousMonth: function() {
 | 
						|
            if (this.currentMonth === 1) {
 | 
						|
                this.currentMonth = 12;
 | 
						|
                this.currentYear--;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                this.currentMonth--;
 | 
						|
            }
 | 
						|
            this.drawCurrent();
 | 
						|
        },
 | 
						|
        drawNextMonth: function() {
 | 
						|
            if (this.currentMonth === 12) {
 | 
						|
                this.currentMonth = 1;
 | 
						|
                this.currentYear++;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                this.currentMonth++;
 | 
						|
            }
 | 
						|
            this.drawCurrent();
 | 
						|
        },
 | 
						|
        drawPreviousYear: function() {
 | 
						|
            this.currentYear--;
 | 
						|
            this.drawCurrent();
 | 
						|
        },
 | 
						|
        drawNextYear: function() {
 | 
						|
            this.currentYear++;
 | 
						|
            this.drawCurrent();
 | 
						|
        }
 | 
						|
    };
 | 
						|
    window.Calendar = Calendar;
 | 
						|
    window.CalendarNamespace = CalendarNamespace;
 | 
						|
})();
 |