From 0ca89fa3d11a91a9dcd27a8157fefec3f869b0b5 Mon Sep 17 00:00:00 2001 From: Michael Prentice Date: Wed, 16 Dec 2020 02:49:21 -0500 Subject: [PATCH] fix(select): form remains valid after empty option is selected - change md-select's `$isEmpty()` implementation from a naive falsy check to a more robust check that is similar to AngularJS' default - add empty option to validations demo Fixes #10005 --- src/components/select/demoValidations/index.html | 1 + src/components/select/select.js | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/select/demoValidations/index.html b/src/components/select/demoValidations/index.html index 99796aa3f8..5572d36df7 100755 --- a/src/components/select/demoValidations/index.html +++ b/src/components/select/demoValidations/index.html @@ -14,6 +14,7 @@ + Red Blue Green diff --git a/src/components/select/select.js b/src/components/select/select.js index 2e5f1f56b5..e1959fe459 100755 --- a/src/components/select/select.js +++ b/src/components/select/select.js @@ -589,8 +589,8 @@ function SelectDirective($mdSelect, $mdUtil, $mdConstant, $mdTheming, $mdAria, $ function inputCheckValue() { // The select counts as having a value if one or more options are selected, - // or if the input's validity state says it has bad input (eg string in a number input) - // we must do this on nextTick as the $render is sometimes invoked on nextTick. + // or if the input's validity state says it has bad input (eg: string in a number input). + // We must do this on nextTick as the $render is sometimes invoked on nextTick. $mdUtil.nextTick(function () { containerCtrl && containerCtrl.setHasValue( selectMenuCtrl.getSelectedLabels().length > 0 || (element[0].validity || {}).badInput); @@ -850,7 +850,10 @@ function SelectMenuDirective($parse, $mdUtil, $mdConstant, $mdTheming) { self.ngModel.$isEmpty = function($viewValue) { // We have to transform the viewValue into the hashKey, because otherwise the // OptionCtrl may not exist. Developers may have specified a trackBy function. - return !self.options[self.hashGetter($viewValue)]; + var hashedValue = self.options[self.hashGetter($viewValue)] ? self.options[self.hashGetter($viewValue)].value : null; + // Base this check on the default AngularJS $isEmpty() function. + // eslint-disable-next-line no-self-compare + return !angular.isDefined(hashedValue) || hashedValue === null || hashedValue === '' || hashedValue !== hashedValue; }; // Allow users to provide `ng-model="foo" ng-model-options="{trackBy: '$value.id'}"` so