Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
fix(datepicker): properly set ngModel validity. Fixes #4926
Browse files Browse the repository at this point in the history
  • Loading branch information
jelbourn committed Oct 30, 2015
1 parent c99541f commit b4d7733
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/components/autocomplete/autocomplete-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ md-autocomplete.md-THEME_NAME-theme {
}
}
}
.md-autocomplete-suggestions-container.md-THEME_NAME-theme, {
.md-autocomplete-suggestions-container.md-THEME_NAME-theme {
background: '{{background-50}}';
li {
color: '{{background-900}}';
Expand Down
6 changes: 3 additions & 3 deletions src/components/datepicker/datePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@
// the directive's isolate scope.
var scope = this.$mdUtil.validateScope(this.$element) ? this.$element.scope() : null;

if ( scope ) {
if (scope) {
scope.$watch(this.$attrs['ngDisabled'], function(isDisabled) {
self.setDisabled(isDisabled);
});
Expand Down Expand Up @@ -338,11 +338,11 @@
DatePickerCtrl.prototype.setErrorFlags = function() {
if (this.dateUtil.isValidDate(this.date)) {
if (this.dateUtil.isValidDate(this.minDate)) {
this.ngModelCtrl.$error['mindate'] = this.date < this.minDate;
this.ngModelCtrl.$setValidity('mindate', this.date >= this.minDate);
}

if (this.dateUtil.isValidDate(this.maxDate)) {
this.ngModelCtrl.$error['maxdate'] = this.date > this.maxDate;
this.ngModelCtrl.$setValidity('maxdate', this.date <= this.maxDate);
}
}
};
Expand Down
86 changes: 65 additions & 21 deletions src/components/datepicker/datePicker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,21 @@ describe('md-date-picker', function() {
var initialDate = new Date(2015, FEB, 15);

var ngElement, element, scope, pageScope, controller;
var $timeout, $$rAF, $animate, $window, keyCodes, dateUtil, dateLocale;
var $compile, $timeout, $$rAF, $animate, $window, keyCodes, dateUtil, dateLocale;

var DATEPICKER_TEMPLATE =
'<md-datepicker name="birthday" ' +
'md-max-date="maxDate" ' +
'md-min-date="minDate" ' +
'ng-model="myDate" ' +
'ng-required="isRequired" ' +
'ng-disabled="isDisabled">' +
'</md-datepicker>';

beforeEach(module('material.components.datepicker', 'ngAnimateMock'));

beforeEach(inject(function($compile, $rootScope, $injector) {
beforeEach(inject(function($rootScope, $injector) {
$compile = $injector.get('$compile');
$$rAF = $injector.get('$$rAF');
$animate = $injector.get('$animate');
$window = $injector.get('$window');
Expand All @@ -25,29 +35,33 @@ describe('md-date-picker', function() {
pageScope.myDate = initialDate;
pageScope.isDisabled = false;

var template = '<md-datepicker ' +
'md-max-date="maxDate" ' +
'md-min-date="minDate" ' +
'ng-model="myDate" ' +
'ng-required="isRequired" ' +
'ng-disabled="isDisabled">' +
'</md-datepicker>';
ngElement = $compile(template)(pageScope);
$rootScope.$apply();

scope = ngElement.isolateScope();
controller = ngElement.controller('mdDatepicker');
element = ngElement[0];

createDatepickerInstance(DATEPICKER_TEMPLATE);
controller.closeCalendarPane();
}));

/**
* Populates the inputElement with a value and triggers the input events.
* Compile and link the given template and store values for element, scope, and controller.
* @param {string} template
* @returns {angular.JQLite} The root compiled element.
*/
function createDatepickerInstance(template) {
var outputElement = $compile(template)(pageScope);
pageScope.$apply();

ngElement = outputElement[0].tagName == 'MD-DATEPICKER' ?
outputElement : outputElement.find('md-datepicker');
element = ngElement[0];
scope = ngElement.isolateScope();
controller = ngElement.controller('mdDatepicker');

return outputElement;
}

/** Populates the inputElement with a value and triggers the input events. */
function populateInputElement(inputString) {
controller.ngInputElement.val(inputString).triggerHandler('input');
$timeout.flush();
pageScope.$apply();
}

it('should set initial value from ng-model', function() {
Expand Down Expand Up @@ -84,28 +98,58 @@ describe('md-date-picker', function() {
it('should set the `required` $error flag', function() {
pageScope.isRequired = true;
populateInputElement('');
pageScope.$apply();

expect(controller.ngModelCtrl.$error['required']).toBe(true);
});

it('should set the `mindate` $error flag', function() {
pageScope.minDate = new Date(2015, JAN, 1);
populateInputElement('2014-01-01');
pageScope.$apply();
controller.ngModelCtrl.$render();

expect(controller.ngModelCtrl.$error['mindate']).toBe(true);
});

it('should set the `mindate` $error flag', function() {
it('should set the `maxdate` $error flag', function() {
pageScope.maxDate = new Date(2015, JAN, 1);
populateInputElement('2016-01-01');
pageScope.$apply();
controller.ngModelCtrl.$render();

expect(controller.ngModelCtrl.$error['maxdate']).toBe(true);
});

describe('inside of a form element', function() {
var formCtrl;

beforeEach(function() {
createDatepickerInstance('<form>' + DATEPICKER_TEMPLATE + '</form>');
formCtrl = ngElement.controller('form');
});

it('should set `required` $error flag on the form', function() {
pageScope.isRequired = true;
populateInputElement('');
controller.ngModelCtrl.$render();

expect(formCtrl.$error['required']).toBeTruthy();
});

it('should set `mindate` $error flag on the form', function() {
pageScope.minDate = new Date(2015, JAN, 1);
populateInputElement('2014-01-01');
controller.ngModelCtrl.$render();

expect(formCtrl.$error['mindate']).toBeTruthy();
});

it('should set `maxdate` $error flag on the form', function() {
pageScope.maxDate = new Date(2015, JAN, 1);
populateInputElement('2016-01-01');
controller.ngModelCtrl.$render();

expect(formCtrl.$error['maxdate']).toBeTruthy();
});
});
});

describe('input event', function() {
Expand Down

0 comments on commit b4d7733

Please sign in to comment.