1 /*global gettext, pgettext, get_format, quickElement, removeChildren, addEvent*/
3 calendar.js - Calendar functions by Adrian Holovaty
4 depends on core.js for utility functions like removeChildren or quickElement
9 // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
10 var CalendarNamespace = {
26 pgettext('one letter Sunday', 'S'),
27 pgettext('one letter Monday', 'M'),
28 pgettext('one letter Tuesday', 'T'),
29 pgettext('one letter Wednesday', 'W'),
30 pgettext('one letter Thursday', 'T'),
31 pgettext('one letter Friday', 'F'),
32 pgettext('one letter Saturday', 'S')
34 firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
35 isLeapYear: function(year) {
36 return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0));
38 getDaysInMonth: function(month, year) {
40 if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) {
43 else if (month === 4 || month === 6 || month === 9 || month === 11) {
46 else if (month === 2 && CalendarNamespace.isLeapYear(year)) {
54 draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999
55 var today = new Date();
56 var todayDay = today.getDate();
57 var todayMonth = today.getMonth() + 1;
58 var todayYear = today.getFullYear();
61 // Use UTC functions here because the date field does not contain time
62 // and using the UTC function variants prevent the local time offset
63 // from altering the date, specifically the day field. For example:
66 // var x = new Date('2013-10-02');
67 // var day = x.getDate();
70 // The day variable above will be 1 instead of 2 in, say, US Pacific time
72 var isSelectedMonth = false;
73 if (typeof selected !== 'undefined') {
74 isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month);
77 month = parseInt(month);
78 year = parseInt(year);
79 var calDiv = document.getElementById(div_id);
80 removeChildren(calDiv);
81 var calTable = document.createElement('table');
82 quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year);
83 var tableBody = quickElement('tbody', calTable);
85 // Draw days-of-week header
86 var tableRow = quickElement('tr', tableBody);
87 for (var i = 0; i < 7; i++) {
88 quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
91 var startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
92 var days = CalendarNamespace.getDaysInMonth(month, year);
96 // Draw blanks before first of month
97 tableRow = quickElement('tr', tableBody);
98 for (i = 0; i < startingPos; i++) {
99 nonDayCell = quickElement('td', tableRow, ' ');
100 nonDayCell.className = "nonday";
103 function calendarMonth(y, m) {
104 function onClick(e) {
106 callback(y, m, django.jQuery(this).text());
111 // Draw days of month
113 for (i = startingPos; currentDay <= days; i++) {
114 if (i % 7 === 0 && currentDay !== 1) {
115 tableRow = quickElement('tr', tableBody);
117 if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) {
118 todayClass = 'today';
123 // use UTC function; see above for explanation.
124 if (isSelectedMonth && currentDay === selected.getUTCDate()) {
125 if (todayClass !== '') {
128 todayClass += "selected";
131 var cell = quickElement('td', tableRow, '', 'class', todayClass);
132 var link = quickElement('a', cell, currentDay, 'href', '#');
133 addEvent(link, 'click', calendarMonth(year, month));
137 // Draw blanks after end of month (optional, but makes for valid code)
138 while (tableRow.childNodes.length < 7) {
139 nonDayCell = quickElement('td', tableRow, ' ');
140 nonDayCell.className = "nonday";
143 calDiv.appendChild(calTable);
147 // Calendar -- A calendar instance
148 function Calendar(div_id, callback, selected) {
149 // div_id (string) is the ID of the element in which the calendar will
151 // callback (string) is the name of a JavaScript function that will be
152 // called with the parameters (year, month, day) when a day in the
153 // calendar is clicked
154 this.div_id = div_id;
155 this.callback = callback;
156 this.today = new Date();
157 this.currentMonth = this.today.getMonth() + 1;
158 this.currentYear = this.today.getFullYear();
159 if (typeof selected !== 'undefined') {
160 this.selected = selected;
163 Calendar.prototype = {
164 drawCurrent: function() {
165 CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected);
167 drawDate: function(month, year, selected) {
168 this.currentMonth = month;
169 this.currentYear = year;
172 this.selected = selected;
177 drawPreviousMonth: function() {
178 if (this.currentMonth === 1) {
179 this.currentMonth = 12;
187 drawNextMonth: function() {
188 if (this.currentMonth === 12) {
189 this.currentMonth = 1;
197 drawPreviousYear: function() {
201 drawNextYear: function() {
206 window.Calendar = Calendar;
207 window.CalendarNamespace = CalendarNamespace;