I have a directive that receives whether an element should be required or not from a REST api. Right now, I can't seem to get the form to invalidate when an attribute is set to required.
So, in essence I'm able to dynamically add the 'required' attribute from the directive below, but it doesn't invalidate the form. Looking through chrome I see that, even though the required attribute exists, a required entry in the $error array doesn't exist.
app.directive('requireiftrue', function ($compile) {
return {
require: '?ngModel',
link: function (scope, el, attrs, ngModel) {
if (!ngModel) {
return;
}
if(attrs.requireiftrue==="true"){
console.log('should require');
el.attr('required', true);
$compile(el.contents())(scope);
}
else{
console.log('should not require');
}
}
};
});
Here's a jsfiddle to illustrate the problem. And, here's sample JSON returned from my rest API
{
race: false,
martialStatus: true,
}
EDIT: While the accepted answer got me up and running, I still had a good bit of finagling to do.
Namely: 1. Resolving a deferred promise to ensure that my form actually receives the required fields to validate 2. observing my 'requireiftrue' attribute
My solution
module config:
function config($stateProvider) {
$stateProvider
.state('testState', {
url: '/test/form',
controller: 'TestCtrl',
templateUrl: 'test/form/testForm.tpl.html',
resolve: {
formDefaultService: function getFormDefaults($q, dataservice) {
// Set up a promise to return
var deferred = $q.defer();
var myData = dataservice.getFormDefaults();
deferred.resolve(myData);
return deferred.promise;
//return
}
},
data: {
pageTitle: 'Test Info'
}
});
}
And, finally the directive / HTML that receives api data:
Directive:
.directive('requireiftrue', function ($compile) {
return {
require: '?ngModel',
link: function (scope, el, attrs, ngModel) {
if (!ngModel) {
return;
}
attrs.$observe('requireiftrue', function(value){
if(value==="true"){
el.attr('required', true);
el.removeAttr('requireiftrue');
$compile(el[0])(scope);
}
});
}
};
});
HTML:
<input max="40"
requireiftrue={{defaults.validation.name}}
validNumber
id="name"
name="name"
type="text"
ng-model="test.name"
class="form-control">
You had two issues: The first is el.contents() returned an empty array. so The first thing you should do is change it to el[0]. But had el.contents() worked you would hav had a much more serious problem. You would have been trying to compile a directive that has itself as a directive which would lead to an infinite loop (well until the browser crashed any way). So here is the revised code:
var app = angular.module('form-example', []);
app.directive('requireiftrue', function ($compile) {
return {
require: '?ngModel',
link: function (scope, el, attrs, ngModel) {
if (!ngModel) {
return;
}
if(attrs.requireiftrue==="true"){
console.log('should require');
el.attr('required', true);
el.removeAttr('requireiftrue');
$compile(el[0])(scope);
}
else{
console.log('should not require');
}
}
};
});
I should note however that now this directive is a one-off. If the model will change, the directive will not be on the element any longer to deal with it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With