Angular template driven form on submit validation - javascript

In angular js, we have $submitted to populate error messages on submit click.
How can we display all validation errors on submit click in Angular
HTML:
<form #nameForm="ngForm" novalidate (ngSubmit)="saveNameForm(formModel)">
<div class="form-group">
<label for="inputName" class="form-control-label"> Name</label>
<input type="text" id="inputName" name="lotCode [(ngModel)]="formModel.name" #lotCode="ngModel" aria-describedby="nameHelp"
autocomplete="new-password" required>
<small id="nameHelp" class="text-danger" *ngIf="lotCode.invalid && lotCode.touched">Required</small>
</div>
<div class="form-group">
<label for="inputDescription" class="form-control-label"> Description</label>
<input type="text" id="inputDescription" name="desCode" [(ngModel)]="formModel.description" #desCode="ngModel" aria-describedby="descriptionHelp"
autocomplete="new-password" required>
<small id="descriptionHelp" class="text-danger" *ngIf="desCode.invalid && desCode.touched">Required</small>
</div>
<button type="submit">Submit </button>
</form>
Component:
export class AppComponent {
formModel: FormModel= new FormModel();
saveNameForm(formModel){
console.log(formModel)
}
}
export class FormModel {
name: string;
description:string;
}
https://stackblitz.com/edit/angular-rizsuy?file=src%2Fapp%2Fapp.component.ts

Here is the solution:
https://stackblitz.com/edit/angular-8jaaqz?file=src%2Fapp%2Fapp.component.html
You should use a variable to set submitted
if submitted then will display error

Angular uses the same form validation that native HTML5 does. Just do this in an Angular context. In the following example, we can use *ngIf to control the display of the messages, and .dirty and .touched to determine if the user interacted with the input.
Example from docs:
<input id="name" name="name" class="form-control"
required minlength="4" appForbiddenName="bob"
[(ngModel)]="hero.name" #name="ngModel" >
<div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert alert-danger">
<div *ngIf="name.errors.required">
Name is required.
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors.forbiddenName">
Name cannot be Bob.
</div>
</div>

Related

maxlegth not working using template driven form in angular 6

I am developing one register form in that form i need maxlength validation but using template driven form can't show maxlength alert message.
<input type="text" class="form-control" placeholder="Enter Name"maxlength="4"
name="name" [(ngModel)]="name" ngModel required #username="ngModel">
<div *ngIf="username.invalid && (username.dirty || username.touched)">
<p style="color:red;font-size:10px;" *ngIf='username.invalid.maxlength'>
You enter only 4 characters.
</p>
</div>
Try:
<form name="form" role="form" #form="ngForm">
<div class="form-group">
<label class="form-control-label" for="userName">UserName</label>
<input
type="userName"
class="form-control"
id="userName"
name="userName"
#userNameInput="ngModel" //ngModel variable and template variable should not be the same
[(ngModel)]="userName"
minlength=4
maxlength=50
required>
<div *ngIf="userNameInput.dirty && userNameInput.invalid">
<small class="form-text text-danger" *ngIf="userNameInput.errors.required">
Your userName is required.
</small>
<small class="form-text text-danger" *ngIf="userNameInput.errors.minlength">
Your userName is required to be at least 4 characters.
</small>
<small class="form-text text-danger" *ngIf="userNameInput.errors.maxlength">
Your username cannot be longer than 50 characters.
</small>
</div>
</div>
</form>
DEMO
For me, the issue was input type="number".
Once I removed the type number maxLength worked.
Angular version: 8
username.invalid will be username.errors?
*ngIf="username.errors?.maxlength"
so there are a couple of steps to follow to validate your input like
please check this
<input
type="text"
placeholder="Your full name"
name="name"
ngModel
#userName="ngModel"
maxlength="4"
required>
<div *ngIf="userName.errors?.minlength && userName.touched" class="error">
Minimum of 4 characters
</div>
?.prop is called the “Safe navigation operator”
that means it avoids an exception for null and undefined values in in property paths
As if you use maxlength property for input type it does not allows a user to type anything beyond that length [As I tested in Chrome].
So if you want to display an alert or error message then you can check for input's length property and display error message:
HTML:
Remove maxlength from input type and check for username.value?.length in if condition
<input type="text" class="form-control" placeholder="Enter Name" name="username" [(ngModel)]="name" ngModel required #username="ngModel">
<div *ngIf="username.value?.length > 4">
<p style="color:red;font-size:10px;">
You enter only 4 characters.
</p>
</div>
WORKING DEMO
I needed to validate the length using the template only and I need it to invalidate the form as well so here is what I did using pattern
<textarea class="form-control" id="Command" rows="3" name="dialogCommand" pattern="^(.|\n){0,4000}$" #comment="ngModel" [(ngModel)]="comment" [ngClass]="{ 'is-invalid': comment?.errors?.pattern }"></textarea>
<div class="text-danger small" *ngIf="comment?.errors?.pattern">The comment cannot be greater than 4000 characters long</div>
This will count on multiple lines.
Hope this helps someone

Bootstrap 4 Form Validation with Javascript /jQuery

I am new to web development, and am trying to set up a practice form to learn form validation. I am following Bootstrap's doc for Custom Styles to handle those with accessibility issues that use screen readers, and to standardize the validation appearance to users across different browsers.
I have set up a basic form as well as am trying to create a JavaScript function using jQuery to handle the validation. I feel like I am almost there, but still do not have the validation working as the Bootstrap demo displays.
index.html
<form id="signup-form" novalidate>
<div class="form-group">
<h1>Sign Up</h1>
<p>Use this form to enter your name and email to sign up.</p>
</div>
<!-- Name -->
<div class="form-group">
<div class="row">
<div class="col">
<label for="firstNameInput">Name</label>
<input type="text" class="form-control" id="firstNameInput" placeholder="First name" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col">
<label for="lastNameInput">Last</label>
<input type="text" class="form-control" id="lastNameInput" placeholder="Last name" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
</div>
</div>
<!-- Email -->
<div class="form-group">
<label for="emailAddressInput">Email address</label>
<input type="email" class="form-control" id="emailAddressInput" aria-describedby="emailHelp" placeholder="name#example.com" required>
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
<div class="invalid-feedback">
Please provide a valid email.
</div>
</div>
<!-- Options -->
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="radio" name="Radios" id="type1RadioButton" value="option1" checked>
<label class="form-check-label" for="type1RadioButton">
Type 1 user
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="Radios" id="type2RadioButton" value="option2">
<label class="form-check-label" for="type2RadioButton">
Type 2 user
</label>
</div>
</div>
<!-- Submit Button -->
<div class="form-group">
Submit
</div>
</form>
script.js
$(document).ready(function() {
$("#submitButton").click(function() {
//Fetch form to apply custom Bootstrap validation
var form = $("#signup-form")
//alert(form.prop('id')) //test to ensure calling form correctly
if (form.checkValidity() === false) {
event.preventDefault()
event.stopPropagation()
}
form.addClass('was-validated')
})
})
The problem is that checkValidity() exists on the first form node, not the form.
Change this: form.checkValidity() === false
to this: form[0].checkValidity() === false
and it works: https://www.codeply.com/go/pUPBLzn6yL
$(document).ready(function() {
$("#submitButton").click(function() {
//Fetch form to apply custom Bootstrap validation
var form = $("#signup-form")
alert(form.prop('id')) //test to ensure calling form correctly
if (form[0].checkValidity() === false) {
event.preventDefault()
event.stopPropagation()
}
form.addClass('was-validated');
//Make ajax call here
})
})
More on Bootstrap 4 Validation:
Can't make the validation work in Bootstrap 4

Updated Angular version causes error on ngMessages

I updated AngularJs version from 1.3 to 1.4.
It causes an error as,
Syntax Error: Token '{' invalid key at column 2 of the expression
[{{frmname}}.emailAddress.$error] starting at
[{frmname}}.emailAddress.$error].
It works perfectly in Angular 1.3
<form name="{{frmname}}">
<h1>My form name = {{frmname}}</h1>
<div class="field">
<label for="emailAddress">Enter your email address:</label>
<input type="email" name="emailAddress" ng-model="email" required />
<div ng-messages="{{frmname}}.emailAddress.$error">
<div ng-message="required">
You forgot to enter your email address...
</div>
<div ng-message="email">
You did not enter your email address correctly...
</div>
</div>
</div>
<input type="submit" />
</form>
FIDDLE
If you need to set your form name from a dynamic variable then you could use ng-form to validate your inputs inside the actual form.
Basic html:
<form name="{{formName}}" novalidate>
<ng-form name="emailError">
<div ng-messages="emailError.emailAddress.$error" style="color:maroon" role="alert">
<label for="emailAddress">Enter your email address:</label>
<input type="email" name="emailAddress" ng-model="email" minlength="5" required />
<div ng-messages="emailError.emailAddress.$error" style="color:maroon" role="alert">
<div ng-message="required">You did not enter a field</div>
</div>
</ng-form>
<input type="submit" />
</form>
Plunker: https://plnkr.co/edit/Q0ifmRXKkLfwKGNqv8p4?p=preview
Official documentation of ngForm: https://docs.angularjs.org/api/ng/directive/ngForm
Finally i got the solution,
Add a function for getting ng-messages attribute value.
<div ng-messages="getMessages('emailAddress')">
<div ng-message="required">
You forgot to enter your email address...
</div>
<div ng-message="email">
You did not enter your email address correctly...
</div>
</div>
Declare the function inside your controller or directive.
$scope.getMessages = function (el) {
return $scope.$eval($scope.frmname)[el].$error;
}
FIDDLE

AngularJS Form validation Group error message

In angularJs FORM SUBMIT how to display all validation messagees in one single div at bottom of the page. Ex:
<div id="err-msg"> <!-- error message will come here --></div>
I referred documents but all are displaying below the text box using
<p ng-show="userForm.email.$invalid && !userForm.email.$pristine" class="alert alert-danger">Enter a valid email.</p>
How to write one area to bind all the messages in to same place (avoid use this userForm.email.$invalid)
Note I tried ng-message but am not clear any one help me. Please refer the below code for normal HMTL jQuery error display like need to take care using the AngularJS
HTML
<div id="main">
<form> <div><input id="email_txt" type="text" name ="email" value="" > </div>
<div><input id="pass_txt" type="password" name ="password" value="" > </div>
<div><input id="validate_btn" type="submit" value="Validate" > </div>
</form>
</div>
<div id="err-msg"> <!-- error message will come here --></div>
jQuery:
$('#main').on('click', '#validate_btn', function() {
if($('#email_txt').val().length == 0){
$('#err-msg').val("Please enter emailid!");
}else if($('#pass_txt').val().length == 0){
$('#err-msg').val("Please enter password!");
}
...
...
else{
alert("Good");
}
});
AngularJS current code :
<form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate>
<div class="form-group">
<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>
<input type="email" name="email" class="form-control" ng-model="email">
<p ng-show="userForm.email.$invalid && !userForm.email.$pristine" class="help-block">Enter a valid email.</p>
<button type="submit" class="btn btn-primary">Submit</button>
<form>
app.js
.controller('validatectrl',['$scope',function($scope){
$scope.submitForm = function(isValid) {
// check to make sure the form is completely valid
if (isValid) {
alert('Good');
}
};
}]);
How to rewrite?
If a form is invalid, the errors will be stored in the object $scope.form.$error. Please check console of this JSFiddle. From the $error property on the form, you can populate the error messages.
angular.module('Joy', [])
.controller('FormCtrl', ['$scope', function ($scope) {
$scope.user = {};
$scope.submit = function () {
console.log($scope.userInfo);
};
}]);
The HTML:
<div ng-app="Joy" id="play-ground">
<form name="userInfo" novalidate ng-controller="FormCtrl">
<div class="ui input">
<input ng-model="user.email" ng-message="YOU ARE WRONG" name="User Email" type="email">
</div>
<div class="ui input">
<input ng-model="user.name" name="User Name" type="text" required>
</div>
<div class="ui divider"></div>
<button class="ui primary button" ng-click="submit()">Submit</button>
<div class="ui positive message">User: {{ user | json }}</div>
</form>
</div>

Confirm password custom directive is not working in Angular

I try to implement confirm password validation in angular view. write new
directive in app.js
and add compare-to in confirm password text box
<div class="form-group">
<label class="control-label col-sm-2" for="pwd">Password:</label>
<div class="col-sm-10">
<input type="password"
class="form-control"
placeholder="Enter password"
ng-model="Password"
ng-minlength="5">
<span class="validationMessage" ng-show="frm.password.$dirty && frm.password.$error.required">Required!</span>
<span class="validationMessage" ng-show="frm.password.$dirty && frm.password.$error.minlength">Min length 5!</span>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="pwd">Confirm Password:</label>
<div class="col-sm-10">
<input type="password"
class="form-control"
ng-model="ConfirmPassword"
required
compare-to="Password"
placeholder="Enter Confirm password">
<span class="validationMessage" ng-show="frm.ConfirmPassword.$error">Required!</span>
</div>
</div>
But the confirm password is not shows any validation. and show a error message Cannot set property 'compareTo' of undefined in chrome.
It's working, mostly. You just have little logic flaws there.
First of all, using <label for="x"> expects template to have a element with id="x" present. Nothing major there but when you check for form validity you should refer to your form fields, not underlying model.
So instead of frm.<ng-model-var>.$error you should type in frm.<form-field-name>.$error.
You need to add names for your inputs, and check your form validation logic once more. This should work fine for your password.
<!-- added required, input name, changed validation logic -->
<input type="password"
name="password"
class="form-control"
placeholder="Enter password"
ng-model="Password"
required
ng-minlength="5" />
<span class="validationMessage"
ng-show="frm.password.$error.required">
Required!
</span>
<span class="validationMessage"
ng-show="frm.password.$dirty && frm.password.$error.minlength">
Min length 5!
</span>
and this for your confirm password.
<!-- added input name, changed validation logic -->
<input type="password"
name="confirmpassword"
class="form-control"
placeholder="Enter Confirm password"
ng-model="ConfirmPassword"
required
compare-to="Password" />
<span class="validationMessage"
ng-show="frm.password.$valid && frm.confirmpassword.$invalid">
Passwords do not match!
</span>
Try with updated versions
http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js
https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular-route.min.js
and in your controller.js add this..
'ngRoute'
var loginApp = angular.module('indexApp', ['authModule','requestModule','ngRoute']);

Categories