Angularjs - Custom select option validator - check if selected value is in option list
Custom select option validator - check if selected value is in option list. Original Angular ng-required invalid result only work when value is "", undefined, null, NaN.
by hugogo7646
HTML
<div ng-app="app" ng-controller="controller as ctrl">
<form name="form">
<label><input type="radio" name="optionType" ng-value="1" ng-model="ctrl.optionType" /> Set option list 1</label>
<label><input type="radio" name="optionType" ng-value="2" ng-model="ctrl.optionType" /> Set option list 2</label>
<select name="mySelector" ng-model="ctrl.selectedVal" ng-options="selectOption.optionValue.id as selectOption.title for selectOption in ctrl.selectOptionList" select-option-check-validator ng-required="true">
</select>
<button ng-click="ctrl.selectedVal = 0">
Set selectedVal to 0
</button>
<div>
ctrl.selectedVal : {{ctrl.selectedVal}}
</div>
<div>
form.mySelector.$error.selectedValueInOptionList : {{form.mySelector.$error.selectedValueInOptionList ? "invalid" : "valid"}}
</div>
<div>
form.mySelector.$error.selectedValueInOptionList : {{form.mySelector.$error.required ? "invalid" : "valid"}}
</div>
</form>
</div>
JavaScript
angular.module("app", [])
.controller("controller", ["$scope", function($scope) {
var self = this;
self.optionType = 1;
self.selectedVal = 0;
self.optionList1 = [{
optionValue: {
id: 11
},
title: "id 11"
}, {
optionValue: {
id: 12
},
title: "id 12"
}];
self.optionList2 = [{
optionValue: {
id: 21
},
title: "id 21"
}, {
optionValue: {
id: 22
},
title: "id 22"
}];
self.selectOptionList = [];
$scope.$watch(angular.bind(this, function() {
return this.optionType;
}), function(newVal, oldVal) {
//if value of selectedValue can not be found in self.selectOptionList,
// selectedValue will be assigned to null.
if (newVal == 1) {
self.selectOptionList = self.optionList1;
} else if (newVal == 2) {
self.selectOptionList = self.optionList2;
self.selectedVal = 21;
}
});
}]).directive('selectOptionCheckValidator', ["$parse", function($parse) {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
var regex = /(.+)\sas\s(.+)\sfor\s(.+)\sin\s(.+)/;
var matchString = regex.exec(attrs.ngOptions);
var collectionExpression = matchString[4]; // "ctrl.selectOptionList"
var arryItemVarableName = matchString[3]; // "selectOption"
var valueExpression = matchString[1]; // "selectOption.optionValue.id"
scope.$watch(collectionExpression, function(newValue, oldValue) {
checkIsSelectedValueInOptionList();
});
element.on("change", function() {
scope.$apply(function() {
checkIsSelectedValueInOptionList();
});
});
function checkIsSelectedValueInOptionList() {
var isSelectedValueInOptionList = false;
var selectedValue = $parse(attrs.ngModel)(scope);
var optionList =...