How to use Angular input fields email validation inside controller? - angularjs

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

Related

AngularJS - perform extra validation on form submit

I've been googling for a while and can't seem to find a good answer for my specific case. I've found ways to do real-time validations but I want to combine that with some custom validations after a user clicks on "submit". I want to allow the user to still click on the submit even if it's not valid but then I'll cancel the submission in the code. Take the following code:
<form name="cashForm" id="cashForm" novalidate>
<input type="text" id="name" required /> //
<input type="number" placeholder="Tax: " required name="tax" id="tax" />
<input type="number" placeholder="Tip: " required name="tip" id="tip" />
<button ng-click="submission()" ng-disabled="paymentForm.$invalid">Submit</button>
</form>
//inside controller
this.submission = function() {
//check if tip + tax is over 20
//prevent form and show error message if not
//otherwise allow default behavior
}
So I only want the form to actually submit if the tax/tip is over 10. How do I check for this and how do I prevent the form submission if it doesn't meet the requirements? Also, would I put this logic in the controller?
It looks pretty close to what you're after to me. Just a couple of things...
Add ng-model directives to your input controls to create two-way data-bindings that you can pick up and use in your controller:
<form name="cashForm" id="cashForm" novalidate>
<input id="name" name="name" type="text" ng-model="nameValue" required />
<input id="tax" name="tax" type="number" ng-model="taxValue" placeholder="Tax: " required />
<input id="tip" name="tip" type="number" ng-model="tipValue" placeholder="Tip: " required />
<button
ng-click="submission()"
ng-disabled="paymentForm.$invalid">
Submit
</button>
Inject $scope into your controller to allow you to pick up those ng-model bindings in your controller's submission method:
function submission() {
$scope.errorMsg = "";
if ($scope.taxValue <= 10) {
$scope.errorMsg = "tax not greater than 10";
return;
}
if ($scope.tipValue <= 10) {
$scope.errorMsg = "tip not greater than 10";
return;
}
// If you reached here your post-click validation passed,
// so continue to submit the data...
}
You could then display an error message using the ng-if directive with a css class that highlights the error message:
<div ng-if="!!errorMessage" class="text-danger">
{{ errorMessage }}
</div>
Finally, once you've cracked using $scope in your controller you might want to read about the perceived evils of using $scope and consider switching to controller-as syntax instead. Check out John Papa's Blog Post AngularJS's Controller As and the vm Variable

How to reset validation after submitting a form in AngularJS?

I have one input field:
<input type="text" name="title" ng-model="genreData.title" class="form-control"
ng-class="{'error': addGenreForm.title.$invalid && !addGenreForm.title.$pristine}"
placeholder="Genre name" ng-minlength="minlength" required autofocus>
When I succesfully submit form this input is got class="error" after this:
$scope.genreData = {};
How can I fix it?
You've got to inject the form in the ng-submit function and then call the form's controller built in function $setPristine().
e.g.
View:
<form name="myForm" ng-submit="submitForm(myForm)">
<!--Input Fields-->
</form>
Controller:
$scope.submitForm = function(form) {
//Do what ever I have to do
//Then reset form
form.$setPristine();
}
I think setting
$scope.addGenreForm.$setPristine() and $scope.addGenreForm.$setUntouched
can work after submitting your form
Please share some plunker so I can help more if you still have any issues

Angular - Cannot read property '$invalid' of undefined

I am creating a login page using angular and typescript. When the submit button is clicked, I would like the login function in the controller to fire, but if the form is invalid then it just returns.
This is my first time using typescript, so every time I try to put in the if statement to check if the form is invalid it throws the error Cannot read property '$invalid' of undefined.
Here is the html:
<form class="login-form" name="loginForm" ng-submit="vm.login()" novalidate>
<input type="email" name="email" placeholder="Email" required ng-model="vm.email" ng-class="{true: 'input-error'}[submitted && loginForm.email.$invalid]"/>
<input type="password" name="password" placeholder="Password" required ng-model="vm.password" ng-class="{true: 'input-error'}[submitted && loginForm.password.$invalid]"/>
<input type="submit" id="submit" ng-click="submitted=true"/>
</form>
And here is the compiled javascript:
var LoginModule;
(function (LoginModule) {
var LoginController = (function () {
function LoginController() {
}
LoginController.prototype.login = function () {
if(this.loginForm.$invalid) {
return;
}
console.log("Login was clicked, email is " + this.email + " and password is " + this.password);
};
return LoginController;
})();
LoginModule.LoginController = LoginController;
})(LoginModule || (LoginModule = {}));
angular.module('loginModule', []).controller('LoginController', LoginModule.LoginController);
It looks like the common issue with this was that people were not specifying the form name, but that is not the case here. Does anyone know why I could be getting this error?
You need the controller alias in the form name
<form name="vm.loginForm" ng-submit="vm.login()" novalidate>
While #charlietfl's answer is correct for the OP's question, this error can also be thrown if you've missed the ng-model property on an input control and are using the ui.bootstrap.showErrors $scope.$broadcast('show-errors-check-validity') method.
As per the documentation (my emphasis):
.. an input control that has the ngModel directive holds an instance of NgModelController. Such a control instance can be published as a property of the form instance using the name attribute on the input control. The name attribute specifies the name of the property on the form instance.

Have AngularJS perform logic on form inputs when form submits

I currently have a form like the following:
<form autocomplete="on" enctype="multipart/form-data" accept-charset="UTF-8" method="POST" action="{{trustSrc(SUBMIT_URL)}}">
<input type="text" name="firstinput" ng-model="first"/>
<input type="text" name="secondinput" ng-model="second"/>
<input type='submit'/>
</form>
And a controller like so:
$scope.first = "first";
$scope.second = "second";
$scope.SUBMIT_URL = DATABASE_URL + "forms/submit/";
$scope.trustSrc = function(src) {
return $sce.trustAsResourceUrl(src);
};
And when I submit this form as is, it works just fine with the backend. However I now need to use ng-submit in place of the standard HTML form submit because I need to run a find and replace in $scope.first. The backend expects the data to be posted exactly in the way the original HTML form does. How do I use $http or $resource to post in the exact same format as the HTML form?
It is not very clear what you are trying to accomplish. But, you should tidy up your code a bit, to make the implementation easier:
Don't use different variables for each input's field. Instead, use an object with different keys.
Use ng-click (or ng-submit) for your submission. Action will go inside your JS logic.
Use the novalidate attribute so that Angular can properly format, and validate your form on its own (and you don't get confusing cross-browser effects).
With those in mind, your new markup would be:
<form autocomplete="on" enctype="multipart/form-data" accept-charset="UTF-8" novalidate>
<input type="text" name="first" ng-model="form.first" />
<input type="text" name="second" ng-model="form.second" />
<button ng-click="submit">Submit</button>
</form>
Your JS directive is then:
app.directive('form', function($http)
{
return function(scope, element, attrs)
{
// Leave this empty if you don't have an initial data set
scope.form = {
first : 'First Thing To Write',
second : 'Second item'
}
// Now submission is called
scope.submit = function()
{
// You have access to the variable scope.form
// This contains ALL of your form and is in the right format
// to be sent to an backend API call; it will be a JSON format
// Use $http or $resource to make your request now:
$http.post('/api/call', scope.form)
.success(function(response)
{
// Submission successful. Post-process the response
})
}
}
});

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