calendar.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*global gettext, get_format, quickElement, removeChildren*/
  2. /*
  3. calendar.js - Calendar functions by Adrian Holovaty
  4. depends on core.js for utility functions like removeChildren or quickElement
  5. */
  6. (function() {
  7. 'use strict';
  8. // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
  9. var CalendarNamespace = {
  10. monthsOfYear: gettext('January February March April May June July August September October November December').split(' '),
  11. daysOfWeek: gettext('S M T W T F S').split(' '),
  12. firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
  13. isLeapYear: function(year) {
  14. return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0));
  15. },
  16. getDaysInMonth: function(month, year) {
  17. var days;
  18. if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) {
  19. days = 31;
  20. }
  21. else if (month === 4 || month === 6 || month === 9 || month === 11) {
  22. days = 30;
  23. }
  24. else if (month === 2 && CalendarNamespace.isLeapYear(year)) {
  25. days = 29;
  26. }
  27. else {
  28. days = 28;
  29. }
  30. return days;
  31. },
  32. draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999
  33. var today = new Date();
  34. var todayDay = today.getDate();
  35. var todayMonth = today.getMonth() + 1;
  36. var todayYear = today.getFullYear();
  37. var todayClass = '';
  38. // Use UTC functions here because the date field does not contain time
  39. // and using the UTC function variants prevent the local time offset
  40. // from altering the date, specifically the day field. For example:
  41. //
  42. // ```
  43. // var x = new Date('2013-10-02');
  44. // var day = x.getDate();
  45. // ```
  46. //
  47. // The day variable above will be 1 instead of 2 in, say, US Pacific time
  48. // zone.
  49. var isSelectedMonth = false;
  50. if (typeof selected !== 'undefined') {
  51. isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month);
  52. }
  53. month = parseInt(month);
  54. year = parseInt(year);
  55. var calDiv = document.getElementById(div_id);
  56. removeChildren(calDiv);
  57. var calTable = document.createElement('table');
  58. quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year);
  59. var tableBody = quickElement('tbody', calTable);
  60. // Draw days-of-week header
  61. var tableRow = quickElement('tr', tableBody);
  62. for (var i = 0; i < 7; i++) {
  63. quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
  64. }
  65. var startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
  66. var days = CalendarNamespace.getDaysInMonth(month, year);
  67. var nonDayCell;
  68. // Draw blanks before first of month
  69. tableRow = quickElement('tr', tableBody);
  70. for (i = 0; i < startingPos; i++) {
  71. nonDayCell = quickElement('td', tableRow, ' ');
  72. nonDayCell.className = "nonday";
  73. }
  74. // Draw days of month
  75. var currentDay = 1;
  76. for (i = startingPos; currentDay <= days; i++) {
  77. if (i % 7 === 0 && currentDay !== 1) {
  78. tableRow = quickElement('tr', tableBody);
  79. }
  80. if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) {
  81. todayClass = 'today';
  82. } else {
  83. todayClass = '';
  84. }
  85. // use UTC function; see above for explanation.
  86. if (isSelectedMonth && currentDay === selected.getUTCDate()) {
  87. if (todayClass !== '') {
  88. todayClass += " ";
  89. }
  90. todayClass += "selected";
  91. }
  92. var cell = quickElement('td', tableRow, '', 'class', todayClass);
  93. quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '(' + year + ',' + month + ',' + currentDay + '));');
  94. currentDay++;
  95. }
  96. // Draw blanks after end of month (optional, but makes for valid code)
  97. while (tableRow.childNodes.length < 7) {
  98. nonDayCell = quickElement('td', tableRow, ' ');
  99. nonDayCell.className = "nonday";
  100. }
  101. calDiv.appendChild(calTable);
  102. }
  103. };
  104. // Calendar -- A calendar instance
  105. function Calendar(div_id, callback, selected) {
  106. // div_id (string) is the ID of the element in which the calendar will
  107. // be displayed
  108. // callback (string) is the name of a JavaScript function that will be
  109. // called with the parameters (year, month, day) when a day in the
  110. // calendar is clicked
  111. this.div_id = div_id;
  112. this.callback = callback;
  113. this.today = new Date();
  114. this.currentMonth = this.today.getMonth() + 1;
  115. this.currentYear = this.today.getFullYear();
  116. if (typeof selected !== 'undefined') {
  117. this.selected = selected;
  118. }
  119. }
  120. Calendar.prototype = {
  121. drawCurrent: function() {
  122. CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected);
  123. },
  124. drawDate: function(month, year, selected) {
  125. this.currentMonth = month;
  126. this.currentYear = year;
  127. if(selected) {
  128. this.selected = selected;
  129. }
  130. this.drawCurrent();
  131. },
  132. drawPreviousMonth: function() {
  133. if (this.currentMonth === 1) {
  134. this.currentMonth = 12;
  135. this.currentYear--;
  136. }
  137. else {
  138. this.currentMonth--;
  139. }
  140. this.drawCurrent();
  141. },
  142. drawNextMonth: function() {
  143. if (this.currentMonth === 12) {
  144. this.currentMonth = 1;
  145. this.currentYear++;
  146. }
  147. else {
  148. this.currentMonth++;
  149. }
  150. this.drawCurrent();
  151. },
  152. drawPreviousYear: function() {
  153. this.currentYear--;
  154. this.drawCurrent();
  155. },
  156. drawNextYear: function() {
  157. this.currentYear++;
  158. this.drawCurrent();
  159. }
  160. };
  161. window.Calendar = Calendar;
  162. })();