Reputation: 15303
I made a simple testing input fields, But I trying to convert the validation on blur, But i don't have any idea to achive this, since I am not such familiar with angularjs.
any one help me to validate only one blur in this example please..
myJs:
angular.module('myApp', [])
.controller('FormController', function($scope) {
$scope.fields = [
{placeholder: 'Username', isRequired: true},
{placeholder: 'Password', isRequired: true},
{placeholder: 'Email (optional)', isRequired: false}
];
$scope.submitForm = function() {
alert("it works!");
};
});
html:
<div ng-app="myApp">
<form name="signup_form" ng-controller="FormController" ng-submit="submitForm()" novalidate>
<div ng-repeat="field in fields" ng-form="signup_form_input">
<input type="text"
name="dynamic_input"
ng-required="field.isRequired"
ng-model="field.name"
placeholder="{{field.placeholder}}" />
<div ng-show="signup_form_input.dynamic_input.$dirty && signup_form_input.dynamic_input.$invalid">
<span class="error" ng-show="signup_form_input.dynamic_input.$error.required">The field is required.</span>
</div>
</div>
<button type="submit" ng-disabled="signup_form.$invalid">Submit All</button>
</form>
</div>
Upvotes: 12
Views: 28254
Reputation: 6247
If you have a custom validation, a simple way to go is using ngBlur. Add the following to your field and write a validation function in your controller:
<input type="text"
ng-model="fieldVal"
ng-blur="validate(fieldVal)"/>
You can also use ng-model-options combined with ng-change
<input type="text"
ng-modle="fildsVal"
ng-model-option="{ updateOn: 'blur' }"
ng-change="validate(fieldVal)" />
I also found the debounce option very nice to trigger the validation. You can time it so that when user is done typing, the validation triggers:
<input type="text"
ng-model-options="{ debounce: 800 }"
ng-pattern="/^[0-9]{1,9}$/" />
Upvotes: 2
Reputation: 30098
You can simply create a directive that has the same name as ngModel
. Add a blur
event on the element that changes the $dirty
state of the ngModel
to true. Make sure to change ngModel
's $dirty
state to false when changes are made on the element by adding a callback inside ngModel.$viewChangeListeners
array.
The directive looks something like this:
.directive('ngModel', function() {
return {
require: 'ngModel',
link: function(scope, elem, attr, ngModel) {
elem.on('blur', function() {
ngModel.$dirty = true;
scope.$apply();
});
ngModel.$viewChangeListeners.push(function() {
ngModel.$dirty = false;
});
scope.$on('$destroy', function() {
elem.off('blur');
});
}
}
});
Note: Don't worry if the custom directive name, ngModel
, is the same with Angular's default ngModel
, it will simply run both of them (it won't overwrite it). The scope.$on('$destroy')
listener, removes the blur
event handler when the scope is destroyed, e.g. when route changes and the controller is destroyed or when a field is removed which triggers a rebuild of the repeated DOM elements again(destroying the child scope created by ng-repeat
).
Upvotes: 11
Reputation: 709
angular.module('myApp', [])
.controller('FormController', function($scope) {
$(document).ready(function(){
$("#form input").on('blur', function(){
alert("Cannot be null");
});
});
$scope.fields = [
{placeholder: 'Username', isRequired: true},
{placeholder: 'Password', isRequired: true},
{placeholder: 'Email (optional)', isRequired: false}
];
$scope.submitForm = function() {
alert("it works!");
};
});
just give id to form and add the javascript code. Thats all. For live demo "http://jsfiddle.net/SaurabhGhewari/2ko9bamk/"
Upvotes: 3
Reputation: 32127
If you update to Angular 1.3 you can use ng-model-options
to update the model on blur.
<input type="text"
name="dynamic_input"
ng-required="field.isRequired"
ng-model="field.name"
ng-model-options="{ updateOn: 'blur' }"
placeholder="{{field.placeholder}}" />
However, if you can't update then there are plenty of ways to do this here.
Upvotes: 22