I have created a async validator 'username-validator' to check username availability and to avoid number of remote calls I am updating ng-model on 'blur' event rather than on 'key press'. So validator is triggered only on 'blur' event.
<input type="text" ng-model="signup.username" name="username"
required
username-validator
ng-model-options="{ updateOn: 'blur' }">
But when form gets submitted it checks if form is valid and only then it gets submitted.
$scope.submit = function(form) {
if (form.$valid) {
alert('submitting', $scope.signup.username, $scope.signup.password);
}
};
But when I am clicking on Submit button and if form is in $pending state then form doesn't get submitted in one click, because at the time of click it is in $pending state and $valid is undefined.
I want to write my $scope.submit function to handle submission once $pending state is resolved.
How do i do it?
Don't want to disable the Submit button for $pending state.
To demonstrate the problem I am adding running snippet with it.
angular.module('app', ['ngMessages'])
.controller('MainCtrl', function($scope) {
$scope.signup = {};
$scope.submit = function(form) {
if (form.$valid) {
alert('submitting ' + $scope.signup.username + ' ' + $scope.signup.password);
}
};
})
.directive('usernameValidator', function($q, $timeout) {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
ngModel.$asyncValidators.username = function(modelValue, viewValue) {
if (!viewValue) {
return $q.when(true);
}
var deferred = $q.defer();
$timeout(function() {
// Faking actual server-side validity check with $http.
// Let's pretend our service is so popular all short username are already taken
if (viewValue && viewValue.length < 5) {
deferred.reject();
}
deferred.resolve();
}, 2000);
return deferred.promise;
};
}
};
});
.validation-error {
color: red;
}
.validation-pending {
color: orange;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular-messages.min.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body ng-app="app">
<div ng-controller="MainCtrl">
<form name="myForm" ng-submit="submit(myForm)" novalidate>
<div>
<label>
Username:
<input type="text" ng-model="signup.username" name="username" required username-validator ng-model-options="{ updateOn: 'blur' }">
</label>
<div ng-if="myForm.username.$dirty">
<div ng-messages="myForm.username.$error" class="validation-error">
<div ng-message="required">Username required</div>
<div ng-message="username">Username already in use</div>
</div>
<div ng-messages="myForm.username.$pending" class="validation-pending">
<div ng-message="username">Checking username availability...</div>
</div>
</div>
</div>
<div>
<label>
Password:
<input type="password" ng-model="signup.password" name="password" required>
</label>
<div ng-messages="myForm.password.$error" ng-if="myForm.password.$dirty" class="validation-error">
<div ng-message="required">Password required</div>
</div>
</div>
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>