Skip to content
This repository was archived by the owner on May 29, 2019. 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
66 changes: 64 additions & 2 deletions src/datepicker/datepicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,10 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
currentText: '@',
clearText: '@',
closeText: '@',
dateDisabled: '&'
dateDisabled: '&',
minDate: '@',
maxDate: '@'

},
link: function(scope, element, attrs, ngModel) {
var dateFormat,
Expand Down Expand Up @@ -500,7 +503,62 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
if (attrs.dateDisabled) {
datepickerEl.attr('date-disabled', 'dateDisabled({ date: date, mode: mode })');
}
function compareDates(date1, date2) {
if (isNaN(date1) || isNaN(date2)) {
return undefined;
}
else {
return (new Date(date1.getFullYear(), date1.getMonth(), date1.getDate()) - new Date(date2.getFullYear(), date2.getMonth(), date2.getDate()) );
}
}

function getDateLimitToCheck(limitName){
var watchDate=scope.watchData[limitName];
if (!watchDate) {
return null;
} else {
return new Date(watchDate);
}
}

function isDateLimitMet(limitName, dateToCheck, viewValue){
var dateCompare = compareDates(new Date(viewValue), dateToCheck);
if (limitName=='minDate'){
return !dateCompare || dateCompare>0;
} else if (limitName=='maxDate'){
return !dateCompare || dateCompare<0;
}
}
function dateLimitFormat(limitName, viewValue){
var dateLimit=getDateLimitToCheck(limitName);
if (dateLimit) {
ngModel.$setValidity(limitName, isDateLimitMet(limitName, dateLimit , viewValue));
}
return viewValue;
}
function dateLimitParse(limitName, viewValue){
var dateLimit=getDateLimitToCheck(limitName);
if (dateLimit) {
var isMet = isDateLimitMet(limitName, dateLimit , viewValue);
ngModel.$setValidity(limitName, isMet );
return isMet ? viewValue : undefined;
} else {
return viewValue;
}
}

function minLimitParse(viewValue) {
return dateLimitParse('minDate', viewValue);
}
function minLimitFormat(viewValue) {
return dateLimitFormat('minDate', viewValue);
}
function maxLimitParse(viewValue) {
return dateLimitParse('maxDate', viewValue);
}
function maxLimitFormat(viewValue) {
return dateLimitFormat('maxDate', viewValue);
}
function parseDate(viewValue) {
if (!viewValue) {
ngModel.$setValidity('date', true);
Expand All @@ -523,6 +581,10 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
}
}
ngModel.$parsers.unshift(parseDate);
ngModel.$parsers.unshift(minLimitParse);
ngModel.$formatters.unshift(minLimitFormat);
ngModel.$parsers.unshift(maxLimitParse);
ngModel.$formatters.unshift(maxLimitFormat);

// Inner change
scope.dateSelection = function(dt) {
Expand All @@ -544,7 +606,7 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
});
});

// Outter change
// Outer change
ngModel.$render = function() {
var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
element.val(date);
Expand Down
67 changes: 65 additions & 2 deletions src/datepicker/test/datepicker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1123,11 +1123,19 @@ describe('datepicker directive', function () {
$sniffer = _$sniffer_;
$rootScope.isopen = true;
$rootScope.date = new Date('September 30, 2010 15:30:00');
var wrapElement = $compile('<div><input ng-model="date" datepicker-popup is-open="isopen"><div>')($rootScope);
$rootScope.minimumDate = new Date('January 1, 1970');
$rootScope.maximumDate = new Date('January 1, 2020');
$rootScope.dateDisabledHandler = jasmine.createSpy('dateDisabledHandler');
var wrapElement = $compile('<div><input ng-model="date" min-date = "minimumDate" max-date = "maximumDate" date-disabled="dateDisabledHandler(date, mode)" datepicker-popup is-open="isopen"><div>')($rootScope);
$rootScope.$digest();
assignElements(wrapElement);

}));

it('executes the dateDisabled expression for each visible day plus one for validation', function() {
expect($rootScope.dateDisabledHandler.calls.length).toEqual(42+1);
});

it('datepicker is displayed', function() {
expect(dropdownEl).not.toBeHidden();
});
Expand Down Expand Up @@ -1161,6 +1169,41 @@ describe('datepicker directive', function () {
$rootScope.date = new Date('January 10, 1983 10:00:00');
$rootScope.$digest();
expect(inputEl.val()).toBe('1983-01-10');
expect(inputEl).not.toHaveClass('ng-invalid');
expect(inputEl).not.toHaveClass('ng-invalid-min-date');
expect(inputEl).not.toHaveClass('ng-invalid-max-date');
});

it('updates the input correctly when model changes to a date prior to minimum date', function() {
$rootScope.date = new Date('January 10, 1963 10:00:00');
$rootScope.$digest();
expect(inputEl.val()).toBe('1963-01-10');
expect(inputEl).toHaveClass('ng-invalid');
expect(inputEl).toHaveClass('ng-invalid-min-date');
expect(inputEl).not.toHaveClass('ng-invalid-max-date');
});

it('input is not marked with invalid minimum date when minimum is not a valid date', function() {
expect(inputEl).not.toHaveClass('ng-invalid-min-date');
$rootScope.minimumDate = 'pizza';
$rootScope.$digest();
expect(inputEl).not.toHaveClass('ng-invalid-min-date');
});

it('updates the input correctly when model changes to a date past the maximum date', function() {
$rootScope.date = new Date('January 10, 2023 10:00:00');
$rootScope.$digest();
expect(inputEl.val()).toBe('2023-01-10');
expect(inputEl).toHaveClass('ng-invalid');
expect(inputEl).toHaveClass('ng-invalid-max-date');
expect(inputEl).not.toHaveClass('ng-invalid-min-date');
});

it('input is not marked with invalid maximum date when maximum is not a valid date', function() {
expect(inputEl).not.toHaveClass('ng-invalid-max-date');
$rootScope.maximumDate = new Date('pizza');
$rootScope.$digest();
expect(inputEl).not.toHaveClass('ng-invalid-max-date');
});

it('closes the dropdown when a day is clicked', function() {
Expand Down Expand Up @@ -1214,7 +1257,27 @@ describe('datepicker directive', function () {
expect(inputEl).not.toHaveClass('ng-invalid-date');
});

describe('focus', function () {
it('sets `ng-invalid` for date prior to minimum date', function() {
changeInputValueTo(inputEl, '1960-12-01');

expect(inputEl).toHaveClass('ng-invalid');
expect(inputEl).toHaveClass('ng-invalid-min-date');
expect(inputEl).not.toHaveClass('ng-invalid-max-date');
expect($rootScope.date).toBeNull();
expect(inputEl.val()).toBe('1960-12-01');
});

it('sets `ng-invalid` for date past the maximum date', function() {
changeInputValueTo(inputEl, '2050-12-01');

expect(inputEl).toHaveClass('ng-invalid');
expect(inputEl).not.toHaveClass('ng-invalid-min-date');
expect(inputEl).toHaveClass('ng-invalid-max-date');
expect($rootScope.date).toBeNull();
expect(inputEl.val()).toBe('2050-12-01');
});

describe('focus', function () {
beforeEach(function() {
var body = $document.find('body');
body.append(inputEl);
Expand Down