This repository has been archived by the owner on Sep 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
/
calendarYearBody.js
186 lines (156 loc) · 5.95 KB
/
calendarYearBody.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
(function() {
'use strict';
angular.module('material.components.datepicker')
.directive('mdCalendarYearBody', mdCalendarYearDirective);
/**
* Private component, consumed by the md-calendar-year, which separates the DOM construction logic
* and allows for the year view to use md-virtual-repeat.
*/
function mdCalendarYearDirective() {
return {
require: ['^^mdCalendar', '^^mdCalendarYear', 'mdCalendarYearBody'],
scope: { offset: '=mdYearOffset' },
controller: CalendarYearBodyCtrl,
controllerAs: 'mdYearBodyCtrl',
bindToController: true,
link: function(scope, element, attrs, controllers) {
var calendarCtrl = controllers[0];
var yearCtrl = controllers[1];
var yearBodyCtrl = controllers[2];
yearBodyCtrl.calendarCtrl = calendarCtrl;
yearBodyCtrl.yearCtrl = yearCtrl;
scope.$watch(function() { return yearBodyCtrl.offset; }, function(offset) {
if (angular.isNumber(offset)) {
yearBodyCtrl.generateContent();
}
});
}
};
}
/**
* Controller for a single year.
* @ngInject @constructor
*/
function CalendarYearBodyCtrl($element, $$mdDateUtil, $mdDateLocale) {
/**
* @final
* @type {!JQLite}
*/
this.$element = $element;
/** @final */
this.dateUtil = $$mdDateUtil;
/** @final */
this.dateLocale = $mdDateLocale;
/** @type {Object} Reference to the calendar. */
this.calendarCtrl = null;
/** @type {Object} Reference to the year view. */
this.yearCtrl = null;
/**
* Number of months from the start of the month "items" that the currently rendered month
* occurs. Set via angular data binding.
* @type {number|null}
*/
this.offset = null;
/**
* Date cell to focus after appending the month to the document.
* @type {HTMLElement}
*/
this.focusAfterAppend = null;
}
/** Generate and append the content for this year to the directive element. */
CalendarYearBodyCtrl.prototype.generateContent = function() {
var date = this.dateUtil.incrementYears(this.calendarCtrl.firstRenderableDate, this.offset);
this.$element
.empty()
.append(this.buildCalendarForYear(date));
if (this.focusAfterAppend) {
this.focusAfterAppend.classList.add(this.calendarCtrl.FOCUSED_DATE_CLASS);
this.focusAfterAppend = null;
}
};
/**
* Creates a single cell to contain a year in the calendar.
* @param {number} year Four-digit year.
* @param {number} month Zero-indexed month.
* @returns {HTMLElement}
*/
CalendarYearBodyCtrl.prototype.buildMonthCell = function(year, month) {
var calendarCtrl = this.calendarCtrl;
var yearCtrl = this.yearCtrl;
var cell = this.buildBlankCell();
// Represent this month/year as a date.
var firstOfMonth = new Date(year, month, 1);
cell.setAttribute('aria-label', this.dateLocale.monthFormatter(firstOfMonth));
cell.id = calendarCtrl.getDateId(firstOfMonth, 'year');
// Use `data-timestamp` attribute because IE10 does not support the `dataset` property.
cell.setAttribute('data-timestamp', String(firstOfMonth.getTime()));
if (this.dateUtil.isSameMonthAndYear(firstOfMonth, calendarCtrl.today)) {
cell.classList.add(calendarCtrl.TODAY_CLASS);
}
if (this.dateUtil.isValidDate(calendarCtrl.selectedDate) &&
this.dateUtil.isSameMonthAndYear(firstOfMonth, calendarCtrl.selectedDate)) {
cell.classList.add(calendarCtrl.SELECTED_DATE_CLASS);
cell.setAttribute('aria-selected', 'true');
}
var cellText = this.dateLocale.shortMonths[month];
if (this.dateUtil.isMonthWithinRange(
firstOfMonth, calendarCtrl.minDate, calendarCtrl.maxDate) &&
(!angular.isFunction(calendarCtrl.monthFilter) ||
calendarCtrl.monthFilter(firstOfMonth))) {
var selectionIndicator = document.createElement('span');
selectionIndicator.classList.add('md-calendar-date-selection-indicator');
selectionIndicator.textContent = cellText;
cell.appendChild(selectionIndicator);
cell.addEventListener('click', yearCtrl.cellClickHandler);
if (calendarCtrl.displayDate &&
this.dateUtil.isSameMonthAndYear(firstOfMonth, calendarCtrl.displayDate)) {
this.focusAfterAppend = cell;
}
} else {
cell.classList.add('md-calendar-date-disabled');
cell.textContent = cellText;
}
return cell;
};
/**
* Builds a blank cell.
* @return {HTMLElement}
*/
CalendarYearBodyCtrl.prototype.buildBlankCell = function() {
var cell = document.createElement('td');
cell.tabIndex = -1;
cell.classList.add('md-calendar-date');
cell.setAttribute('role', 'gridcell');
cell.setAttribute('tabindex', '-1');
return cell;
};
/**
* Builds the <tbody> content for the given year.
* @param {Date} date Date for which the content should be built.
* @returns {DocumentFragment} A document fragment containing the months within the year.
*/
CalendarYearBodyCtrl.prototype.buildCalendarForYear = function(date) {
// Store rows for the month in a document fragment so that we can append them all at once.
var year = date.getFullYear();
var yearBody = document.createDocumentFragment();
var monthCell, i;
// First row contains label and Jan-Jun.
var firstRow = document.createElement('tr');
var labelCell = document.createElement('td');
labelCell.className = 'md-calendar-month-label';
labelCell.textContent = String(year);
firstRow.appendChild(labelCell);
for (i = 0; i < 6; i++) {
firstRow.appendChild(this.buildMonthCell(year, i));
}
yearBody.appendChild(firstRow);
// Second row contains a blank cell and Jul-Dec.
var secondRow = document.createElement('tr');
secondRow.appendChild(this.buildBlankCell());
for (i = 6; i < 12; i++) {
secondRow.appendChild(this.buildMonthCell(year, i));
}
yearBody.appendChild(secondRow);
return yearBody;
};
})();