diff --git a/src/datepicker/datepicker.js b/src/datepicker/datepicker.js index 05784947d0..121fb9b5d0 100644 --- a/src/datepicker/datepicker.js +++ b/src/datepicker/datepicker.js @@ -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, @@ -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); @@ -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) { @@ -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); diff --git a/src/datepicker/test/datepicker.spec.js b/src/datepicker/test/datepicker.spec.js index b673d162da..075952d0ac 100644 --- a/src/datepicker/test/datepicker.spec.js +++ b/src/datepicker/test/datepicker.spec.js @@ -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('