I would like to use the built in form validation provided by AngularJS. However, within the form I am using custom directives that each have an isolate scope. Because of this the form element does not have access to the bound values.
Any idea how to fix this?
or, is it possible to use AngularJS validation without the use of a form?
The ng-minlength and ng-required directives are not triggering the form validation.
<div ng-app="myApp" ng-controller="myCtrl">
<form name="myForm" novalidate>
<do-something ng-model="variable"></do-something>
<h4 data-ng-if="myForm.myElement.$error.required">Please enter something</h4>
<h4 data-ng-if="myForm.myElement.$error.greaterThanOne">Please enter a value greater than 1</h4>
<h4 data-ng-if="myForm.myElement.$error.minLength">Please enter something longer than 1 digit</h4>
{{myForm.myElement.$error}}
</form>
</div>
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
});
app.directive('doSomething', function () {
return {
restrict: 'E',
require: '?ngModel',
scope: {
model: '=ngModel'
},
template:
'<div>' +
' <input name="myElement" ng-model="model" ng-required ng-minlength="1" />' +
'</div>'
}
});
Full Plunk can be found here: Here is a plunkr that demonstrates the problem:
I would like to use the built in form validation provided by AngularJS. However, within the form I am using custom directives that each have an isolate scope. Because of this the form element does not have access to the bound values.
Any idea how to fix this?
or, is it possible to use AngularJS validation without the use of a form?
The ng-minlength and ng-required directives are not triggering the form validation.
<div ng-app="myApp" ng-controller="myCtrl">
<form name="myForm" novalidate>
<do-something ng-model="variable"></do-something>
<h4 data-ng-if="myForm.myElement.$error.required">Please enter something</h4>
<h4 data-ng-if="myForm.myElement.$error.greaterThanOne">Please enter a value greater than 1</h4>
<h4 data-ng-if="myForm.myElement.$error.minLength">Please enter something longer than 1 digit</h4>
{{myForm.myElement.$error}}
</form>
</div>
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
});
app.directive('doSomething', function () {
return {
restrict: 'E',
require: '?ngModel',
scope: {
model: '=ngModel'
},
template:
'<div>' +
' <input name="myElement" ng-model="model" ng-required ng-minlength="1" />' +
'</div>'
}
});
Full Plunk can be found here: Here is a plunkr that demonstrates the problem: http://plnkr.co/edit/iWyvX2?p=preview
Share Improve this question edited Jun 23, 2014 at 22:48 Daniel Mackay asked Jun 23, 2014 at 6:44 Daniel MackayDaniel Mackay 2,3561 gold badge15 silver badges19 bronze badges 2- Have you passed in the value as an attribute to your directive? You should be able to set the scope on that particular value as bidirectional I would have thought. I'm making assumptions here though; post a Fiddle. – Chris Bell Commented Jun 23, 2014 at 6:52
- I have posted a plunkr to illustrate the problem. I have passed the attribute into the directive. Can you see anything wrong? – Daniel Mackay Commented Jun 23, 2014 at 13:10
3 Answers
Reset to default 2From my understanding, yes you have to use a form for validation.
The way in which I validate is to set up a directive like below
module.directive('ngDoSomething', function() {
restrict: 'A'
require: '?ngModel',
scope: {
model: '=ngModel'
}
link: function($scope, element, attrs, ngModel) {
$scope.$watch('model', function(val) {
ngModel.$setValidity('required', !!val);
ngModel.$setValidity('greaterThanOne', val > 1);
}
});
Then use the html
<form name="somethingForm">
<input name="somethingElement" data-ng-do-something data-ng-model="variable" />
<h4 data-ng-if="somethingForm.somethingElement.$error.required">Please enter something</h4>
<h4 data-ng-if="somethingForm.somethingElement.$error.greaterThanOne">Please enter a value greater than 1</h4>
</form>
I hope this helps
Ok Daniel, I was intrigued so I looked into it a bit further. The main difference between your code and @user3766487 is that you're using a directive element and injecting template. I believe this has caused a bit of ambiguity (you'll see that the directive itself and the inject input element both have the same name attribute). The linkage of the model doesn't appear to be quite working either.
I've changed your code to replace the template instead, which has made things a bit simpler. It appears to work:
http://plnkr.co/edit/eTSbjNe4KXW9IbUKtKuG
The ng-validators will work as expected with this 2 changes:
(1) Change the property name to "minlength" (instead of "minLength"):
<h4 data-ng-if="myForm.myElement.$error.minlength">
(2) Set ng-required to "true":
<input name="myElement" ... ng-required="true">
Setting minlength to "1" does not do anything because form validation does not check minlength wen the input is empty. If you set minlength to "5" and type one character in the input, you will see the message "Please enter something longer than 5 digit"
http://plnkr.co/edit/porkuq5JcKDU89s8g8ZT?p=preview
Your custom validator "greaterThanOne" is defined on the do-something directive. You can show its message by adding a name attribute such as myElementContainer:
<do-something name="myElementContainer" ng-model="myElement"></do-something>
<h4 data-ng-show="myForm.myElementContainer.$error.greaterThanOne">Please enter a value greater than 1</h4>
I would remend to to define the logic in another directive as an attribute to the input element.
Also, using $validators is remended over calling $setValidity: https://docs.angularjs/api/ng/type/ngModel.NgModelController