ng-required not working for enabled fields from disabled state - angularjs

I am facing an issue with the Angular validation for fields which disables/enables on checkbox check.
The scenario in which it is failing is stated below:
Checkout page is having address fields and a checkbox which is checked by default and it means the shipping address and the billing address are same. If it is unchecked then I have to provide a billing address. I have a button which will show the payment option if the fields are filled up with correct data.
The validation is working fine as long as the checkbox is checked. But it is failing to validate the billing address fields if the checkbox is unchecked.
What I have done:
I have disabled and hid the billing address fields if the checkbox is checked. Once unchecked, I am showing the billing address fields with all the fields in enabled and required state. The reason behind this is if I don't disable the fields then the hidden billing address fields are considered in the field validation.
The view page with the Angular validation:
<form class="form-horizontal address" name="addressForm" novalidate>
<div class="panel-body">
<div class="form-group">
<div class="col-md-12">
<h4>Shipping Address</h4>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.country.$invalid && !addressForm.country.$pristine }">
<div class="col-md-12"><strong>Country:</strong></div>
<div class="col-md-12">
<input type="text" name="country" class="form-control" value="" ng-model="shipCountry" ng-required="true" />
<p ng-show="addressForm.country.$invalid && !addressForm.country.$pristine" class="help-block">Country name is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.fname.$invalid && !addressForm.fname.$pristine }">
<div class="col-md-12"><strong>Full Name:</strong></div>
<div class="col-xs-12">
<input type="text" name="fname" class="form-control" value="" ng-model="shipFullName" ng-required="true" />
<p ng-show="addressForm.fname.$invalid && !addressForm.fname.$pristine" class="help-block">Your name is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.address.$invalid && !addressForm.address.$pristine }">
<div class="col-md-12"><strong>Address:</strong></div>
<div class="col-md-12">
<input type="text" name="address" class="form-control" value="" ng-model="shipAddress" ng-required="true" />
<p ng-show="addressForm.address.$invalid && !addressForm.address.$pristine" class="help-block">Your address is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.city.$invalid && !addressForm.city.$pristine }">
<div class="col-md-12"><strong>City:</strong></div>
<div class="col-md-12">
<input type="text" name="city" class="form-control" value="" ng-model="shipCity" ng-required="true" />
<p ng-show="addressForm.city.$invalid && !addressForm.city.$pristine" class="help-block">Your city is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.state.$invalid && !addressForm.state.$pristine }">
<div class="col-md-12"><strong>State:</strong></div>
<div class="col-md-12">
<input type="text" name="state" class="form-control" value="" ng-model="shipState" ng-required="true" />
<p ng-show="addressForm.state.$invalid && !addressForm.state.$pristine" class="help-block">Your state is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.zip_code.$invalid && !addressForm.zip_code.$pristine }">
<div class="col-md-12"><strong>Zip / Postal Code:</strong></div>
<div class="col-md-12">
<input type="text" name="zip_code" class="form-control" value="" ng-model="shipPostal" ng-required="true" ng-pattern="/^[0-9]+$/" maxlength="7" />
<p ng-show="addressForm.zip_code.$invalid && !addressForm.zip_code.$pristine" class="help-block">Error in postal code field!!</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.phone_number.$invalid && !addressForm.phone_number.$pristine }">
<div class="col-md-12"><strong>Phone Number:</strong></div>
<div class="col-md-12">
<input type="text" name="phone_number" class="form-control" value="" ng-model="shipPhone" ng-required="true" maxlength="10"
ng-pattern="/^[0-9]+$/" />
<p ng-show="addressForm.phone_number.$invalid && !addressForm.phone_number.$pristine" class="help-block">Error in phone number field!!</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.email_address.$invalid && !addressForm.email_address.$pristine }">
<div class="col-md-12"><strong>Email Address:</strong></div>
<div class="col-md-12">
<input type="text" name="email_address" class="form-control" value="" ng-model="shipEmail" ng-required="true" ng-pattern="/^(([^<>()\[\]\\.,;:\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,}))$/" />
<p ng-show="addressForm.email_address.$invalid && !addressForm.email_address.$pristine" class="help-block">Error in email field!!</p>
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="checkbox" name="address" class="" value="" /> Save address
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<input type="checkbox" name="address" class="" value="" ng-model="billSameAsShip" ng-change="toggleBillAddressView()" />Billing Address same as Shipping Address
</div>
</div>
</div>
<!--SHIPPING METHOD END-->
<!--BILLING METHOD START-->
<div class="panel-body" ng-hide="billSameAsShip">
<div class="form-group">
<div class="col-md-12">
<h4>Billing Address</h4>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.bill_country.$invalid && !addressForm.bill_country.$pristine }">
<div class="col-md-12"><strong>Country:</strong></div>
<div class="col-md-12">
<input type="text" class="form-control" name="bill_country" value="" ng-model="billCountry" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
<p ng-show="addressForm.bill_country.$invalid && !addressForm.bill_country.$pristine" class="help-block">Your billing country is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.bill_fname.$invalid && !addressForm.bill_fname.$pristine }">
<div class="col-xs-12">
<strong>Full Name:</strong>
<input type="text" name="bill_fname" class="form-control" value="" ng-model="billFullName" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
<p ng-show="addressForm.bill_fname.$invalid && !addressForm.bill_fname.$pristine" class="help-block">Your full name is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.bill_address.$invalid && !addressForm.bill_address.$pristine }">
<div class="col-md-12"><strong>Address:</strong></div>
<div class="col-md-12">
<input type="text" name="bill_address" class="form-control" value="" ng-model="billAddress" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
<p ng-show="addressForm.bill_address.$invalid && !addressForm.bill_address.$pristine" class="help-block">Your billing address is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.bill_city.$invalid && !addressForm.bill_city.$pristine }">
<div class="col-md-12"><strong>City:</strong></div>
<div class="col-md-12">
<input type="text" name="bill_city" class="form-control" value="" ng-model="billCity" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
<p ng-show="addressForm.bill_city.$invalid && !addressForm.bill_city.$pristine" class="help-block">Your billing city is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.bill_state.$invalid && !addressForm.bill_state.$pristine }">
<div class="col-md-12"><strong>State:</strong></div>
<div class="col-md-12">
<input type="text" name="bill_state" class="form-control" value="" ng-model="billState" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
<p ng-show="addressForm.bill_state.$invalid && !addressForm.bill_state.$pristine" class="help-block">Your billing state is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.bill_zip_code.$invalid && !addressForm.bill_zip_code.$pristine }">
<div class="col-md-12"><strong>Zip / Postal Code:</strong></div>
<div class="col-md-12">
<input type="text" name="bill_zip_code" class="form-control" value="" ng-model="billPostal" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
<p ng-show="addressForm.bill_zip_code.$invalid && !addressForm.bill_zip_code.$pristine" class="help-block">Your billing zip/postal code is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.bill_phone_number.$invalid && !addressForm.bill_phone_number.$pristine }">
<div class="col-md-12"><strong>Phone Number:</strong></div>
<div class="col-md-12">
<input type="text" name="bill_phone_number" class="form-control" value="" ng-model="billPhone" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
<p ng-show="addressForm.bill_phone_number.$invalid && !addressForm.bill_phone_number.$pristine" class="help-block">Your billing phone number is required.</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : addressForm.bill_email_address.$invalid && !addressForm.bill_email_address.$pristine }">
<div class="col-md-12"><strong>Email Address:</strong></div>
<div class="col-md-12">
<input type="text" name="bill_email_address" class="form-control" value="" ng-model="billEmail" ng-disabled="billSameAsShip" ng-required="{{!billSameAsShip}}" />
<p ng-show="addressForm.bill_email_address.$invalid && !addressForm.bill_email_address.$pristine" class="help-block">Your billing email address is required.</p>
</div>
</div>
</div>
<div class="panel-footer">
<div class="form-group">
<div class="col-xs-12 text-right">
<button type="button" class="btn btn-primary btn-submit-fix" ng-click="gotoInvoice()">Show Payment Option</button>
</div>
</div>
</div>
</form>

Don't use ng-hide. Use ng-if. ng-if will remove the fields from the form, which thus won't take them into accound when validating the form.

Related

Can not access ng-model values inside controller [angularJS]

When I try to access user.firstname value in controller, it gives the following error.
TypeError: Cannot read property 'firstname' of undefined
$scope.signUpCustomer = function(){
console.log("GGGGGGGGGGGGGGGGGGGGGGGGG ", $scope.user.firstname);
}
<form class="form-horizontal font-hp-simplified signUpUserForm row" role="form" ng-submit="signUpCustomer()" name ="signUpUserForm" ng-show="!userVendor">
<div class="col-md-12">
<div class="col-md-6">
<div class="form-group">
<label for="firstname" class="col-md-12">First Name:</label>
<div class="col-md-12">
<input ng-model="user.firstname" type="text" class="form-control" name="firstname" required />
<span class="text-danger" ng-show="signUpUserForm.firstname.$invalid && signUpUserForm.firstname.$dirty ">First name is required</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="lastname" class="col-md-12">Last Name:</label>
<div class="col-md-12">
<input ng-model="user.lastname" type="text" class="form-control" name="lastname" required />
<span class="text-danger" ng-show="signUpUserForm.lastname.$invalid && signUpUserForm.lastname.$dirty ">Last name is required</span>
</div>
</div>
</div>
</div>
<div class="col-md-12">
<div class="col-md-6">
<div class="form-group">
<label for="email" class="col-md-12">Email:</label>
<div class="col-md-12">
<input ng-model="user.email" type="email" class="form-control" name="email" required />
<span class="text-danger" ng-show="signUpUserForm.email.$error.required && signUpUserForm.email.$dirty ">Email is required</span>
<span class="text-danger" ng-show="signUpUserForm.email.$error.email && signUpUserForm.email.$dirty ">Please enter valid email</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="password" class="col-md-12">Password:</label>
<div class="col-md-12">
<input ng-model="user.password" type="password" class="form-control" name="password" required />
<span class="text-danger" ng-show="signUpUserForm.password.$invalid && signUpUserForm.password.$dirty">Password is required</span>
</div>
</div>
</div>
</div>
<div class="col-md-12">
<div class="col-md-6">
<div class="form-group">
<label for="phone" class="col-md-12">Phone:</label>
<div class="col-md-12">
<input ng-model="user.phone" type="text" class="form-control" name="phone" required />
<span class="text-danger" ng-show="signUpUserForm.phone.$invalid && signUpUserForm.phone.$dirty">Phone is required</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="country" class="col-md-12">Country:</label>
<div class="col-md-12">
<select name="country" ng-model="user.country" type="text" class="form-control form-bg-white" required>
<!-- <option value="" disabled selected>Select Your Country</option> -->
<option value="" disabled selected></option>
<option ng-repeat="country in countries" value="{{country}}">{{country}}</option>
</select>
<span class="text-danger" ng-show="signUpUserForm.country.$invalid && signUpUserForm.country.$dirty">Country is required</span>
</div>
</div>
</div>
</div>
<div class="col-md-12">
<div class="col-md-12">
<!-- Button -->
<div class="form-group">
<div class="col-md-12">
<div class="icon-user-signup">
<div class="input-group-addon">
<i class="fa fa-user"></i>
</div>
<button id="btn-signup" class="btn btn-primary col-md-12">SIGN UP</button>
</div>
</div>
<!-- <div class="mrg-top-10 col-md-12 text-right">
<h4><a ng-click="go('/seller#/signup')" class="ven-link">
Become a vendor today
</a></h4>
</div>-->
</div>
</div>
</div>
<!-- <div class="col-md-12 control">
<div class="signup-border" >
Already have an account ?
<a ui-sref="loginUser" >
Sign In Here
</a>
</div>
</div> -->
</form>
You need to initialize the $scope.customer first in controller
$scope.user = {};

ng-form in ng-repeat and checking the validation status of all forms

So, I have a parent form with a nested set of ng-forms like this:
<form class="row" name="parentForm" ng-repeat="model in controller.addresses track by $index" novalidate>
<div class="col-xs-12 row-title">
<h1>{{ model.type || 'Delivery' }} address</h1>
</div>
<div class="col-xs-12 col-sm-4 col-lg-4">
<div class="form" name="saveForm" ng-form>
<div class="form-group">
<label class="control-label">Company name</label>
<input class="form-control" name="company" type="text" placeholder="Enter your company name" ng-model="model.company" />
</div>
<div class="form-group" ng-class="{ 'has-error' : saveForm.address1.$invalid && !saveForm.address1.$pristine }">
<label class="control-label">House name/number</label>
<input class="form-control" name="houseName" type="text" placeholder="Please enter your address 1" ng-model="model.houseName" ng-minlength="3" required />
</div>
<div class="form-group">
<label class="control-label">Street</label>
<input class="form-control" name="street" type="text" placeholder="Please enter your address 2" ng-model="model.street" />
</div>
<div class="form-group">
<label class="control-label">Town</label>
<input class="form-control" name="town" type="text" placeholder="Please enter your address 3" ng-model="model.town" />
</div>
<div class="form-group">
<label class="control-label">County</label>
<input class="form-control" name="county" type="text" placeholder="Please enter your address 4" ng-model="model.county" />
</div>
<div class="form-group" ng-class="{ 'has-error' : saveForm.postCode.$invalid && !saveForm.postCode.$pristine }">
<label class="control-label">Post code</label>
<input class="form-control" name="postCode" type="text" placeholder="Enter your post code" ng-model="model.postCode" ng-minlength="3" required />
</div>
</div>
</div>
</form>
I then have a button:
<div class="row">
<div class="col-xs-12 col-sm-4 col-lg-4">
<div div class="row">
<div class="col-xs-6 tile">
<a class="red" ui-sref="^">
<i class="fa fa-trash"></i>
<div class="footer">Back</div>
</a>
</div>
<div class="col-xs-6 tile" ng-if="parentForm.$valid">
<a class="yellow" ui-sref="^.finance">
<i class="fa fa-arrow-right"></i>
<div class="footer">Continue</div>
</a>
</div>
</div>
</div>
</div>
I want this button to only show if all child forms are valid. I was hoping that I could just use parentForm.$valid but that doesn't work.
Does anyone know how to solve this?
Try to do parentForm.saveForm.$valid.
It will work
Nested forms aren't valid in HTML5 - but you can place your saveForm outside the parentForm and then use the input element's form attribute to specify a form for your input elements.
<form name="form1">
<input type="string" ng-model="form1input" required>
<input type="string" form="form2" ng-model="form2input" required>
</form>
<div ng-form="form2" id="form2"></div>
<button ng-if="form1.$valid && form2.$valid">Click</button>
Plunker: https://plnkr.co/edit/y9ipsNoEW596guLf2CzM?p=preview

Angular JS Set focus and required validation, requires to click the link twice to open the link

Please refer my HTML form attached
var app = angular.module('main_app',['ngRoute',"angucomplete-alt","ngStorage",'ui-notification','ngSanitize'])
.factory('myService', function () {
return {
say: function ($scope) {
return "Hello World";
}
}
})
;
app.config(function(NotificationProvider) {
NotificationProvider.setOptions({
delay: 10000,
startTop: 20,
startRight: 10,
verticalSpacing: 20,
horizontalSpacing: 20,
positionX: 'right',
positionY: 'top'
});
});
app.controller('RegisterGuestController', function($scope,$routeParams,$http,$location,$rootScope,Notification){
$scope.book_id = $routeParams.id_book;
$scope.loginBlock = true;
$scope.lostPassword = false;
//console.log($scope.book_id);
$http({
url: base_url+"api_user/register_guest",
method: "GET",
params: {book_id: $scope.book_id}
}).success(function(data){
if(data.return_code==1){
$scope.bookDetails = data.data.bookDetails[0];
//alert ($scope.bookDetails.name);
$('#frm_name').focus();
} else {
Notification.error({message: data.data.message, title: 'Error'});
}
});
});
<html><head><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script></head>
<body ng-cloak class="" ng-app="main_app" >
<div class="registration-page" ng-init="register_guest()" >
<form method="post" id="registrationForm" name="frmregisterGuest" novalidate >
<div class="row">
<div class="col-sm-6 ">
<div class="form-group required" ng-class="{ 'has-error' : frmregisterGuest.frm_name.$invalid && frmregisterGuest.frm_name.$touched}" >
<label for="txtfirstname">first_name</label>
<input type="text" name="frm_name" value="" id="frm_name" class="form-control" ng-blur="validate=true" ng-model="frm_name" title="Enter your first name." required ng-pattern="/^[a-zA-Z']*$/" ng-minlength="2" ng-maxlength="20">
<div ng-show="frmregisterGuest.frm_name.$error.pattern" class="help-block">Please enter only letters</div>
<div ng-show="frmregisterGuest.frm_name.$error.minlength" class="help-block">Min length of first name is 2</div>
<div ng-show="frmregisterGuest.frm_name.$error.maxlength" class="help-block">Min length of first name is 20</div>
<div ng-show="frmregisterGuest.frm_name.$touched && frmregisterGuest.frm_name.$error.required" class="help-block">Please enter first name</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group" ng-class="{ 'has-error' : frmregisterGuest.frm_middleName.$invalid && frmregisterGuest.frm_middleName.$touched}" >
<label for="txtmiddleName">middle name</label>
<input type="text" name="frm_middleName" id="frm_middleName" ng-blur="validate=true" ng-model="frm_middleName" class="form-control" title="Enter your middle name." ng-pattern="/^[a-zA-Z']*$/" ng-minlength="2" ng-maxlength="20">
<div ng-show="frmregisterGuest.frm_middleName.$error.pattern" class="help-block">Please enter only letters</div>
<div ng-show="frmregisterGuest.frm_middleName.$error.minlength" class="help-block">Min length of middle name is 2</div>
<div ng-show="frmregisterGuest.frm_middleName.$error.maxlength" class="help-block">Max length of middle name is 20</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group" ng-class="{ 'has-error' : frmregisterGuest.frm_lname.$invalid && frmregisterGuest.frm_lname.$touched}">
<label for="txtlastName">last name</label>
<input type="text" name="frm_lname" id="frm_lname" value="" class="form-control" ng-blur="validate=true" ng-model="frm_lname" title="Enter your last name." ng-pattern="/^[a-zA-Z']*$/" ng-minlength="2" ng-maxlength="20">
<div ng-show="frmregisterGuest.frm_lname.$error.pattern" class="help-block">Please enter only letters</div>
<div ng-show="frmregisterGuest.frm_lname.$error.minlength" class="help-block">Min length of last name is 2</div>
<div ng-show="frmregisterGuest.frm_lname.$error.maxlength" class="help-block">Min length of last name is 20</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group required" ng-class="{ 'has-error' : frmregisterGuest.frm_email.$invalid && frmregisterGuest.frm_email.$touched}">
<label for="txtemail">email</label>
<input type="email" name="frm_email" id="frm_email" value="" class="form-control" title="Enter your email address." ng-blur="validate=true" ng-model="frm_email" required ng-pattern="/^[^\s#]+#[^\s#]+\.[^\s#]{2,}$/">
<div ng-show="frmregisterGuest.frm_email.$touched && frmregisterGuest.frm_email.$error.required" class="help-block">Please enter eamil</div>
<div ng-show="frmregisterGuest.frm_email.$error.pattern" class="help-block">Please enter correct email</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group required" ng-class="{ 'has-error' : frmregisterGuest.frm_password.$invalid && frmregisterGuest.frm_password.$touched}" >
<label for="txtpassword">password</label>
<input type="password" name="frm_password" id="frm_password" value="" class="form-control" title="Enter your password ." ng-blur="validate=true" ng-model="frm_password" required ng-minlength="6" ng-maxlength="10" >
<div ng-show="frmregisterGuest.frm_password.$touched && frmregisterGuest.frm_password.$error.required" class="help-block">Please enter password</div>
<div ng-show="frmregisterGuest.frm_password.$error.minlength" class="help-block">Min length of password is 2</div>
<div ng-show="frmregisterGuest.frm_password.$error.maxlength" class="help-block">Max length of password is 20</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group required" ng-class="{ 'has-error' : frmregisterGuest.frm_password2.$invalid && frmregisterGuest.frm_password2.$touched}">
<label for="txtpassword2">confirm password</label>
<input type="password" name="frm_password2" id="frm_password2" class="form-control" title="Enter your confirm_password." ng-model="frm_password2" required>
<div ng-show="frmregisterGuest.frm_password2.$touched && frmregisterGuest.frm_password2.$error.required" class="help-block">Please enter confirm password</div>
<div ng-show="(!frmregisterGuest.frm_password2.$error.required) && frmregisterGuest.frm_password2.$touched && frmregisterGuest.frm_password2.$error.noMatch" class="help-block">password does not match</div>
</div>
</div>
</div>
<div class="clearfix"></div>
<div class="col-sm-5 col-sm-offset-1">
<div class="form-group">
<p class="lostpassword">
lost your password
or
already registered
</p>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<input type="hidden" id="bookId" name="bookId" ng-value="{{bookDetails.id_book}}" value="{{bookDetails.id_book}}">
<input type="button" ng-click="doRegister()" id="register" name="register" value="Register" class="btn btn-primary" ng-disabled="frmregisterGuest.$invalid" >
</div>
</div>
</form>
</div></body></html>
I am setting focus to first field using following code in register_guest() JS function:
$('#frm_name').focus();
The form works fine When I am not using focus().
But by setting focus to first field, when I click the 'already registered' link, it displays 'required field error message' and does not redirect.
when I click second time on the same link, it redirects to required page.
I am using jquery version jquery-1.12.4 and AngularJS v1.4.1[enter image description here][1]
try to use attribute autofocus inside instead jquery focus()

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.

How to change the ng-model value to upper case for validation

<div class="form-group" ng-class="{'active': field == 'country', 'has-error has-feedback' :Country.$invalid && submitted}">
<label class="col-xs-2 control-label muted" for="Country">Country</label>
<div class="col-xs-9">
<input type="text" class="form-control" id="Country" name="Country" ng-change="ChangesMade()" ng-model="data.country" ng-readonly="previewMode" ng-focus="field='country';showHelp()" ng-required="contactPersonId">
</div>
</div>
Based on this field the state s required. But it can be either capital or lower case how i can i add filter to it
<div class="col-xs-4 pad-none" ng-class="{'has-error has-feedback' : (data.country =='US' || data.country =='CANADA' | uppercase) && State.$invalid && submitted }">
<div class="col-xs-4" >
<label class="control-label muted" for="State">State</label>
</div>
<div class="col-xs-8 pad-none">
<input type="text" class="form-control" id="State" name="State" ng-change="ChangesMade()" ng-model="data.state" ng-readonly="previewMode" ng-focus="field='state';showHelp()" ng-required="data.country =='US' || data.country =='Canada' ">
</div>
</div>
Try:
ng-required="data.country.toUpperCase() === 'US' || data.country =='Canada'"

Resources