AngularJS show error when submitting - angularjs

I am using AngularJS step wizard and inside the form for the first step I need validation errors to appear when the use tries to hit submit. Right now I have the following:
<span class="error" ng-show="user.validate.step1.firstname.$invalid">Required Field</span>
But the error shows when I first goto the step and when I start typing in the field it goes away, I would like this to appear when the user tries to hit submit, not when they first goto the step. I already have this to indicate a required field
<span class="error">*</span>
Here is the full code:
<form name="user.validate.step1" novalidate>
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="firstname" class="col-md-4 form-label">First Name:</label>
<div class="col-md-8">
<div class="input-group">
<input class="form-control" type="text" name="firstname" ng-model="user.firstname" value="{{user.firstname}}" ng-blur="blur1=true" required />
<span class="error" ng-show="user.validate.step1.firstname.$invalid">*</span>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
keep in mind I have more than one input in this form.

Add the validation in the button using ng-click="validateInputs()" and create a var invalidEntry and a function validateInputs() to check if the input is valid or not. Something like this:
var inputs = [inputModel1,inputModel2,inputModel3];
function validateInputs(){
invalidEntry = false;
for(e in inputs){
if(CheckInvalid(inputs[e])){
invalidEntry = true;
return;
}
}
}
function CheckValid(string){
if(string == "" || string === null || string === undefined){
return true;
} else {
return false;
}
}
The submit button:
<button ng-click="validateInputs()">Submit</button>
And the span:
<span class="error" ng-show="invalidEntry">Required Field</span>
And the inputs should look like this:
<input type="text" ng-model="inputModel1"></input>
<input type="text" ng-model="inputModel2"></input>
<input type="text" ng-model="inputModel3"></input>

You should change ngShow in following way
ng-show="user.validate.step1.firstname.$invalid && !user.validate.step1.firstname.$pristine"
Check this article block AngularJS Form Validation: Only Showing Errors After Submitting the Form

Related

Resting Form and Clear Error Validations in register form on clicking a button

I am doing one register page using angularjs.
Follows my html code:
<form name="frominline" action="post" class="clearfix form-hidden" id="Register-form">
<div class="col-md-12">
<div class="input-group blmd-form">
<div class="blmd-line">
<input type="text" name="userid" autocomplete="off" id="username" class="form-control" required autofocus="" ng-model="user.name" ng-minlength="3" ng-maxlength="12" ng-model-options="{ allowInvalid: true }">
<label class="blmd-label">User Id</label>
</div>
<p class="login-error" ng-show="frominline.userid.$dirty && frominline.userid.$error.required">
<span style="color : red">required</span>
</p>
<p ng-show="frominline.userid.$error.minlength" class="help-block" style="color:red;">Username is too short.</p>
<p ng-show="frominline.userid.$error.maxlength" class="help-block" style="color:red;">Username is too long.</p>
</div>
<div class="input-group blmd-form">
<div class="blmd-line">
<input type="email" name="email" autocomplete="off" id="email" class="form-control" required autofocus="" ng-model="user.email">
<label class="blmd-label">Email</label>
</div>
<span class="login-error" ng-show="frominline.email.$error.required && frominline.email.$dirty" style="color:red;" ng-model-options="{ allowInvalid: true }">required</span>
<span class="login-error" ng-show="!frominline.email.$error.required && frominline.email.$error.email && frominline.email.$dirty" style="color:red;">invalid email</span>
</div>
<button type="reset" ng-click="resetform(frominline)">reset</button>
</form>
My js code:
app.controller('loginCtrl'['$scope',function('$scope'){
var user = this;
$scope.resetform(form){
user.name='';
user.email='';
$scope.frominline.$dirty = false;
$scope.frominline.$pristine = true;
$scope.frominline.$submitted = false;
}]);
Now, in first image, those are the validation errors.
Now, I hit the reset button and the validation errors are gone but in the second image I got required field.
Can you please help me removing or reseting the whole form on a button click?
I tried with many options like $setPristine() or $setValidity() but i can't fix this issue "required" error message.
Follows the image of the form with only required error message after clicking reset button:
The form is probably cleared, but those input fields are not. When you are display the error for a particular field (e.g. ng-show="frominline.userid.$error.minlength") include the state of the form as well (e.g. ng-show="frominline.$submitted && frominline.userid.$error.minlength").

form.$valid is working for "required" but it's not working for ngPattern and maxlength.

If zipcode is empty then form is invalid so button is disabled but if zipcode is 2 digits error message is showing but form is showing as valid in controller. If zipcode is empty then I need to disable button but I'm checking form valid or not but dont worry about ng-disabled. I just need solution for showing the "div" if and only if form is valid.
function submitUserDetail (formValid) {
if(formValid) {
$scope.showDiv = true;
}
}
<div class="">
<div class="">
<label required>
Zip code required
</label>
<label pattern>
Invalid Zip code
</label>
</div>
<div class="">
<input type="tel" maxlength="5" class="" name="zip5"
ng-model="userDetail.zipCode" required=""
pattern="^\d{5}$"
data-validate-on-blur="true" value=""
size="5">
<span class="" title="Reset" onclick="jQuery(this).prev('input').val('').trigger('change');"></span>
</div>
</div>
<div class="">
<div class="">
<div class="">
<span class=""></span>
<button class="" href="#" id="button" ng-click="submitUserDetail(form.$valid)" ng-disabled="form.$invalid">See section</button>
<span class=""></span>
</div>
</div>
</div>
<div ng-if="showDiv">
.......
</div>
Thanks in advance.
I assume that you have a <form> wrapping the HTML provided.
If so, you should make sure your <form> tag has novalidate applied so you're using AngularJS form validation and not HTML5 form validation:
<form name="form" ng-submit="submitUserDetail(form.$valid)" novalidate>
Also, it looks like you're mixing HTML5 validation attributes with AngularJS validation attributes. You should be using ng-required and ng-pattern instead of required and pattern.

angular validation - prevent button ng-click() when form is invalid

I have an angular form as part of a single page App. The 'Continue' button moves a user to the next section of the app, and has an ng-click. I would like to prevent this ng-click from happening when the button is clicked and the form is invalid, but I don't want to disable the Continue button.
Example: A user comes to the page and immediately clicks the Continue button without providing a first name. The error message "You should provide a first name" is shown and the user remains on the page.
How can I do this? Here is the code:
<form name="form" novalidate >
<div ng-show="form.FirstName.$touched && form.FirstName.$error.required" class="errorMessage">
You must enter a first name
</div>
<div class="form-group">
<label for="firstName" class="form-label">First Name</label>
<input id="firstName" class="form-control" name="FirstName" ng-model="vm.user.firstName" required />
</div>
<div class="btn-group">
<button ng-click="vm.next()">Continue</button>
</div>
</form>
Just add form.$valid && before the function call:
<form name="form" novalidate >
<div ng-show="form.FirstName.$touched && form.FirstName.$error.required" class="errorMessage">
You must enter a first name
</div>
<div class="form-group">
<label for="firstName" class="form-label">First Name</label>
<input id="firstName" class="form-control" name="FirstName" ng-model="vm.user.firstName" required />
</div>
<div class="btn-group">
<button ng-click="form.$valid && vm.next()">Continue</button>
</div>
</form>
Either a button is disabled or it's clickable, you can't have it both ways.
What you could do in your controller for vm.next() is say:
myApp.controller('Page1Controller'), ['$scope', function ($scope)
{
$scope.vm = {};
$scope.vm.next = function()
{
if (! $scope.vm.isFormValid())
return;
//move to the next page with your current code
...
}
$scope.vm.isFormValid()
{
$scope.vm.shouldShowError = $scope.form.valid; //add vm.shouldShowError to your error message ng-show in the view so it will display only after clicking continue
return $scope.form.valid;
}
}]);

validate form on button in angularjs

I have to validate a form only after click on button. Now it is working on blur and focus. How can I disable focus and blur validation and validate them on button click. fiddle
<form ng-app="form-example" class="row form-horizontal" novalidate>
<div class="control-group">
<label class="control-label" for="inputEmail">Email</label>
<div class="controls">
<input type="email" id="inputEmail" placeholder="Email" ng-model="email" required>
<div class="input-help">
<h4>Invalid Email</h4>
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" for="inputPassword">Password</label>
<div class="controls">
<input ng-model="password" class="immediate-help" required type="password" id="inputPassword" placeholder="Password">
<div class="input-help">
<ul>
<li>required</strong></li>
</ul>
</div>
</div>
</div>
<div class="control-group">
<div class="controls">
<button class="btn">Create Account</button>
</div>
</div>
</form>
You could have dummy class on your form level that will tell the form has been submitted or not like ng-class="{submitted: submitted}", and on click of button we will use ng-click="submitted=true" so that after clicking on button form will have submitted class on it. Then we will apply our CSS rule for ng-invalid & ng-dirty to also consider an .submitted class by using concept of deep nesting of classes.
/* Show red border when stuff has been typed in, but its invalid */
.submitted .ng-dirty.ng-invalid {
border-color:#ec3f41;
}
Other CSS rules should be taken care of this thing like I shown above.
the problem is that you just added the validation and you're showing the message on ng-invalid ( with css). here is an example of working code to do what you want.
<div class="form-group col-xs-12 required" ng-class="{ 'has-error' : creditCardDetailsForm.security_code.$invalid && submitted}">
<label class="col-lg-28 col-l-5 col-md-5 text-left font-l-20 primary control-label">Security code (CVC) </label>
<div class="col-lg-3 col-md-4 text-left">
<input class="form-control" name="security_code" data-stripe="cvc" ng-model="payment_details.security_code" type="number" minLength="3" required>
<p ng-show="creditCardDetailsForm.security_code.$invalid && submitted" class="help-block">Security code is required.</p>
<p ng-show="creditCardDetailsForm.security_code.minLength.$invalid && submitted" class="help-block">Invalid CVC.</p>
</div>
</div>
see, here I check if the form is invalid and the submitted has been clicked...
in my controller:
$scope.purchasePackage = function (status, response) {
$scope.submitted = true;
if ($scope.creditCardForm.creditCardDetailsForm.$valid) {
//do something
}
};
since you did your hide and show with CSS you can just add the class on click to the form and then do .submitted .ng-invalid so it only shows up after you have submitted.

Validate form field only on submit or user input

I have form fields that are validated using required. The problem is, that the error is displayed immediately when the form is rendered. I want it only to be displayed after the user actually typed in the text field, or on submit.
How can I implement this?
Use $dirty flag to show the error only after user interacted with the input:
<div>
<input type="email" name="email" ng-model="user.email" required />
<span ng-show="form.email.$dirty && form.email.$error.required">Email is required</span>
</div>
If you want to trigger the errors only after the user has submitted the form than you may use a separate flag variable as in:
<form ng-submit="submit()" name="form" ng-controller="MyCtrl">
<div>
<input type="email" name="email" ng-model="user.email" required />
<span ng-show="(form.email.$dirty || submitted) && form.email.$error.required">
Email is required
</span>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
function MyCtrl($scope){
$scope.submit = function(){
// Set the 'submitted' flag to true
$scope.submitted = true;
// Send the form to server
// $http.post ...
}
};
Then, if all that JS inside ng-showexpression looks too much for you, you can abstract it into a separate method:
function MyCtrl($scope){
$scope.submit = function(){
// Set the 'submitted' flag to true
$scope.submitted = true;
// Send the form to server
// $http.post ...
}
$scope.hasError = function(field, validation){
if(validation){
return ($scope.form[field].$dirty && $scope.form[field].$error[validation]) || ($scope.submitted && $scope.form[field].$error[validation]);
}
return ($scope.form[field].$dirty && $scope.form[field].$invalid) || ($scope.submitted && $scope.form[field].$invalid);
};
};
<form ng-submit="submit()" name="form">
<div>
<input type="email" name="email" ng-model="user.email" required />
<span ng-show="hasError('email', 'required')">required</span>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
If you want to show error messages on form submission, you can use condition form.$submitted to check if an attempt was made to submit the form. Check following example.
<form name="myForm" novalidate ng-submit="myForm.$valid && createUser()">
<input type="text" name="name" ng-model="user.name" placeholder="Enter name of user" required>
<div ng-messages="myForm.name.$error" ng-if="myForm.$submitted">
<div ng-message="required">Please enter user name.</div>
</div>
<input type="text" name="address" ng-model="user.address" placeholder="Enter Address" required ng-maxlength="30">
<div ng-messages="myForm.name.$error" ng-if="myForm.$submitted">
<div ng-message="required">Please enter user address.</div>
<div ng-message="maxlength">Should be less than 30 chars</div>
</div>
<button type="submit">
Create user
</button>
</form>
You can use angularjs form state form.$submitted.
Initially form.$submitted value will be false and will became true after successful form submit.
Erik Aigner,
Please use $dirty(The field has been modified) and $invalid (The field content is not valid).
Please check below examples for angular form validation
1)
Validation example HTML for user enter inputs:
<form ng-app="myApp" ng-controller="validateCtrl" name="myForm" novalidate>
<p>Email:<br>
<input type="email" name="email" ng-model="email" required>
<span ng-show="myForm.email.$dirty && myForm.email.$invalid">
<span ng-show="myForm.email.$error.required">Email is required.</span>
<span ng-show="myForm.email.$error.email">Invalid email address.</span>
</span>
</p>
</form>
2)
Validation example HTML/Js for user submits :
<form ng-app="myApp" ng-controller="validateCtrl" name="myForm" novalidate form-submit-validation="">
<p>Email:<br>
<input type="email" name="email" ng-model="email" required>
<span ng-show="submitted || myForm.email.$dirty && myForm.email.$invalid">
<span ng-show="myForm.email.$error.required">Email is required.</span>
<span ng-show="myForm.email.$error.email">Invalid email address.</span>
</span>
</p>
<p>
<input type="submit">
</p>
</form>
Custom Directive :
app.directive('formSubmitValidation', function () {
return {
require: 'form',
compile: function (tElem, tAttr) {
tElem.data('augmented', true);
return function (scope, elem, attr, form) {
elem.on('submit', function ($event) {
scope.$broadcast('form:submit', form);
if (!form.$valid) {
$event.preventDefault();
}
scope.$apply(function () {
scope.submitted = true;
});
});
}
}
};
})
3)
you don't want use directive use ng-change function like below
<form ng-app="myApp" ng-controller="validateCtrl" name="myForm" novalidate ng-change="submitFun()">
<p>Email:<br>
<input type="email" name="email" ng-model="email" required>
<span ng-show="submitted || myForm.email.$dirty && myForm.email.$invalid">
<span ng-show="myForm.email.$error.required">Email is required.</span>
<span ng-show="myForm.email.$error.email">Invalid email address.</span>
</span>
</p>
<p>
<input type="submit">
</p>
</form>
Controller SubmitFun() JS:
var app = angular.module('example', []);
app.controller('exampleCntl', function($scope) {
$scope.submitFun = function($event) {
$scope.submitted = true;
if (!$scope.myForm.$valid)
{
$event.preventDefault();
}
}
});
Invoking of validation on form element could be handled by triggering change event on this element:
a) exemple: trigger change on separated element in form
$scope.formName.elementName.$$element.change();
b) exemple: trigger change event for each of form elements for example on ng-submit, ng-click, ng-blur ...
vm.triggerChangeForFormElements = function() {
// trigger change event for each of form elements
angular.forEach($scope.formName, function (element, name) {
if (!name.startsWith('$')) {
element.$$element.change();
}
});
};
c) and one more way for that
var handdleChange = function(form){
var formFields = angular.element(form)[0].$$controls;
angular.forEach(formFields, function(field){
field.$$element.change();
});
};

Resources