is it possible to do form validation in the submit handler? - angularjs

You can do form validatin using html in angular, but if you hit the <enter> key in an input field, the form gets submitted with all data being undefined (disabled button is ignored).
How can I do form validation in the ng-submit="submitForm()" handler (where it belongs).
Edit: so everyone is telling me that enter triggers the submit button to submit (and since its disabled it should work) -- I don't believe this to be true, but here's my form. For me it just submits when i hit enter.
<form novalidate class="user" name="user" ng-show="showUserForm" ng-submit="joinChat()">
<input type="text" placeholder="Enter nick" required ng-model="user.nick" tabindex="1" ng-minlength="2" ng-maxlength="10">
<button ng-disabled="user.$invalid">Join</button>
</form>
Here's what joinChat() does:
$scope.joinChat = function(){
$scope.showPostMessage = true;
$scope.showUserForm = false;
socket.emit('chat:join', { nick: $scope.user.nick });
};

First of all, make sure you turn off html5 validation by setting novalidate on your form and make sure your form has a name. This makes it easy to pass the form controller to your submit handler:
<form novalidate name="myForm" ng-submit="submitForm(myForm)"></form>
Then in your handler you can do what you want:
$scope.submitForm = function(form){
if(form.$invalid){
alert("FORM INVALID");
}
else{
// do whatever you want to do on form submit.
}
};
If you want to do additional validation you can use the form object to access all form controls, read their values and set their valid state. The form object is a formController who's api is documented here:
http://docs.angularjs.org/api/ng.directive:form.FormController
You can also access each individual control. For example if you have an input like:
<input type="text" name="myInput" ng-model="someValue" />
You can access it from the form object like so:
form.myInput;
You can then do anything documented in ngModelController:
http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController
For example, you can set the input to be invalid:
form.myInput.$setValidity('someCustomError', false);
You can read the current value:
var currentValue = form.myInput.$viewValue;
etc...

Related

Angular: Disable button on click after required fields are filled in the form

I need to disable the submit button after clicking on the button to prevent multiple submissions but before the it has to ensure that the required fields are filled.
I tried
<body ng-app="ngToggle">
<div ng-controller="AppCtrl">
<form name="newUserForm">
<input type="text" required>
<input type="text" required>
<input type="text">
<button ng-click="disableClick()" ng-disabled="isDisabled"
ng-model="isDisabled">Disable ng-click</button>
</form>
</div>
</body>
angular.module('ngToggle', [])
.controller('AppCtrl',['$scope', function($scope){
$scope.isDisabled = false;
$scope.disableClick = function() {
alert("Clicked!");
$scope.isDisabled = true;
return false;
}
}]);
but this will only disable the button without any validation
Ok, I get what you mean/want so I'll try to help and come up with some code - which is obviously missing but if it wasn't missing the necessary code, you'd have the solution :)
First, you'll have to properly write your form:
<form name="newUserForm" ng-submit="disableClick(newUserForm.$valid)" novalidate>
<input type="text" name="input1" ng-model="form.input1" required>
<input type="text" name="input2" ng-model="form.input2" required>
<input type="text" name="input3" ng-model="form.input3"> //not required
<button type="submit" ng-disabled="isDisabled">Disable ng-click</button>
</form>
so what we've got here, which you're missing:
You did name your form, but you're missing a submit, in the form as ng-submit or the button with type="submit", which will submit the form and that's when the validation happens
In order for Angular to validate your inputs, they need to have ng-model, otherwise it will not validate (HTML5 validation would, but read on)
I've added novalidate so we tell the browser "Hey, we need this validated but not by you, so do nothing", and Angular takes over
And last but not least, Angular adds a couple of properties to the form (see more here: Angular form Docs), $valid being one of them, which is set to true when all validated inputs are valid.
So this sums up the changes you needed to do to your form.
As for the Javascript part, there is just one small change:
$scope.disableClick = function(valid) {
if(valid && !$scope.isDisabled) {
$scope.isDisabled = true;
}
return false;
}
I guess the change is obvious, but I'll explain anyway - check that newUserForm.$valid (boolean) and if it's true (meaning form has passed validation) disable this button.
Of course, you'll have to add checks not to run the code on any type of submits and not just disabling the button (which can easily be re-enabled via Dev Tools), so that's why I added !$scope.isDisabled to the if statement.
Hope this answers your question :)
P.S. Here's a running demo in Plunker

How to get ui.bootstrap timepicker control to pass validation by default, without user interacting with control

When the timepicker control is inside a form and has an initial 'valid' default value, it should validate and $scope.formname.$valid should be true. However, what I am seeing is that unless the user interacts with the control, it's not validated and the form is not in valid state, this is not acceptable since the user may not even want to change the default time value. Any ideas what can be done for angular to validate the control with its default value and form respectively.
https://plnkr.co/edit/p1I2NoNpg3XMzijHUadi?p=preview
<form name="myForm" novalidate>
<uib-timepicker ng-model="time" template-url="timepicker.html" hour-step="1" ng-required="true" minute-step="1" show-meridian="false" ></uib-timepicker>
<input type="submit" value="Form state" ng-click="alertState()"></button>
</form>
var app = angular.module('demo',['ui.bootstrap']);
app.controller('myCtrl',[ '$scope', function($scope) {
$scope.alertState = function() {
alert($scope.myForm.$valid);
};
}]);

How to submit a form with pressing tab or enter (form contains hidden fields) in Angular Js

form with pressing tab or enter (form contains hidden fields) in Angular Js.
Here is my controller code
$scope.preview = function(pre)
{
$scope.master = angular.copy(pre);
};
Here is my view template code
<form ng-submit="preview(pre)" name="form" novalidate>
<input type="hidden" ng-model="item.name" name='pre.name' value='{{item.name}}'ng-show="item.name==product.name">
<input type="hidden" ng-model="item.sku" name='pre.sku' value='{{item.sku}}'ng-show="item.name==product.name">
<input type="hidden" ng-model="item.price" name='pre.price' value='{{item.price}}'ng-show="item.name==product.name">
<input ng-model="item.quantity" name='pre.quantity' value='{{item.quantity}}'ng-show="item.name==product.name"> // After changing the quantity then by pressing tab or enter the data have to submit
</form>
<pre>form = {{pre | json}}</pre> // have to show all the values which we giving in the form
Having it submit on enter is easy: Add a submit button which isn't visible for the user: http://plnkr.co/edit/WFtx5tJydqCI2usK6FhP?p=preview
To have it submit on tab, you'll need to write a custom directive which listens to key events.
Also:
When using ng-model, there's no need to set the value of an input
ng-show on hidden inputs is not doing anything. If you want to omit these fields, use ng-if

How to use Angular input fields email validation inside controller?

I'm trying to validate a variable as email inside Angular controller.
var valid = $filter('email')($scope.email);
The email filter doesn't exists, generates "unknown provider error". What's the correct way to access email validation from inside the controller?
Thanks.
Later edit: don't put me to create a custom filter, it must be a way using angular validation.
You can create a hidden input type email:
<input type="email" hidden id="emailValidator" required ng-model="x" />
Then in js set the value to that input and check validity:
var validator = $('#emailValidator')[0];
validator.value = "someemail#tovalidate.com";
return validator.checkValidity();
Also this documentation could be helpful: https://docs.angularjs.org/guide/forms
You could use form and prevent form submission by adding ng-disabled to the submit button:
<form name="form">
<input type="email" ng-model="email" name="email" required/>
<button type="submit"
ng-disabled="form.$invalid">Submit</button>
</form>
{{form.email.$valid}}
As the point of validation is to prevent submission and show error messages. I think it's enough to do it there instead of controllers where you handle your business logic.
DEMO
You can write your own filter:
angular.module(/**some module description here**/).
filter('email',function(){
var validateEmail = function(email) {
var re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
return function(input){
return validateEmail(input);
};
});
Regular expression is borrowed from here

prevent default on submit :- Angularjs

I want to prevent-default action of http-post to '/signUp' if e-mail is null upon filling form.
Controller Code:-
$scope.signUp = function() {
if($scope.email = null);
preventdefault;
}
html (jade) :-
form(name="input", action="/signUp", method="post")
input(type="submit", value="submit")
When you have the action attribute specified for the form, angularjs will not do preventDefault.
If you remove it and add ng-submit instead:
<form name="myForm" method="post" ng-submit="signUp(myForm)" novalidate>
<input type="email" name="email" ng-model="newSignup.email" required>
<button type="submit">sign up</button>
</form>
In this case the form will always have preventDefault and on submit your $scope.signUp() function will be called where you can proceed with an ajax post to the backend /signup or further validation.
Note that by using proper validation attributes on your inputs (like type="email" and required), angularjs will perform some basic validation for you.
You can have an extra ng-disabled="!myForm.$valid" on the submit button to keep the button disabled while the email is not correctly entered.
By using ng-model on the inputs like in my example, your scope will get a $scope.newSignup object which you can check in your signUp() function for further validation:
$scope.signUp = function(htmlForm) {
if ($scope.newSignup.email !== 'some#email.com') {
return false; // you should really show some info to the user
}
...
}

Resources