UNPKG

angular-material-npfixed

Version:

The Angular Material project is an implementation of Material Design in Angular.js. This project provides a set of reusable, well-tested, and accessible Material Design UI components. Angular Material is supported internally at Google by the Angular.js, M

182 lines (151 loc) 5.99 kB
(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 {!angular.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} */ 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.focus(); this.focusAfterAppend = null; } }; /** * Creates a single cell to contain a year in the calendar. * @param {number} opt_year Four-digit year. * @param {number} opt_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', 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)) { 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 {HTMLTableCellElement} */ 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 = 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; }; })();