From 73a408224d8053154f4749ee7218c0ae3cd04deb Mon Sep 17 00:00:00 2001 From: crisbeto Date: Fri, 15 Jul 2016 21:18:49 +0200 Subject: [PATCH] fix(datepicker): add asterisk when required, more unit tests * Fixes the datepicker not getting the asterisk, when it's required and inside of a md-input-container. * Adds missing unit tests for the md-input-container integration. Fixes #8950. Closes #9043 --- .../datepicker/js/datepickerDirective.js | 6 ++ .../datepicker/js/datepickerDirective.spec.js | 77 ++++++++++++++++--- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/components/datepicker/js/datepickerDirective.js b/src/components/datepicker/js/datepickerDirective.js index 6475e77f03d..b71fcc80c44 100644 --- a/src/components/datepicker/js/datepickerDirective.js +++ b/src/components/datepicker/js/datepickerDirective.js @@ -54,6 +54,7 @@ * * */ + function datePickerDirective($$mdSvgRegistry, $mdUtil, $mdAria) { return { template: function(tElement, tAttrs) { @@ -121,6 +122,7 @@ var mdDatePickerCtrl = controllers[1]; var mdInputContainer = controllers[2]; var parentForm = controllers[3]; + var mdNoAsterisk = $mdUtil.parseAttributeBoolean(attr.mdNoAsterisk); mdDatePickerCtrl.configureNgModel(ngModelCtrl, mdInputContainer); @@ -146,6 +148,10 @@ if (!mdInputContainer.label) { $mdAria.expect(element, 'aria-label', attr.mdPlaceholder); + } else if(!mdNoAsterisk) { + attr.$observe('required', function(value) { + mdInputContainer.label.toggleClass('md-required', !!value); + }); } scope.$watch(mdInputContainer.isErrorGetter || function() { diff --git a/src/components/datepicker/js/datepickerDirective.spec.js b/src/components/datepicker/js/datepickerDirective.spec.js index 363ce4faea3..39f04bda038 100644 --- a/src/components/datepicker/js/datepickerDirective.spec.js +++ b/src/components/datepicker/js/datepickerDirective.spec.js @@ -21,7 +21,7 @@ describe('md-datepicker', function() { 'ng-disabled="isDisabled">' + ''; - beforeEach(module('material.components.datepicker', 'ngAnimateMock')); + beforeEach(module('material.components.datepicker', 'material.components.input', 'ngAnimateMock')); beforeEach(inject(function($rootScope, $injector) { $compile = $injector.get('$compile'); @@ -115,17 +115,6 @@ describe('md-datepicker', function() { }).not.toThrow(); }); - it('should work inside of md-input-container', function() { - var template = - '' + - '' + - ''; - - expect(function() { - $compile(template)(pageScope); - }).not.toThrow(); - }); - describe('ngMessages support', function() { it('should set the `required` $error flag', function() { pageScope.isRequired = true; @@ -623,4 +612,68 @@ describe('md-datepicker', function() { expect(element.querySelector(triangleSelector)).toBeNull(); }); }); + + describe('md-input-container integration', function() { + var element; + + it('should register the element with the mdInputContainer controller', function() { + compileElement(); + + var inputContainer = element.controller('mdInputContainer'); + + expect(inputContainer.input[0]).toBe(element[0].querySelector('md-datepicker')); + expect(inputContainer.element).toHaveClass('_md-datepicker-floating-label'); + }); + + it('should notify the input container that the element has a placeholder', function() { + compileElement('md-placeholder="Enter a date"'); + expect(element).toHaveClass('md-input-has-placeholder'); + }); + + it('should add the asterisk if the element is required', function() { + compileElement('ng-required="isRequired"'); + var label = element.find('label'); + + expect(label).not.toHaveClass('md-required'); + pageScope.$apply('isRequired = true'); + expect(label).toHaveClass('md-required'); + }); + + it('should not add the asterisk if the element has md-no-asterisk', function() { + compileElement('required md-no-asterisk'); + expect(element.find('label')).not.toHaveClass('md-required'); + }); + + it('should pass the error state to the input container', inject(function($material) { + compileElement('required'); + + var ngModelCtrl = element.find('md-datepicker').controller('ngModel'); + var invalidClass = 'md-input-invalid'; + + expect(ngModelCtrl.$valid).toBe(true); + expect(element).not.toHaveClass(invalidClass); + + ngModelCtrl.$setViewValue(null); + ngModelCtrl.$setTouched(true); + $material.flushOutstandingAnimations(); + + expect(ngModelCtrl.$valid).toBe(false); + expect(element).toHaveClass(invalidClass); + })); + + afterEach(function() { + element.remove(); + }); + + function compileElement(attrs) { + var template = + '' + + '' + + '' + + ''; + + element = $compile(template)(pageScope); + pageScope.$digest(); + } + }); });