Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/components/datepicker/js/calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,4 +387,22 @@
date.getDate()
].join('-');
};

/**
* Util to trigger an extra digest on a parent scope, in order to to ensure that
* any child virtual repeaters have updated. This is necessary, because the virtual
* repeater doesn't update the $index the first time around since the content isn't
* in place yet. The case, in which this is an issue, is when the repeater has less
* than a page of content (e.g. a month or year view has a min or max date).
*/
CalendarCtrl.prototype.updateVirtualRepeat = function() {
var scope = this.$scope;
var virtualRepeatResizeListener = scope.$on('$md-resize-enable', function() {
if (!scope.$$phase) {
scope.$apply();
}

virtualRepeatResizeListener();
});
};
})();
1 change: 1 addition & 0 deletions src/components/datepicker/js/calendarMonth.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
}

this.attachScopeListeners();
calendarCtrl.updateVirtualRepeat();

// Fire the initial render, since we might have missed it the first time it fired.
calendarCtrl.ngModelCtrl && calendarCtrl.ngModelCtrl.$render();
Expand Down
24 changes: 8 additions & 16 deletions src/components/datepicker/js/calendarYear.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
* Controller for the mdCalendar component.
* @ngInject @constructor
*/
function CalendarYearCtrl($element, $scope, $animate, $q, $$mdDateUtil, $timeout) {
function CalendarYearCtrl($element, $scope, $animate, $q, $$mdDateUtil) {

/** @final {!angular.JQLite} */
this.$element = $element;
Expand All @@ -60,9 +60,6 @@
/** @final */
this.dateUtil = $$mdDateUtil;

/** @final */
this.$timeout = $timeout;

/** @final {HTMLElement} */
this.calendarScroller = $element[0].querySelector('.md-virtual-repeat-scroller');

Expand Down Expand Up @@ -103,12 +100,6 @@
*/
this.items = { length: 400 };

if (maxDate && minDate) {
// Limit the number of years if min and max dates are set.
var numYears = this.dateUtil.getYearDistance(minDate, maxDate) + 1;
this.items.length = Math.max(numYears, 1);
}

this.firstRenderableDate = this.dateUtil.incrementYears(calendarCtrl.today, - (this.items.length / 2));

if (minDate && minDate > this.firstRenderableDate) {
Expand All @@ -119,13 +110,14 @@
this.firstRenderableDate = this.dateUtil.incrementMonths(maxDate, - (this.items.length - 1));
}

// Trigger an extra digest to ensure that the virtual repeater has updated. This
// is necessary, because the virtual repeater doesn't update the $index the first
// time around since the content isn't in place yet. The case, in which this is an
// issues, is when the repeater has less than a page of content (e.g. there's a min
// and max date).
if (minDate || maxDate) this.$timeout();
if (maxDate && minDate) {
// Limit the number of years if min and max dates are set.
var numYears = this.dateUtil.getYearDistance(this.firstRenderableDate, maxDate) + 1;
this.items.length = Math.max(numYears, 1);
}

this.attachScopeListeners();
calendarCtrl.updateVirtualRepeat();

// Fire the initial render, since we might have missed it the first time it fired.
calendarCtrl.ngModelCtrl && calendarCtrl.ngModelCtrl.$render();
Expand Down
2 changes: 1 addition & 1 deletion src/components/datepicker/js/calendarYearBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@

var cellText = this.dateLocale.shortMonths[month];

if (this.dateUtil.isDateWithinRange(firstOfMonth,
if (this.dateUtil.isMonthWithinRange(firstOfMonth,
calendarCtrl.minDate, calendarCtrl.maxDate)) {
var selectionIndicator = document.createElement('span');
selectionIndicator.classList.add('md-calendar-date-selection-indicator');
Expand Down
17 changes: 16 additions & 1 deletion src/components/datepicker/js/dateUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
incrementYears: incrementYears,
getYearDistance: getYearDistance,
clampDate: clampDate,
getTimestampFromNode: getTimestampFromNode
getTimestampFromNode: getTimestampFromNode,
isMonthWithinRange: isMonthWithinRange
};

/**
Expand Down Expand Up @@ -292,5 +293,19 @@
}
}

/**
* Checks if a month is within a min and max range, ignoring the date and time components.
* If minDate or maxDate are not dates, they are ignored.
* @param {Date} date
* @param {Date} minDate
* @param {Date} maxDate
*/
function isMonthWithinRange(date, minDate, maxDate) {
var month = date.getMonth();
var year = date.getFullYear();

return (!minDate || minDate.getFullYear() < year || minDate.getMonth() <= month) &&
(!maxDate || maxDate.getFullYear() > year || maxDate.getMonth() >= month);
}
});
})();
99 changes: 80 additions & 19 deletions src/components/datepicker/js/dateUtil.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,50 +326,50 @@ describe('$$mdDateUtil', function() {
});

it('should return true when a date is in range', function() {
var date = new Date('2015-05-02');
var minDate = new Date('2015-05-01');
var maxDate = new Date('2015-05-03');
var date = new Date(2015, JUN, 2);
var minDate = new Date(2015, JUN, 1);
var maxDate = new Date(2015, JUN, 3);
expect(dateUtil.isDateWithinRange(date, minDate, maxDate)).toBeTruthy();
});

it('should return false when a date is before the range', function() {
var date = new Date('2015-04-29');
var minDate = new Date('2015-05-01');
var maxDate = new Date('2015-05-03');
var date = new Date(2015, MAY, 29);
var minDate = new Date(2015, JUN, 1);
var maxDate = new Date(2015, JUN, 3);
expect(dateUtil.isDateWithinRange(date, minDate, maxDate)).toBeFalsy();
});

it('should return false when a date is after the range', function() {
var date = new Date('2015-05-05');
var minDate = new Date('2015-05-01');
var maxDate = new Date('2015-05-03');
var date = new Date(2015, JUN, 5);
var minDate = new Date(2015, JUN, 1);
var maxDate = new Date(2015, JUN, 3);
expect(dateUtil.isDateWithinRange(date, minDate, maxDate)).toBeFalsy();
});

it('should set the time to midnight before checking the min date', function() {
var date = new Date('2015-05-01T11:00:00');
var minDate = new Date('2015-05-01T12:00:00');
var maxDate = new Date('2015-05-03');
var date = new Date(2015, JUN, 1, 11, 0, 0);
var minDate = new Date(2015, JUN, 1, 0, 0, 0);
var maxDate = new Date(2015, JUN, 3);
expect(dateUtil.isDateWithinRange(date, minDate, maxDate)).toBeTruthy();
});

it('should set the time to midnight before checking the max date', function() {
var date = new Date('2015-05-03T13:00:00');
var minDate = new Date('2015-05-01');
var maxDate = new Date('2015-05-03T12:00:00');
var date = new Date(2015, JUN, 3, 13, 0, 0);
var minDate = new Date(2015, 5, 1);
var maxDate = new Date(2015, JUN, 3, 12, 0, 0);
expect(dateUtil.isDateWithinRange(date, minDate, maxDate)).toBeTruthy();
});

it('should ignore an invalid minDate when checking if the date is in range', function() {
var date = new Date('2015-05-02');
var date = new Date(2015, JUN, 2);
var minDate = null;
var maxDate = new Date('2015-05-03');
var maxDate = new Date(2015, JUN, 3);
expect(dateUtil.isDateWithinRange(date, minDate, maxDate)).toBeTruthy();
});

it('should ignore an invalid maxDate when checking if the date is in range', function() {
var date = new Date('2015-05-02');
var minDate = new Date('2015-05-01');
var date = new Date(2015, JUN, 2);
var minDate = new Date(2015, JUN, 1);
var maxDate = null;
expect(dateUtil.isDateWithinRange(date, minDate, maxDate)).toBeTruthy();
});
Expand Down Expand Up @@ -436,4 +436,65 @@ describe('$$mdDateUtil', function() {

node = null;
});

describe('isMonthWithinRange method', function() {
it('should return true when a month is in range', function() {
var date = new Date(2015, JUN, 1);
var minDate = new Date(2015, MAY, 1);
var maxDate = new Date(2015, JUL, 1);
expect(dateUtil.isMonthWithinRange(date, minDate, maxDate)).toBeTruthy();
});

it('should return false when a month is before the range', function() {
var date = new Date(2015, MAY, 1);
var minDate = new Date(2015, JUN, 1);
var maxDate = new Date(2015, JUL, 1);
expect(dateUtil.isMonthWithinRange(date, minDate, maxDate)).toBeFalsy();
});

it('should return false when a month is after the range', function() {
var date = new Date(2015, AUG, 1);
var minDate = new Date(2015, JUN, 1);
var maxDate = new Date(2015, JUL, 1);
expect(dateUtil.isMonthWithinRange(date, minDate, maxDate)).toBeFalsy();
});

it('should ignore an invalid minDate when checking if the month is in range', function() {
var date = new Date(2015, JUN, 1);
var minDate = null;
var maxDate = new Date(2015, JUL, 1);
expect(dateUtil.isMonthWithinRange(date, minDate, maxDate)).toBeTruthy();
});

it('should ignore an invalid maxDate when checking if the month is in range', function() {
var date = new Date(2015, JUN, 1);
var minDate = new Date(2015, JUN, 1);
var maxDate = null;
expect(dateUtil.isMonthWithinRange(date, minDate, maxDate)).toBeTruthy();
});

it('should take the year into account when comparing with the min date', function() {
var date = new Date(2015, MAR, 1);
var minDate = new Date(2014, JUN, 1);
expect(dateUtil.isMonthWithinRange(date, minDate)).toBeTruthy();
});

it('should take the year into account when comparing with the max date', function() {
var date = new Date(2015, JUL, 1);
var maxDate = new Date(2016, FEB, 1);
expect(dateUtil.isMonthWithinRange(date, null, maxDate)).toBeTruthy();
});

it('should return true, even though parts of the month are before the minDate', function() {
var date = new Date(2015, MAY, 1);
var minDate = new Date(2015, MAY, 20);
expect(dateUtil.isMonthWithinRange(date, minDate)).toBeTruthy();
});

it('should return true, even though parts of the month are after the maxDate', function() {
var date = new Date(2015, JUN, 20);
var maxDate = new Date(2015, JUN, 1);
expect(dateUtil.isMonthWithinRange(date, null, maxDate)).toBeTruthy();
});
});
});