Angular form validation: how to override $invalid - angularjs

<div class="col-xs-7">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="settings.input">
checked
</label>
</div>
<div collapse="!settings.input" ng-class="myform.input.$invalid ? 'has-error has-feedback': ''">
<input type="number" class="form-control input-sm" id="inputEmail3" name="input" ng-model="settings.input" placeholder="if checked, then do validation" required min="0">
<span ng-show="myform.input.$invalid" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
</div>
</div>
demo here
My question is when I set required for the input, the form.$valid will be false, But what I want is only when the checkbox checked, then do input validation, So when not checked, even the input is empty, the value of form.$valid should be true
What I purpose is to override the $valid of input, how to override?

Form field is getting invalid because you had required attribute over input field, so every time that form input field is considered as required. So what you can do is, you should add required attribute on form field conditionally by having ng-required directive on input with expression.
Markup
<div collapse="!settings.input" ng-class="myform.input.$invalid ? 'has-error has-feedback': ''">
<input type="number" class="form-control input-sm" id="inputEmail3" name="input"
ng-model="settings.input" placeholder="if checked, then do validation"
ng-required="settings.input" min="0"/>
<span ng-show="myform.input.$invalid" class="glyphicon glyphicon-remove form-control-feedback"
aria-hidden="true"></span>
</div>
Forked Plunkr

Angular has ng-required directive that allows to enable required attribute with an expression. Replace required="" on input with the following:
ng-required="settings.checked"
Live example

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").

Toggle class on input depending on input's value

I am still new to Angular but I have an existing application that uses Angular 1.5 pretty heavily.
I have a basic form that I need to add a class to depending on the following criteria:
The form can only have an End Date value or an Active for value. It cannot have both. I was thinking I need to disable the input box of the input not being used.
Ex. If a user inputs a date into the End Date input, then the Active for input will become disabled.
I looked into ng-if but every example I came across was for checking if the entered input variable was empty or equal to a value in a .js controller, not checking if the current entered variable was equal to another entered variable in the form.
<div class="form-group">
<label>End date:</label>
<div class="input-group">
<input type="text" class="form-control" is-open="endDateOpened" uib-datepicker-popup="MM/dd/yyyy" ng-model="updatePatientLabel.active_end_date"/>
<span class="input-group-btn">
<button type="button" class="btn btn-search" ng-click="openEndDate($event)"><i class="fa fa-calendar"></i></button>
</span>
</div>
</div>
<div class="form-group">
<label>Or will be active for:</label>
<input name="expirationTimeNumber" type="number" class="form-control time" ng-model="updatePatientLabel.expiration_time_number"/>
</div>
Here is a screenshot of my modal where this happens. Ignore the other inputs as they are not affected by the conditions I've laid out.
Thanks
Form Screen Shot
You can use ng-disabled.
//initialize your dates with null
$scope.updatePatientLabel = {};
$scope.updatePatientLabel.active_end_date = null;
$scope.updatePatientLabel.expiration_time_number = null;
HTML:
<input id="endDate" ng-disabled="updatePatientLabel.expiration_time_number !== null" ng-model="updatePatientLabel.active_end_date" />
<input id="activeDate" ng-disabled="updatePatientLabel.active_end_date !== null" ng-model="updatePatientLabel.expiration_time_number" />
You have a few options. Classes, as you mentioned, or ng-if. The ng-if seems more elegant, like so:
<div class="form-group" ng-if="updatePatientLabel.active_end_date != ''">
<label>End date:</label>
<div class="input-group">
<input type="text" class="form-control" is-open="endDateOpened" uib-datepicker-popup="MM/dd/yyyy" ng-model="updatePatientLabel.active_end_date"/>
<span class="input-group-btn">
<button type="button" class="btn btn-search" ng-click="openEndDate($event)"><i class="fa fa-calendar"></i></button>
</span>
</div>
</div>
<div class="form-group" ng-if="updatePatientLabel.expiration_time_number > 0">
<label>Or will be active for:</label>
<input name="expirationTimeNumber" type="number" class="form-control time" ng-model="updatePatientLabel.expiration_time_number"/>
</div>
Otherwise, you could do an inline conditional outputting "hidden" inside the class attribute only if the value is not present. Something like this:
<div class="form-group {{updatePatientLabel.active_end_date != '' ? '' : 'hidden'}}">
<label>End date:</label>
<div class="input-group">
<input type="text" class="form-control" is-open="endDateOpened" uib-datepicker-popup="MM/dd/yyyy" ng-model="updatePatientLabel.active_end_date"/>
<span class="input-group-btn">
<button type="button" class="btn btn-search" ng-click="openEndDate($event)"><i class="fa fa-calendar"></i></button>
</span>
</div>
</div>
<div class="form-group {{updatePatientLabel.expiration_time_number > 0 ? '' : 'hidden'}}">
<label>Or will be active for:</label>
<input name="expirationTimeNumber" type="number" class="form-control time" ng-model="updatePatientLabel.expiration_time_number"/>
</div>
I use both in my projects, and either way is perfectly acceptable. Though, ng-if does seem more elegant and a bit more suited for this scenario.

How to use element name in ng-show and form validation

I was looking at the W3school example of form validation for Angular JS, here is the code:
<form name="myForm">
<p>Name:
<input name="myName" ng-model="myName" required>
<span ng-show="myForm.myName.$touched && myForm.myName.$invalid">The name is required.</span>
</p>
<p>Adress:
<input name="myAddress" ng-model="myAddress" required>
<span ng-show="myForm.myAddress.$untouched">Please enter address.</span>
</p>
</form>
note the ng-show="myForm.myName.$touched", does Angular find the element's name attribute as default? What if the input has an id and I want to use that instead of name?
You can use this in below way..
<input name="myName" id="myNameId" ng-model="myName" required>
<span ng-show='angular.element($("#myNameId")).$touched && angular.element($("#myNameId")).$invalid'>The name is required.</span>
</p>

AngularJS and Bootstrap: Red border on invalid input field on submit

I've this basic form implemented using AngularJS and Bootstrap:
http://jsfiddle.net/dennismadsen/0stwd03k/
HTML
<div ng-controller="MyCtrl">
<form class="well" name="formTest" ng-submit="save()">
<div class="form-group">
<label for="name">Name*</label>
<input type="name" class="form-control" id="name" placeholder="Enter name" required />
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
JavaScript
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.save = function () {
};
}
Result
The Name input field is required. When I click the submit button, I need the input field to have a red border if it's invalid. How can this be done?
Alternatively, if I unfocus the input field and it's still not valid, it would be great that the red corder is shown on that time, instead of waiting for the form submit.
Twitter Bootstrap has an has-error class, so I would use this in conjunction with ng-class for the form group, then a label with the label and label-danger classes for good measure:
<div class="form-group" ng-class="{'has-error': errors.Name }">
<label for="name">Name*</label>
<input type="name" class="form-control" id="name" placeholder="Enter name" required />
<span class="label label-danger" ng-if="errors.Name">{{errors.Name}}</span>
</div>
Then in your controller, have an errors object, and set the Name property of this to a string when the name is invalid.
The first thing you were missing was adding ng-model='name' to input field, then only will the form become invalid once you click submit, otherwise the form will always be valid since it considers that there is no field present.
Then I'd add the submitted class on the submit click button, then put the border css like .submitted would be the parent and .ng-invalid would be the child so we can put the style on .submitted .ng-invalid
HTML
<div ng-controller="MyCtrl">
<form class="well" name="formTest" ng-class="{'submitted': submitted}" ng-submit="save()" >
<div class="form-group">
<label for="name">Name*</label>
<input type="name" class="form-control" id="name" placeholder="Enter name" ng-model="name" required />
</div>{{submitted}}
<button type="submit" class="btn btn-default" ng-click="submitted= true;">Submit</button>
</form>
</div>
CSS
.submitted .ng-invalid{
border: 1px solid red;
}
Working Fiddle
Hope this could help you, Thanks.
Basically you need angular to take over validation, so add novalidate to form. Also add ng-class to input field to determine wether to add error css
<form name="myForm" novalidate ng-submit="test()">
<input type="text" name="user" ng-model="user" required ng-class="myForm.user.$invalid && myForm.user.$dirty ? 'error' : ''">
<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>
<input type="submit"
ng-disabled="myForm.user.$dirty && myForm.user.$invalid ||
myForm.email.$dirty && myForm.email.$invalid">
</p>
</form>
Good luck..

angular validation not working

I am using angular validation on an html page, where I have defined a form along with validation on the form. However, when I run the page, all the validations I have used on the page is visible. Is there a way I can hide all the validations?
<form ng-controller="validateCtrl"
name="loginForm" novalidate>
<p>UserName:<br>
<input type="text" name="uName" ng-model="uName" required>
<span style="color:red" ng-show="loginForm.uName.$dirty && loginForm.uName.$invalid && loginForm.uName.$error.required">
Username is required
</span>
</p>
<p>Password:<br>
<input type="text" name="pwd" ng-model="pwd" required>
<span style="color:red" ng-show="loginForm.pwd.$dirty && loginForm.pwd.$invalid">
<span ng-show="loginForm.pwd.$error.required">Password is required.</span>
</span>
</p>
<p>
<input type="submit" ng-click="popupuser()"
ng-disabled="loginForm.$invalid ">
</p>
</form>
<script src="https://code.angularjs.org/1.2.3/angular.min.js"></script>
Your code for form is fine please see here http://jsbin.com/figuve/1/edit
Make sure that your validateCtrl exist otherwise validation will not work plase see here
http://jsbin.com/figuve/2/edit
or
remove ng-controller="validateCtrl" from your form if you don't need it.
please see here http://jsbin.com/figuve/3/edit
You can try use variable to check is form submited, like that
<span ng-show="(loginForm.uName.$dirty || isSubmitted) && loginForm.uName.$error.required">Username is required</span>

Resources