I'm working on form validations in angularjs and so far i have completed 99%. But the issue is my form validation works correct only for first time submit only. it's confusing to explain but i'll try my best to explain :P .here it is. When i reset my form it is showing error messages that the fields are empty(As it should).like this
After that if i fill 2 fields and submit again i'll work correctly as it should.like this
Now my problem comes.If i reset my form (fields get cleared) and submit the form, only description field error is shown but not in other two.like this
My code
<form name="userForm" ng-submit="submitForm(userForm.$valid, user)" novalidate>
<!-- NAME -->
<div class="form-group" ng-class="{ 'has-error' : userForm.name.$invalid && userForm.name.$dirty && submitted || (userForm.name.$invalid && userForm.name.$pristine) && submitted }">
<label>Name*</label>
<input type="text" name="name" class="item-input-wrapper" ng-model="user.name" required>
<label><p ng-show="submitted && userForm.name.$error.required" class="help-block "><font color="#009ACD">You name is required.</font></p></label>
</div>
<!-- EMAIL -->
<div class="form-group" ng-class="{ 'has-error' : userForm.email.$invalid && userForm.email.$dirty && submitted || userForm.email.$invalid && userForm.email.$pristine && submitted }">
<label>Email</label>
<input type="email" name="email" class="item-input-wrapper"ng-model="user.email" required >
<label><p ng-show="userForm.email.$invalid && userForm.email.$dirty && submitted || userForm.email.$invalid && userForm.email.$pristine && submitted" class="help-block"><font color="#009ACD">Enter a valid email.</font></p></label>
</div>
<!-- DESCRIPTION -->
<div class="form-group" ng-class="{ 'has-error' : userForm.username.$invalid && userForm.username.$dirty && submitted || userForm.username.$invalid && userForm.username.$pristine && submitted }">
<label>Description</label>
<input type="text" name="username" class="item-input-wrapper" ng-model="user.username" ng-minlength="5" ng-maxlength="60" required>
<label><font color="white"><p ng-show="userForm.username.$error.minlength && submitted" class="help-block"><font color="#009ACD">Description is too short.</font></p></label>
<label><p ng-show="userForm.username.$error.maxlength && submitted" class="help-block"><font color="#009ACD">Description is too long.</font></p></label>
<label><p ng-show="submitted && userForm.username.$error.required" class="help-block "><font color="#009ACD">Description is required.</font></p></label>
</div>
<div class="col"style="text-align: center">
<button align="left"class="button button-block button-reset" type="reset" value="Reset" style="display: inline-block;width:100px;text-align:center "
ng-click="submitted=false" padding-top="true">Reset</button>
<button class="button button-block button-positive" style="display: inline-block;width:100px "
ng-click="submitted=true" type="submit" padding-top="true">Submit</button>
</div>
</form>
</div>
$setPristine(); may be useful for what you looking for. Try to add like this as shown below...
<button class="button" type="reset" ng-click="form.$setPristine()">Reset</button>
For further information and for working demo refer the below link
AngularJS does not proper handle button type="reset"?
you can also refer the below link for setting up the form to pristine state
Reset form to pristine state (AngularJS 1.0.x)
figured out the solution
inside your controller add this
$scope.reset = function() {
$scope.user = angular.copy($scope.orig);
$scope.userForm.$setPristine();
};
Here 'userForm' should be your form name and 'user' should be your model.
This works for me.try it.
<form name="forms.sample" novalidate>
<md-input-container class="md-block" flex-gt-sm>
<label>Name:</label>
<input ng-focus="focus=true" ng-blur="focus=false" style="width:400px;" class="form-control" name="Name" type="text" data-ng-model="Name" ng-pattern="SomePattern" required placeholder="enter the Name here" />
<div ng-messages for="forms.sample.Name.$error" ng-if="!focus">
<div ng-if='forms.sample.Name.$touched' ng-message="required">This is required.</div>
<div ng-if='forms.sample.Name.$touched' ng-message="pattern">Enter a valid domain name</div>
</div>
</md-input-container>
</form>
Related
I am using ng-message for validation. when I click on forgot PIN its validation both field but I want only account number field. But when I click on "LOGIN TO PAYBACK AND REDEEM" it should validate both.
my form is like this
<form class="row" ng-if="!$ctrl.paybackLoggedin" name="paybackForm" novalidate>
<div class="col-sm-8 col-md-5">
<div class="form-group" ng-class='{ "has-success" : paybackForm.paybackalias.$valid, "has-error": paybackForm.paybackalias.$invalid && (paybackForm.$submitted || paybackForm.paybackalias.$dirty), "is-empty": !paybackForm.paybackalias.$viewValue }'>
<input class="form-control" name="paybackalias" pattern="\d{10}|\d{16}" ng-model="$ctrl.paybackAlias" placeholder="Mobile Number / Payback Card Number" type="text" onkeypress='return event.charCode >= 48 && event.charCode <= 57' ng-minlength="10" ng-maxlength="16" required>
<div ng-show="paybackForm.paybackalias.$invalid && !paybackForm.paybackalias.$pristine" ng-messages="paybackForm.paybackalias.$error" class="help-block">
<span ng-message="required">This field is required</span>
<span ng-message="maxlength || minlength">Enter a valid Phone number or Payback account</span>
</div>
</div>
</div>
<div class="col-sm-4 col-md-2">
<div class="form-group" ng-class='{ "has-success" : paybackForm.paybackpin.$valid, "has-error": paybackForm.paybackpin.$invalid && (paybackForm.$submitted || paybackForm.paybackpin.$dirty), "is-empty": !paybackForm.paybackpin.$viewValue }'>
<input class="form-control" name="paybackpin" ng-model="$ctrl.paybackPin" placeholder="Payback PIN" type="text" onkeypress='return event.charCode >= 48 && event.charCode <= 57' ng-minlength="4" ng-maxlength="4" required>
<div ng-show="paybackForm.paybackpin.$invalid && !paybackForm.paybackpin.$pristine" ng-messages="paybackForm.paybackpin.$error" class="help-block">
<span ng-message="required">This field is required</span>
<span ng-message="maxlength || minlength">Enter a valid PIN number</span>
</div>
<small class="help-block text-right"><button class="btn-link-default" ng-click="paybackForm.paybackalias.$valid && $ctrl.paybackForgotPass()">Forgot PIN</button></small>
</div>
</div>
<div class="col-md-5">
<div class="form-group">
<button class="btn btn-block btn-default" ng-click="paybackForm.$valid && $ctrl.paybackLogin()">LOGIN TO PAYBACK AND REDEEM</button>
</div>
</div>
</form>
Since you are using the client side validation on the html you cant pick and choose what will validate, in you'r case i'l suggest to do the validation on you'r on in the submit function for example,
I have two fields password and confirm password and an error message in tag i.e "password mismatch" but it should be displayed when password is typed incorrectly in confirm password field instead it is already being displaying when I opens the form.
HTML
<div class="form-group" ng-class="{ 'has-error': submitted && CreateClientAdminForm.password.$error.required || CreateClientAdminForm.password.$error.pattern }" >
<label class="col-md-4 control-label" for="password">Password*</label>
<div class="col-md-4">
<input id="password" name="password" type="password" placeholder="Password" class="form-control input-md" ng-model="clientAdmin.User.UserPassword" ng-pattern="regex.Password" ng-maxlength="20" required autofocus>
<span ng-show="submitted && CreateClientAdminForm.password.$error.required" class="help-block">Password can not be empty</span>
<span ng-show="CreateClientAdminForm.password.$error.pattern && CreateClientAdminForm.password.$invalid " class="help-block">Please enter a valid password with at least 6 characters. </span>
</div>
</div>
<!-- Password input-->
<div class="form-group" ng-class="{ 'has-error': submitted && CreateClientAdminForm.confirmpassword.$error.required || CreateClientAdminForm.confirmpassword.$error.pattern }" >
<label class="col-md-4 control-label" for="confirmpassword">Confirm Password*</label>
<div class="col-md-4">
<input id="confirmpassword" name="confirmpassword" type="password" placeholder="Password" class="form-control input-md" ng-model="clientAdmin.User.UserconfirmPassword" ng-pattern="regex.Password" ng-maxlength="20" required autofocus>
<span ng-show="submitted && CreateClientAdminForm.confirmpassword.$error.required" class="help-block">Password can not be empty</span>
<span ng-show="clientAdmin.User.UserPassword !== clientAdmin.User.UserconfirmPassword" class="help-block"><p>Password mismatch</p></span>
<span ng-show="CreateClientAdminForm.confirmpassword.$error.pattern && CreateClientAdminForm.confirmpassword.$invalid " class="help-block">Please enter a valid password with at least 6 characters. </span>
</div>
</div>
Controller
globalWeAlertApp.controller("ClientAdminController", function($scope, ClientAdminService,UserCRUDService, toastr, $cookieStore, $window ) {
//Other functions
}
<span
ng-show="clientAdmin.User.UserPassword != clientAdmin.User.UserconfirmPassword
&& (clientAdmin.User.UserPassword != '' &&
lientAdmin.User.UserconfirmPassword != '' )"
class="help-block">
<p>Password mismatch</p>
</span>
I have found some custom code online for simple login form:
<div class="col-md-6 col-md-offset-3">
<h2>Login</h2>
<form name="form" ng-submit="form.$valid && vm.login()" novalidate>
<div class="form-group" ng-class="{ 'has-error': form.$submitted && form.username.$invalid }">
<label for="username">Username</label>
<input type="text" name="username" class="form-control" ng-model="vm.username" required />
<div ng-messages="form.$submitted && form.username.$error" class="help-block">
<div ng-message="required">Username is required</div>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error': form.$submitted && form.password.$invalid }">
<label for="password">Password</label>
<input type="password" name="password" class="form-control" ng-model="vm.password" required />
<div ng-messages="form.$submitted && form.password.$error" class="help-block">
<div ng-message="required">Password is required</div>
</div>
</div>
<div class="form-group">
<button class="btn btn-primary">Login</button>
</div>
<div ng-if="vm.error" class="alert alert-danger">{{vm.error}}</div>
</form>
</div>
Currently, ng-messages with content: 'Username is required' and 'Password is required' are always visible.
Is there any chance I can change this code in a way I see that messages only when authentication fails?
Or in other words can I hide them in HTML, because I guess I have to show them through angular code.
Set an ng-if on your div, checking for the errors:
ng-if="form.password.$error"
ng-if="form.username.$error"
This will ensure that the div only shows if an error in your form exists, specific to those elements.
You can use FormController.$dirty or FormController.$pristine
By Angular Docs:
$pristine: True if user has not interacted with the form yet.
$dirty: True if user has already interacted with the form.
<div ng-if="form.$dirty && vm.error" class="alert alert-danger">{{vm.error}}</div>
I have couple of fields in my form & I want to enable submit button if anyone of them is filled, how I can do this? If I put required to both or anyone of them then it won't work as I want.
<input type="text" name="phone">
<span ng-show="form.addContactForm.phone.$touched && form.addContactForm.phone.$error.required">Phone number or email is required</span>
<input type="text" name="email">
<span ng-show="form.addContactForm.email.$touched && form.addContactForm.email.$error.required">Phone number or email is required</span>
<button type="submit" ng-disabled="form.addContactForm.$invalid || form.addContactForm.$submitted">Submit</button>
If phone or email is entered then other message should hide
You just add the conditions in
<input type="text" name="phone" ng-model="ctrl.phone">
<span ng-show="(form.addContactForm.phone.$touched || form.addContactForm.email.$touched) && !ctrl.phone && !ctrl.email">Phone number or email is required</span>
<input type="text" name="email" ng-model="ctrl.email">
<span ng-show="(form.addContactForm.phone.$touched || form.addContactForm.email.$touched) && !ctrl.phone && !ctrl.email">Phone number or email is required</span>
<button type="submit" ng-disabled="(!ctrl.phone && !ctrl.email) || form.addContactForm.$invalid || form.addContactForm.$submitted">Submit</button>
Edit: Add error message and condition
Simplest solution, if this form is all you have: Use ng-required and make the condition in each field dependent on the other field. I even added a ng-disabled so that, if a field is filled-in, the other becomes disabled. I did not include the error messages for clarity - use the <span>s you already have.
<div ng-app="app" ng-controller="Ctrl as c">
<form name="contactForm">
<input ng-model="c.phone" type="text" name="phone"
ng-required="!c.email" ng-disabled="c.email" />
<input ng-model="c.email" type="text" name="email"
ng-required="!c.phone" ng-disabled="c.phone" />
<button ng-disabled="contactForm.$invalid">Submit</button>
</form>
</div>
Relevant fiddle: https://jsfiddle.net/k0L7c7jh/
If the model becomes larger, solutions like this (i.e. validation rules directly on the UI) do not scale well. For this I like model validations and to that end I created and I am using in my work egkyron, a JS validation framework that binds well with Angular (as well as with others).
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<h2>Validation Example</h2>
<form ng-app="myApp" ng-controller="validateCtrl"
name="myForm" novalidate>
<p>Username:<br>
<input type="text" name="user" ng-model="user" required>
<span style="color:red" ng-show="myForm.user.$dirty && myForm.user.$invalid">
<span ng-show="myForm.user.$error.required">Username is required.</span>
</span>
</p>
<p>Email:<br>
<input type="email" name="email" ng-model="email" required>
<span style="color:red" 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>
<p>
<input type="submit"
ng-disabled="myForm.user.$dirty && myForm.user.$invalid ||
myForm.email.$dirty && myForm.email.$invalid">
</p>
</form>
<script>
var app = angular.module('myApp', []);
app.controller('validateCtrl', function($scope) {
$scope.user = 'John Doe';
$scope.email = 'john.doe#gmail.com';
});
</script>
</body>
</html>
I have this form with validation in AngularJS:
<form ng-app="myApp" ng-controller="validateCtrl as validate" name="myForm" action="sendEmail" novalidate>
<div class="form-group">
<input type="email" name="email" class="form-control" ng-model="validate.email" placeholder="Email" required>
<span style="color:yellow" 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>
</div>
<div class="form-group">
<input type="text" name="subject" class="form-control" ng-model="validate.subject" placeholder="Subject" required>
<span style="color:yellow" ng-show="myForm.subject.$dirty && myForm.subject.$invalid">
<span ng-show="myForm.subject.$error.required">Subject is required.</span>
</span>
</div>
<div class="form-group">
<textarea type="text" name="message" class="form-control" ng-model="validate.message" placeholder="Message..." required></textarea>
<span style="color:yellow" ng-show="myForm.message.$dirty && myForm.message.$invalid">
<span ng-show="myForm.message.$error.required">Message is required.</span>
</span>
</div>
<button type="submit" class="btn btn-lg btn-success"
ng-disabled="myForm.email.$dirty && myForm.email.$invalid ||
myForm.subject.$dirty && myForm.subject.$invalid ||
myForm.message.$dirty && myForm.message.$invalid"></button>
</form>
The button is disabled until the email, subject and message aren't correct. Ok, it's fine. But that is true, only if I have already interacted with the form.
In fact, when the page is loaded the first time and I haven't interacted with the form yet, the button is enabled. So, if I click it, I could send an empy email! I would that when the page is loaded the button is disabled and when I fill the fields become enabled.
How can I do that?
Thanks.
You first condition can be ng-disabled=" myForm.email.$invalid . Remove "myForm.email.$dirty
Try like this
<form name="postForm" method="POST" novalidate>
<div class="col-md-8">
<div class="col-md-12">
<div class="col-md-12"><legend>Submit New Post</legend></div>
</div>
<div class="col-md-12 form-group">
<div class="col-md-12" ng-class="{ 'has-error' : postForm.title.$invalid && !postForm.title.$pristine }">
<input type="text" placeholder="Write Title" class="form-control" name="title" ng-model="post.title" required>
<p ng-show="postForm.title.$invalid && !postForm.title.$pristine" class="text-danger">* Write Post Title</p>
</div>
</div>
<div class="col-md-12 form-group">
<div class="col-md-12" ng-class="{ 'has-error' : postForm.url.$invalid && !postForm.url.$pristine }">
<input type="url" placeholder="Write URL" class="form-control" name="url" ng-model="post.url" >
<p ng-show="postForm.url.$invalid && !postForm.url.$pristine" class="text-danger">* Write URL in http:// or https:// Format</p>
</div>
</div>
<div class="col-md-12">
<div class="col-md-12" >
<p class="text-danger">{{msg}}</p>
</div>
</div>
<div class="col-md-12 form-group">
<div class="col-md-12"><button type="submit" class="btn btn-info" ng-disabled="postForm.$invalid" ng-click="submitForm(....)">Submit</button>
<img src="img/loading.gif" ng-show="loading" /></div>
</div>
</div>
</form>
On your submit button, modify the ng-disabled to this:
ng-disabled="myForm.$invalid || myForm.$pristine">
In this case, you don't have to validate all your inputs separetely. Just test if your form is invalid OR if the user never interacted with it yet.
A form in AngularJS has two different states: pristine and dirty. The pristine indicates that your form was never touched. And dirty is the opposite. When the user set any value to one of your inputs, the angular change the state of your form from pristine to dirty.
I guess this post is a good reference to read about forms in angular