Custom validation in angular js - angularjs

Hi All of the angular developer, I am fetching a validation problem with angular js. I can do the validation under the Form, I can check every validate field by Form in angular js. but i want to do the same job by using Div instead of Form. many people suggested me that you can do by angular directives. but how? They did not clear to me.Here how will i check all validate directives under the Div?. I have not found any solution. Anyone have an idea or solution?. I have given my example below. now i want to validate this by using angular js directives. Thanks
<div name="userForm" novalidate>
<!-- NAME -->
<div class="form-group" ng-class="{ 'has-error' : userForm.name.$invalid && !userForm.name.$pristine }">
<label>Name*</label>
<input type="text" name="name" class="form-control" ng-model="user.name" required>
<p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">You name is required.</p>
</div>
<!-- USERNAME -->
<div class="form-group" ng-class="{ 'has-error' : userForm.username.$invalid && !userForm.username.$pristine }">
<label>Username</label>
<input type="text" name="username" class="form-control" ng-model="user.username" ng-minlength="3" ng-maxlength="8">
<p ng-show="userForm.username.$error.minlength" class="help-block">Username is too short.</p>
<p ng-show="userForm.username.$error.maxlength" class="help-block">Username is too long.</p>
</div>
<!-- EMAIL -->
<div class="form-group" ng-class="{ 'has-error' : userForm.email.$invalid && !userForm.email.$pristine }">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="user.email">
<p ng-show="userForm.email.$invalid && !userForm.email.$pristine" class="help-block">Enter a valid email.</p>
</div>
<button type="button" ng-click="Save()" class="btn btn-primary">Submit</button>
</div>

Use ng-form:
<div ng-form="userForm" novalidate>
...
</div>

You may follow the instruction below
http://www.breezejs.com/documentation/validation
http://www.breezejs.com/breeze-labs/breezedirectivesvalidation

Related

how to display all error messages in the form header in angularjs

I need to display all the messages at the top of the form and I need to implement the custom error for fields like email and phone number.
index.html
<form name="adminForm" ng-submit="addAdmin()" novalidate>
all error messages need to be displayed here
<div class="form-group" ng-class="{ 'has-error': adminForm.firstName.$touched && adminForm.firstName.$invalid }">
<label>First Name</label>
<input type="text" name="firstName" class="form-control" ng-model="admin.first_name" ng-maxlength="255" required>
<div class="help-block" ng-messages="adminForm.firstName.$error" ng-if="adminForm.firstName.$touched">
<div ng-messages-include="messages.html"></div>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error': adminForm.lastName.$touched && adminForm.lastName.$invalid }">
<label>Last Name</label>
<input type="text" name="lastName" class="form-control" ng-model="admin.last_name" ng-maxlength="255" required>
<div class="help-block" ng-messages="adminForm.lastName.$error" ng-if="adminForm.lastName.$touched">
<div ng-messages-include="messages.html"></div>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error': adminForm.email.$touched && adminForm.email.$invalid }">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="admin.email" ng-maxlength="255" required>
<div class="help-block" ng-messages="adminForm.email.$error" ng-if="adminForm.email.$touched">
<div ng-messages-include="messages.html"></div>
</div>
</div>
messages.html
<p ng-message="required">This field is required</p>
<p ng-message="minlength">This field is too short</p>
<p ng-message="maxlength">This field is too long</p>
<p ng-message="email">This needs to be a valid email</p>
<p ng-message="pattern">This needs to be a valid number</p>
<p ng-message="equals">Password must be same</p>
I'm looking for any possible solution or a reference to other possible solutions.
Reason : I'm finding difficulty in implementing unit tests for this(noob), so i think a single error message can make it easy for testing.
Thanks!

How to show error messages for Checkbox set and Radio set using ng-messages?

I have been trying to validate Checkbox set and Radio set and show the error messages using ng-messages directive but it does not work out as expected. The ng-messages does not show the error message at all. I am populating error messages using an html file. Up until the errors are resolved, the submit button will be disabled in my form.
How can I show error messages for the Checkbox set and Radio set when:
One option is not selected in Radio set?
At least one option is not selected in Checkbox set?
Scaling the check for the Checkbox set so that we can check at least 2 or more are checked, etc.?
Here's my form:
<form name="userForm" ng-submit="submitForm()" novalidate>
<div class="form-group" ng-class="{ 'has-error' : userForm.subscribe.$invalid && !userForm.subscribe.$touched }">
<label class="checkbox-inline">
<input type="checkbox" id="subscribe1" value="option1" name="subscribe[]" ng-model="user.subscribe" required> 1
</label>
<label class="checkbox-inline">
<input type="checkbox" id="subscribe2" value="option2" name="subscribe[]" ng-model="user.subscribe" required> 2
</label>
<label class="checkbox-inline">
<input type="checkbox" id="subscribe3" value="option3" name="subscribe[]" ng-model="user.subscribe" required> 3
</label>
<div class="help-block" ng-messages="userForm.subscribe.$error" ng-show="userForm.subscribe.$invalid">
<div ng-messages-include="home/messages.html"></div>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : userForm.gender.$invalid && !userForm.gender.$touched }">
<div class="radio">
<label>
<input type="radio" name="gender" value="male" ng-model="user.gender" />
male
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="gender" value="female" ng-model="user.gender" />
female
</label>
</div>
<div class="help-block" ng-messages="userForm.gender.$error" ng-show="userForm.gender.$invalid">
<div ng-messages-include="home/messages.html"></div>
</div>
</div>
<button type="submit" class="btn btn-primary btn-success " ng-disabled="userForm.$invalid">Submit</button>
</form>
messages.html
<span ng-message="required">This field is required</span>
<span ng-message="minlength">This field is too short</span>
<span ng-message="maxlength">This field is too long</span>
<span ng-message="required">This field is required</span>
<span ng-message="email">This needs to be a valid email</span>
controller.js
angular.module('myApp', ['ngRoute', 'ngAnimate', 'ngMessages']);
angular
.module('myApp')
.controller('HomeCtrl', HomeCtrl);
HomeCtrl.$inject = ['$scope'];
function HomeCtrl($scope) {
$scope.userForm = {};
}
Payment Checkbox set:
<div class="form-group" ng-class="{ 'has-error' : userForm.payment.$invalid && userForm.payment.$touched }">
<label class="checkbox-inline">
<input type="checkbox" id="payment1" value="Visa" name="payment" ng-blur="doTouched()" ng-model="user.payment[1]" ng-required="!someSelected(user.payment)"> Visa
</label>
<label class="checkbox-inline">
<input type="checkbox" id="payment2" value="Mastercard" name="payment" ng-blur="doTouched()" ng-model="user.payment[2]" ng-required="!someSelected(user.payment)"> Mastercard
</label>
<label class="checkbox-inline">
<input type="checkbox" id="payment3" value="Cash" name="payment" ng-blur="doTouched()" ng-model="user.payment[3]" ng-required="!someSelected(user.payment)"> Cash
</label>
<div class="help-block" ng-messages="userForm.payment.$error" ng-show="userForm.payment.$invalid && userForm.payment.$touched">
<div ng-messages-include="home/messages.html"></div>
</div>
</div>
Check this sample:
http://plnkr.co/edit/2w0lIf?p=preview
The check boxes list use the ng-required directive with the someSelected function (defined in the controller) which checks if at least one item is selected:
<div class="form-group" ng-class="{ 'has-error' : userForm.subscribe.$invalid && userForm.subscribe.$touched }">
<label class="checkbox-inline">
<input type="checkbox" id="subscribe1" value="option1" name="subscribe" ng-blur="doTouched()" ng-model="user.subscribe[1]" ng-required="!someSelected(user.subscribe)"> 1
</label>
<label class="checkbox-inline">
<input type="checkbox" id="subscribe2" value="option2" name="subscribe" ng-blur="doTouched()" ng-model="user.subscribe[2]" ng-required="!someSelected(user.subscribe)"> 2
</label>
<label class="checkbox-inline">
<input type="checkbox" id="subscribe3" value="option3" name="subscribe" ng-blur="doTouched()" ng-model="user.subscribe[3]" ng-required="!someSelected(user.subscribe)"> 3
</label>
<div class="help-block" ng-messages="userForm.subscribe.$error" ng-show="userForm.subscribe.$invalid && userForm.subscribe.$touched">
<div ng-messages-include="messages.html"></div>
</div>
</div>
The option button group is easier and use the ng-required directive with the condition !user.gender:
<div class="form-group" ng-class="{ 'has-error' : userForm.gender.$invalid && userForm.gender.$touched }">
<div class="radio">
<label>
<input type="radio" name="gender" value="male" ng-model="user.gender" ng-required="!user.gender"/>
male
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="gender" value="female" ng-model="user.gender" ng-required="!user.gender"/>
female
</label>
</div>
<div class="help-block" ng-messages="userForm.gender.$error" ng-if="userForm.gender.$touched">
<div ng-messages-include="messages.html"></div>
</div>
</div>
The ngBlur directive resolves the issue that a check boxes list become "touched" only when all the items in list are blurred, calling doTouched() function::
$scope.doTouched = function() {
$scope.userForm.subscribe.$setTouched();
}
P.S. pay attention to correct names: userForm is the HTML name of the <form>, user is the name of the model to which is bound the form.
Here is an example I created that suites our purpose.
Our app would create multiple checkbox questions per page, and $touched didn't seem to work on input checkbox fields that all had the same name attribute.
Also the custom angular plugins/directives I've seen for checkboxes are nice (where they just bind to 1 array model) but don't seem to support 'required'.
Here i set a custom_touched event per question which I set via ng-click:
http://jsfiddle.net/armyofda12mnkeys/9gLndp5y/7/
<li ng-repeat="choice in currentquestion.choices">
<input
type="checkbox"
ng-model="choice.selected"
ng-required="!somethingSelectedInTheGroup(currentquestion.required, currentquestion.choices)"
ng-click="currentquestion.custom_touched = true;"
name="{{currentquestion.question_code}}"
id="{{currentquestion.question_code}}_{{choice.option_value}}"
value="{{choice.option_value}}"
/> {{choice.orig_option_txt}}
</li>
$scope.somethingSelectedInTheGroup = function (is_required, choices) {
if(is_required) {
for(var i = 0; i < choices.length; i++) {
var choice = choices [i];
if(choice.selected) {
return true;
}
}
return false;
} else {
return false;
}
}
Note: i originally had used <div ng-if="questionform.$dirty && questionform[currentquestion2.question_code].$invalid">
but that doesn't work out for multiple checkbox questions per form/page.

Cannot clear form

I am trying to reset the form after the submit button is clicked. I understand that setting the form to pristine alone should not clear the input fields. I tried implementing the various suggestions to clear form by setting the form to pristine and then assigning null to all input fields. Is there a more neat way to implement it ?
Template:
<p>{{contactForm.$pristine}}</p>
<div class="inBox">
<form name="contactForm" novalidate>
<div class="form-group" ng-class="{ 'has-error' : contactForm.name.$invalid && !contactForm.name.$pristine }">
<label>Name</label>
<input type="text" ng-model="tabVm.name" class="form-control" name="name" required>
<p ng-show="contactForm.name.$invalid && !contactForm.name.$pristine" class="help-block">You name is required.</p>
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.email.$invalid && !contactForm.email.$pristine }">
<label>Email</label>
<input type="email" ng-model="tabVm.email" name="email" class="form-control" required>
<p ng-show="contactForm.email.$invalid && !contactForm.email.$pristine" class="help-block">Enter a valid email.</p>
</div>
<div class="form-group">
<label>Contact Number</label>
<input type="tel" ng-model="tabVm.number" class="form-control">
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.message.$invalid && !contactForm.message.$pristine }">
<label>Message</label>
<textarea type="text" rows="5" ng-model="tabVm.message" name="message" class="form-control textBox" required></textarea>
<p ng-show="contactForm.message.$invalid && !contactForm.message.$pristine" class="help-block">Brief message is required.</p>
</div>
</form>
<button type="submit" ng-click="sendMsg()" class="btn large-btn"
ng-disabled="contactForm.message.$invalid || contactForm.name.$invalid||contactForm.email.$invalid " >Send</button>
</div>
app.js
$scope.contactForm.$setPristine();
and I also tried
$scope.contactForm.$pristine=true;
Neither of them seem to work. I use angular 1.4.8.
Thank you.
You should use $setPristine() and then reset the ng-model object. Also pay attention you have the submit button outside the <form>.
This is a working JSFiddle (I used only one input for example)
$scope.sendMsg = function() {
$scope.contactForm.$setPristine();
$scope.tabVm = {};
}
You referenced controlForm, but the html you posted have contactForm
I finally got it working by making the following changes :
<div class="container box col-lg-6" >
<p>{{contactForm.$pristine}}</p>
<p>name state: {{contactForm.name.$pristine}}</p>
<div class="inBox">
<form name="contactForm" ng-submit="sendMsg(contactForm)" novalidate>
<div class="form-group" ng-class="{ 'has-error' : contactForm.name.$invalid && !contactForm.name.$pristine }">
<label>Name</label>
<input type="text" ng-model="tabVm.name" class="form-control" name="name" required>
<p ng-show="contactForm.name.$invalid && !contactForm.name.$pristine" class="help-block">You name is required.</p>
</div>
<input type="submit" class="btn large-btn"
ng-disabled="contactForm.message.$invalid || contactForm.name.$invalid||contactForm.email.$invalid " >
</form>
</div>
</div>
and app.js :
$scope.sendMsg=function(form){
if(form.$valid){
console.log("Form is valid"); //this was a check I used to confirm that the controller recognized the form.
}
form.$setPristine();
tabVm.name="";
}
}
I do not clearly understand why this works or what was I doing wrong earlier. I would appreciate if anyone could explain. Thank you.
Do as follows
$scope.sendMsg = function(){
//your function code
$scope.tabVm={};
$scope.tabVm.name='';
$scope.tabVm.email='';
$scope.tabVm.number='';
$scope.tabVm.message='';
}

Angular form validation $pristine not working properly

Can anyone tell me why my validation is being ignored?
Here is my form:
<form name="contactForm" role="form" ng-submit="controller.submit()" novalidate>
<div class="form-group" ng-class="{ 'has-error' : contactForm.fullName.$invalid && !contactForm.fullName.$pristine }">
<input class="form-control" type="text" name="fullName" placeholder="Full name" ng-model="controller.model.fullName" required />
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.email.$invalid && !contactForm.email.$pristine }">
<input class="form-control" type="text" name="email" placeholder="Email address" ng-model="controller.model.email" required />
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.phoneNumber.$invalid && !contactForm.phoneNumber.$pristine }">
<input class="form-control" type="text" name="phoneNumber" placeholder="Phone number" ng-model="controller.model.phoneNumber" required />
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.orderQuantity.$invalid && !contactForm.orderQuantity.$pristine }">
<select class="form-control" name="orderQuantity" ng-model="controller.model.orderQuantity">
<option disabled selected>Order quantity</option>
<option>10+</option>
<option>20+</option>
<option>30+</option>
<option>40+</option>
</select>
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.country.$invalid && !contactForm.country.$pristine }">
<input class="form-control" type="text" name="country" placeholder="Country" ng-model="controller.model.country" required />
</div>
<div class="form-group">
<textarea class="form-control" placeholder="Message" ng-model="controller.model.message"></textarea>
</div>
<div class="form-group">
<div class="recaptcha" theme="dark" vc-recaptcha key="'6Lcc0AgTAAAAAIpcEqqDI3Ko8dZ05H-GGgUnfOvA'"></div>
</div>
<div class="form-group">
<button class="btn btn-primary">Send</button>
</div>
</form>
I set up a codepen here:
http://codepen.io/r3plica/pen/XbzyzQ?editors=101
you should check whether form is submitted or not using contactForm.$submitted.
After form submission the formController object is get updated and various parameter of each controll's model are get updated and then you can validate your data.
you have not checked this in your form validation.
The updated html is
<div class="container" ng-app="validationExample">
<div class="row" ng-controller="ValidationController as controller">
<form style="margin-top: 20px;" name="contactForm" role="form" ng-submit="controller.submit()" novalidate>
<div class="form-group" ng-class="{ 'has-error' : contactForm.fullName.$invalid && contactForm.$submitted }">
<input class="form-control" type="text" name="fullName" placeholder="Full name" ng-model="controller.model.fullName" required />
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.email.$invalid && contactForm.$submitted }">
<input class="form-control" type="email" name="email" placeholder="Email address" ng-model="controller.model.email" required />
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.phoneNumber.$invalid && contactForm.$submitted }">
<input class="form-control" type="tel" name="phoneNumber" placeholder="Phone number" ng-model="controller.model.phoneNumber" required />
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.$submitted && contactForm.orderQuantity.$invalid && contactForm.orderQuantity.$error.required }">
<select class="form-control" required name="orderQuantity" ng-model="controller.model.orderQuantity">
<option disabled selected>Order quantity</option>
<option>10+</option>
<option>20+</option>
<option>30+</option>
<option>40+</option>
</select>
</div>
<div class="form-group" ng-class="{ 'has-error' : contactForm.country.$invalid && contactForm.$submitted}">
<input class="form-control" type="text" name="country" placeholder="Country" ng-model="controller.model.country" required />
</div>
<div class="form-group">
<textarea class="form-control" placeholder="Message" ng-model="controller.model.message"></textarea>
</div>
<div class="form-group">
<button class="btn btn-primary" type="submit">Send</button>
</div>
</form>
</div>
</div>
Here is the updated code codepen
Also instead of $invalid you can use required to validate the fields.Also you can use regular expression to put your custom validation rule.
e.g.
<input name="first_name" class="form-control" required type="text" ng-model="NewUser.first_name" ng-pattern="/^[A-Za-z]+[0-9]*$/" />
<span ng-show="newuser.first_name.$error.pattern">This is not valid <b>Last name</b></span>
Actually the validation is not ignored. In your codepen code, input whatever text and remove to empty. Then switch to another input element. The has-error class is added.
Because you are checking through $dirty, which is by default false if you do not alter any input text (https://docs.angularjs.org/api/ng/type/form.FormController):
$dirty boolean
True if user has already interacted with the form.
I added ng-minlength=5 to your code: http://codepen.io/anon/pen/xGPmqR:
<div class="form-group" ng-class="{ 'has-error' : contactForm.fullName.$invalid && contactForm.fullName.$dirty }">
<input class="form-control" type="text" name="fullName" placeholder="Full name" ng-model="controller.model.fullName" required ng-minlength=5 />
</div>
As you input any text, the ng-minlength rules is working.

Defined function not being called

I have a form
<form role="form" name="signup" novalidate>
<div class="form-group" ng-class="{ 'has-error' : signup.firstname.$invalid && !signup.firstname.$pristine }">
<label>First Name</label>
<input type="text" name="firstname" class="form-control" ng-model="firstname" required>
<p ng-show="signup.firstname.$invalid && !signup.firstname.$pristine" class="help-block">You name is required.</p>
</div><div class="form-group"">
<label>Last Name</label>
<input type="text" name="lastname" class="form-control" ng-model="lastname">
</div>
<div class="form-group" ng-class="{ 'has-error' : signup.phone.$invalid && !signup.phone.$pristine }">
<label>Phone</label>
<input type="text" name="phone" class="form-control" ng-model="phone" ng-minlength="10">
<p ng-show="signup.phone.$invalid && !signup.phone.$pristine" class="help-block">Number is too short!!</p>
</div>
<div class="form-group" ng-class="{ 'has-error' : signup.email.$invalid && !signup.email.$pristine }">
<label>Email</label>
<input type="email" name="email" class="form-control" ng-model="email">
<p ng-show="signup.email.$invalid && !signup.email.$pristine" class="help-block">Enter a valid email.</p>
</div>
<div class="form-group" ng-class="{ 'has-error' : signup.password.$invalid && !signup.password.$pristine }">
<label>Password</label>
<input type="password" name="password" class="form-control" ng-model="password" ng-minlength="6">
<p ng-show="signup.password.$invalid && !signup.password.$pristine" class="help-block">Password is too short</p>
</div>
<div class="form-group" ng-class="{ 'has-error' : signup.passwordRepeat.$invalid && !signup.passwordRepeat.$pristine }">
<label>Password Repeat</label>
<input type="password" name="passwordRepeat" class="form-control" ng-model="passwordRepeat" ng-minlength="6">
<p ng-show="signup.passwordRepeat.$invalid && !signup.passwordRepeat.$pristine" class="help-block">Password repeat is too short</p>
</div>
<button type="submit" class="btn btn-primary btn-success" ng-disabled="signup.$invalid" ng-click="signing()">Create New Account</button>
</form>
it calls a controller function signing()
$scope.signing = function () { $scope.signup($scope.firstname, $scope.lastname, $scope.email, $scope.telephone, $scope.password, $scope.$passwordRepeat); }
which in turn calls
$scope.signup = function ($firstname, $lastname, $email, $phone, $password, $passwordRepeat) {....}
but the console is saying
"Error: $scope.signup is not a function"
the thing is, both functions are defined in the same controller, and it was working fine, before, i can't seem to wrap my head around what could be wrong.
It started saying there was an error, wen i tried to do form validation.
Any help will be highly appreciated.
The problem is that you are using the same name for the form: name="signup". This is also creating a signup property in the $scope, overriding the signup function you defined in the controller. Change one of them at it should work.

Resources