Reputation: 3558
I'm writing a simple login form using angularjs with some client side input validation to check that the user name and password is not empty and longer than three characters. See the below code:
<form name="loginform" novalidate ng-submit="login.submit()" class="css-form">
<fieldset>
<div class="control-group input-prepend">
<span class="add-on"><i class="icon-user"></i></span>
<input type="text" ng-model="login.username" name="username" required ng-minlength="3" placeholder="username" />
</div>
<div class="control-group input-prepend">
<span class="add-on"><i class="icon-lock"></i></span>
<input type="password" ng-model="login.password" name="password" required ng-minlength="3" placeholder="" />
</div>
<div class="control-group">
<input class="btn" type="submit" value="Log in">
</div>
</fieldset>
</form>
And the controller:
var controller = function($scope) {
$scope.login = {
submit: function() {
Console.info($scope.login.username + ' ' + $scope.login.password);
}
}
};
The problem is that the login.submit
function will be called even if the input is not valid. Is it possible to prevent this behaviour?
As a side note I can mention that I use bootstrap and requirejs as well.
Upvotes: 156
Views: 159090
Reputation: 63179
HTML:
<div class="control-group">
<input class="btn" type="submit" value="Log in" ng-click="login.onSubmit($event)">
</div>
In your controller:
$scope.login = {
onSubmit: function(event) {
if (dataIsntValid) {
displayErrors();
event.preventDefault();
}
else {
submitData();
}
}
}
Upvotes: 13
Reputation: 486
I know it's late and was answered, but I'd like to share the neat stuff I made. I created an ng-validate directive that hooks the onsubmit of the form, then it issues prevent-default if the $eval is false:
app.directive('ngValidate', function() {
return function(scope, element, attrs) {
if (!element.is('form'))
throw new Error("ng-validate must be set on a form elment!");
element.bind("submit", function(event) {
if (!scope.$eval(attrs.ngValidate, {'$event': event}))
event.preventDefault();
if (!scope.$$phase)
scope.$digest();
});
};
});
In your html:
<form name="offering" method="post" action="offer" ng-validate="<boolean expression">
Upvotes: 1
Reputation: 9357
Although not a direct solution for the OPs question, if your form is within an ng-app
context, but you want Angular to ignore it altogether, you can do this explicitly using the ngNonBindable
directive:
<form ng-non-bindable>
...
</form>
Upvotes: 4
Reputation: 97
Just to add to the answers above,
I was having a 2 regular buttons as shown below. (No type="submit"anywhere)
<button ng-click="clearAll();" class="btn btn-default">Clear Form</button>
<button ng-disabled="form.$invalid" ng-click="submit();"class="btn btn-primary pull-right">Submit</button>
No matter how much i tried, pressing enter once the form was valid, the "Clear Form" button was called, clearing the entire form.
As a workaround,
I had to add a dummy submit button which was disabled and hidden. And This dummy button had to be on top of all the other buttons as shown below.
<button type="submit" ng-hide="true" ng-disabled="true">Dummy</button>
<button ng-click="clearAll();" class="btn btn-default">Clear Form</button>
<button ng-disabled="form.$invalid" ng-click="submit();"class="btn btn-primary pull-right">Submit</button>
Well, my intention was never to submit on Enter, so the above given hack just works fine.
Upvotes: 2
Reputation: 139
I know this is an old thread but I thought I'd also make a contribution. My solution being similar to the post already marked as an answer. Some inline JavaScript checks does the trick.
ng-click="form.$invalid ? alert('Please correct the form') : saveTask(task)"
Upvotes: 1
Reputation: 26507
Change the submit button to:
<button type="submit" ng-disabled="loginform.$invalid">Login</button>
Upvotes: 67
Reputation: 40143
You can do:
<form name="loginform" novalidate ng-submit="loginform.$valid && login.submit()">
No need for controller checks.
Upvotes: 331
Reputation: 3823
Your forms are automatically put into $scope as an object. It can be accessed via $scope[formName]
Below is an example that will work with your original setup and without having to pass the form itself as a parameter in ng-submit.
var controller = function($scope) {
$scope.login = {
submit: function() {
if($scope.loginform.$invalid) return false;
}
}
};
Working example: http://plnkr.co/edit/BEWnrP?p=preview
Upvotes: 13
Reputation: 3558
So the suggested answer from TheHippo did not work for me, instead I ended up sending the form as a parameter to the function like so:
<form name="loginform" novalidate ng-submit="login.submit(loginForm)" class="css-form">
This makes the form available in the controller method:
$scope.login = {
submit : function(form) {
if(form.$valid)....
}
Upvotes: 43