Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
168
rated 0 times [  174] [ 6]  / answers: 1 / hits: 8927  / 10 Years ago, mon, march 3, 2014, 12:00:00

Say I have a model object with the attribute favoriteColors



{
...
favoriteColors: ['red', 'green', 'blue']
....
}


I expose them to the user with an ng-repeat



<form name=userForm>
...
<ul>
<li ng-repeat=color in user.favoriteColors>
<input type=text ng-model=color />
<a href= ng-click=delete(color)>remove</a>
</li>
</ul>
<a href= ng-click=add()>Add a new favorite color</a>
...
</form>


I would like to be able to check the validity of the favoriteColors field doing something like this



<div ng-show=userForm.favoriteColors.$error>
You must have at least one favorite color
</div>


It doesn't seem possible to do this using a built in validator, and I'm not sure on which element I would put a custom directive in order to get the ngModelController for favoriteColors.


More From » angularjs

 Answers
20

To have validation the way you are requesting, you have to use an ng-model to put your array of colors into the form so that the array can be validated.



Here's a quick example in a plunker where I push a validator on the $parsers pipeline of the ngModelController which will check the colors array length. Keeping the colorRequired directive separate will allow you to have situations where a color is not required. You could also add to that directive so it will take a boolean argument on the attribute so you can decide at run-time if a color should be required.



http://plnkr.co/edit/yFuSXxacSW811WfZqaPC



var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
$scope.colors = ['red', 'blue', 'green'];
});

app.directive(colorGroup, [function() {
use strict;
return {
restrict: 'E',
require: 'ngModel',
template: '<ng-form name=userForm>
<ul>
<li ng-repeat=color in model>
<input type=text ng-model=color />
<a href= ng-click=delete($index)>remove</a>
</li>
</ul>
</ng-form>',
link: function($scope, element, attrs, ngModelCtrl)
{
$scope.$watch(function(){
return ngModelCtrl.$modelValue;
}, function(){
$scope.model = ngModelCtrl.$viewValue;
});

$scope.delete = function(idx)
{
ngModelCtrl.$viewValue.splice(idx, 1);
ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue);
$scope.model = ngModelCtrl.$viewValue;
}
}
}
}]);

app.directive(colorRequired, function() {
use strict;
return {
restrict: 'A',
require: 'ngModel',
link: function($scope, element, attrs, ngModelCtrl)
{
ngModelCtrl.$setValidity('colorrequired', (ngModelCtrl.$viewValue.length > 0));

ngModelCtrl.$parsers.push(function(viewValue) {
var valid = viewValue.length > 0;
ngModelCtrl.$setValidity('colorrequired', valid);
return valid ? viewValue : undefined;
});
}
}
});

[#47208] Sunday, March 2, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
virginia

Total Points: 632
Total Questions: 95
Total Answers: 95

Location: China
Member since Mon, Aug 22, 2022
2 Years ago
;