AngularJS form with validation - angularjs

I have created one form with six fields out of which five are mandatory.There is one submit button. If user hasn't entered any input in the textbox and clicks on submit button, all the required textbox should highlight with red border. How to implement it? :-
<div ng-app="myApp" ng-controller="formCtrl">
<form name="demoForm">
<label>First Name :</label>
<input type="text" ng-model="firstName" required/><br><br>
<label>Last Name :</label>
<input type="text" ng-model="lastName"/><br><br>
<label>Email :</label>
<input type="email" ng-model="emailDet" required/><br><br>
<label>Contact No :</label>
<input type="text" ng-model="contactNo" required/><br><br>
<label>Current Location :</label>
<input type="text" ng-model="currLoc" required/><br><br>
<label>Preferred Location :</label>
<input type="text" ng-model="preLoc" required/><br><br>
<button type="button" ng-click="onSubmit()">Submit</button>
</form>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.onSubmit = function() {
}
});
</script>

This is quite easy. Define new css rule like here and all should be fine
.ng-invalid.ng-submitted input {
border: 1px solid red;
}
Under the hood, angular assign lots of classes to your form and input.
.ng-invalid
signals that something is wrong on the form
.ng-submitted
signals that form was submitted.
And so on. Check documentation and you will find a lot of new findings.

Related

Connect radial input and text input

I have form with radial buttons but the last one is a combination of radial button and text input. I want to somehow connect the two inputs. User should not be able to input the text before clicking the radial button next to it. Also when user starts to write text I wanna stop the radial button checked indication from disappearing. If user clicks some other radial button the text field should empty itself.
<label class="form-check-label">
<input type="radio" name="religion" value="noSay" ng-model="$ctrl.diversityTest.religion">Prefer not to say
</label>
<label class="form-check-label">
<input type="radio" name="religion" value="{{$ctrl.diversityTest.religion}}"> Any other religion or beliefe:
<div>
Please write in: <input ng-keyup="$ctrl.diversityTest.religion = $ctrl.diversityTest.temp" class="input-material" type="text" name="religion" ng-model="$ctrl.diversityTest.temp">
</div>
</label>
You can try like this:-
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.$ctrl = {};
$scope.$ctrl.diversityTest = {};
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<label class="form-check-label">
<input type="radio" ng-click="$ctrl.diversityTest.temp='';$ctrl.diversityTest.otherReligionRadio='';" name="religion" value="noSay" ng-model="$ctrl.diversityTest.religion">Prefer not to say
</label>
<label class="form-check-label">
<input type="radio" name="religion" value="Other_religion" ng-model="$ctrl.diversityTest.otherReligionRadio" > Any other religion or beliefe:
<div>
Please write in: <input class="input-material" type="text" ng-disabled="!($ctrl.diversityTest.otherReligionRadio)" ng-keyup="$ctrl.diversityTest.religion = $ctrl.diversityTest.temp" name="religion" ng-model="$ctrl.diversityTest.temp">
</div>
</label>
<br> Religion : {{$ctrl.diversityTest.religion}}
</div>

ng-model, don't show data in view

I have a case where I use a form with AngularJS. I have radio buttons and the last option is always text input. All of them are connected with the same model so what ever user chooses with radio buttons or type in text input is saved in model.
The problem is with text input. When a user clicks the radio button, its value is shown on the last text input line. How do I stop that and still keep it connected to the same ng-model?
<label class="form-check-label">
<input class="form-check-input" type="radio" name="religion" value="sikhizm" ng-model="$ctrl.diversityTest.religion">Sikhizm
</label>
<label class="form-check-label">
<input class="form-check-input" type="radio" name="religion" value="catholic" ng-model="$ctrl.diversityTest.religion">Catholic
</label>
...
<div class="mtl-20">
Please write in: <input class="input-material" type="text" name="religion" ng-model="$ctrl.diversityTest.religion" >
</div>
You can try a different approach like this:-
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.$ctrl = {};
$scope.$ctrl.diversityTest = {};
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<label class="form-check-label">
<input class="form-check-input" type="radio" name="religion" value="sikhizm" ng-model="$ctrl.diversityTest.religion">Sikhizm
</label>
<label class="form-check-label">
<input class="form-check-input" type="radio" name="religion" value="catholic" ng-model="$ctrl.diversityTest.religion">Catholic
</label>
...
<div class="mtl-20">
Please write in: <input ng-keyup="$ctrl.diversityTest.religion = $ctrl.diversityTest.temp" class="input-material" type="text" name="religion" ng-model="$ctrl.diversityTest.temp" >
</div>
<br>
This is religion model value : {{$ctrl.diversityTest.religion}}
</div>
How about this for a solution? Basically, have the radio buttons. Create an 'Other' with a text box, and only allow it to be selected if you enter a value for other. The text model is different, but when it's filled, will allow you to select 'Other' which will take on the value of what is in the textbox, and pass it to the model you care about.
<label class="form-check-label">
<input class="form-check-input" type="radio" name="religion" value="{{ textValue }}"
ng-disabled="!textValue && !(textValue.length > 5)"
ng-model="diversityTest.religion">
Other
<input class="input-material" type="text" name="religion" ng-model="textValue">
</label>
http://plnkr.co/edit/f9lzNLhZuy0c7BI2kE2A?p=preview

Form angularjs how to show current status while adding ng-model

I have a form in my html page:
<div id=update>
<form class="form-inline" ng-submit="updateCompany(company.companyId,company.companyName,company.newPassword,company.newEmail)" ng-show="updateForm">
<h3>Update Company</h3>
<div class="form-group">
<input type="text"
class="form-control" id="companyId" value={{company.companyId}} readonly/>
</div>
<div class="form-group">
<input type="text"
class="form-control" id="companyName"
value={{company.companyName}} readonly/>
</div>
<div class="form-group">
<input type="text"
class="form-control" id="companyPassword"
placeholder="Enter New Password" ng-model="company.newPassword"/>
</div>
<div class="form-group">
<input type="email"
class="form-control" id="companyEmail" placeholder="Enter New Email"
ng-model="company.newEmail" />
<button type="submit" class="btn btn-default">UPDATE</button>
</div>
</form>
</div>
I would like to show the current company values(id,name,password,email),
in the text fields, than give the user option to change the password and the email and send all the parameters when I submit the form.
The problem is when I put the ng-model on the text field, the current value disappears.
I need a fix for that!!!
In the first two fields I see the value now because I don't have the ng-model on them, once I put ng-model it disappear.
In your controller just attach the company data to scope like this:
$scope.company = yourcompanydata
And as for submitting the data, you don't have to list all the parameters in your html. In your html just leave:
ng-submit="updateCompany()"
And in your controller:
$scope.updateCompany = function(){
// your submitting logic here and all the company data will
// be available under $scope.company
// including the new password and email entered by the user
// so your submitting logic could look something like this:
submitCompanyData($scope.company.companyId, $scope.company.newPassword,...)
}
Here is a simple version codepen to get you started, depending what you'd like to do with data afterwords. I can update as needed.
angular
.module('app', [])
.controller('ExampleController', ExampleController);
function ExampleController() {
var vm = this;
vm.company = {};
vm.info = info;
function info(info) {
console.log(info);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app='app'>
<div class="container" ng-controller="ExampleController as vm">
<form novalidate>
<input type="text" ng-model="vm.company.name" required/>
<input type="email" ng-model="vm.company.email" required/>
<input type="submit" ng-click="vm.info(vm.company)" value="Submit" />
</form>
{{vm.company| json}}
</div>
</body>

$scope.formName.fieldName.$setValidity is not working

I would like to set invalid with angular when firstname is equals to lastname and change the color using styles to red.
http://jsbin.com/japir/2
function RegoController($scope) {
$scope.app = {
firstName: "Saroj"
};
$scope.$watch("app.lastName", function(newVal, oldVal) {
if (!!$scope.app.lastName && !!newVal)
if (angular.lowercase($scope.app.firstName) === angular.lowercase(newVal)) {
debugger;
$scope.form.inputLastName.$setValidity("sameName", false);
}
});
}
<body ng-app>
<div class="container" ng-controller="RegoController">
<div class="col-lg-4">
<form name="form">
<div class="form-group">
<label for="inputFirstName">First Name</label>
<input id="inputFirstName" class="form-control" type="text" ng-model="app.firstName" placeholder="Enter your firstname" required ng-minlength="3" ng-maxlength="20" />
</div>
<div class="form-group">
<label for="inputLastName">Last Name</label>
<input id="inputLastName" class="form-control" type="text" ng-model="app.lastName" placeholder="Enter your last name" required ng-minlength="3" ng-maxlength="20" />
</div>
<div class="form-group">
<label for="inputEmail">Email</label>
<input id="inputEmail" class="form-control" type="email" ng-model="app.email" placeholder="Enter your email" required />
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Save" />
</div>
</form>
{{app}}
</div>
</div>
</body>
The problem is that you are trying to select a form input that has no name; thus making it unable to find the field you are trying to invalidate. Here is a working example:
JSBIN: http://jsbin.com/yozanado/1/
Input field with name:
<input id="inputLastName" name="lastName" class="form-control" type="text" ng-model="app.lastName" placeholder="Enter your last name" required ng-minlength="3" ng-maxlength="20" />
Javascript:
$scope.form.lastName.$setValidity("sameName", false);
AngularJS form validation relies on the name of the form and the name of the fields to find the validation models on scope.
For example, if your HTML is:
<form name="form">
<input name="firstName" ng-model="firstName" />
</form>
You will be able to access the validation $error property on scope using the name attributes:
$scope.form.firstName.$error.sameName
To fix the issues you're having, add a name attribute to your input fields.
JSBin Demo

How to display form errors just when input are invalid and dirty?

I have working with AngularJS. I have the following form :
<html lang="en" ng-app="app">
...
<div ng-controller="RegisterController">
<h3>Register</h3>
<form name="registerForm" class="form-horizontal panel-body" novalidate="novalidate">
<form name="registerForm" class="form-horizontal panel-body" novalidate="novalidate">
<div class="form-group">
<label name="firstname" class="col-md-2 control-label">First Name</label>
<div class="col-md-4">
<input type="text" class="form-control" name="firstname" ng-model="user.firstname" placeholder="First Name" required>
</div>
</div>
<div class="form-group">
<label name="lastname" class="col-md-2 control-label">Last Name</label>
<div class="col-md-4">
<input type="text" class="form-control" name="lastname" ng-model="user.lastname" placeholder="Last Name" required>
</div>
</div>
<div class="form-group">
<label name="email" class="col-md-2 control-label">Your email</label>
<div class="col-md-4">
<input type="email" class="form-control" name="email" ng-model="user.email" placeholder="Email Address" required>
</div>
<div class="col-md-2">
<span ng-show="showError(userInfoForm.email, 'email')" ...>
You must enter a valid email
</span>
<span ng-show="showError(userInfoForm.email, 'required')" ...>
This field is required
</span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-6">
<button class="btn btn-sm btn-primary" ng-disabled="!canRegister()" ng-click="submit()">Register</button>
</div>
</div>
I have also app.js file which contains configuration and controller code, i just paste the controller code:
app.controller('RegisterController', function($scope) {
$scope.getCssClasses = function(ngModelContoller) {
return {
error: ngModelContoller.$invalid && ngModelContoller.$dirty,
success: ngModelContoller.$valid && ngModelContoller.$dirty
};
};
$scope.showError = function(ngModelController, error) {
return ngModelController.$error[error];
};
$scope.canRegister = function() {
return $scope.registerForm.$dirty &&
$scope.registerForm.$valid;
};
});
My problem is that when i load the register page ( the page which contains the form), i have the two errors are printed :
You must enter a valid email This field is required
I am wondering how to do print the error when the input is dirty and invalid and desapear when the input text is valid.
Thansk for your help
Set class "validate" on each input class, and add style.css, like:
.validate.ng-dirty.ng-invalid {
border: 2px solid red;
}
.validate.ng-dirty.ng-valid {
border: 2px solid green;
}
Here is one way (of many) to validate forms http://plnkr.co/edit/u0Wr0dza8lGnVrgwrUEa
$error is the object of errors where the key is the field validation name and value is the actual error message
<input type="email" name="emailName" ng-model="email" required>
for this example myForm.emailName.$error.email = true if email is not matched with format.
myForm.emailName.$error.required = true if you haven't added anyhting in input field
you can check valid or not of the field directly by using myForm.emailName.$valid but
the problem in your case is they want to show the user what is the error by having two cases. so they entered into $error object to check for the error is required email or invalid email
1.Email is required.
2.Invalid email address.
so they used $error object.
this is how myForm.emailName looks:
{"$viewValue":"ss","$validators":{},"$asyncValidators":{},"$parsers":[],"$formatters":[null],"$viewChangeListeners":[],"$untouched":false,"$touched":true,"$pristine":false,"$dirty":true,"$valid":false,"$invalid":true,"$error":{"email":true},"$name":"emailName","$options":null}
check this out

Resources