What is a component in Angular?
What is a pipe?
What is a service?
What is a directive?
To create an Angular project what are the minimum requirement?
· Install the latest version of node. Download and install the latest version of node from its official website.
· Install the latest version of Angular CLI by executing the following command from the windows command prompt. To install Angular CLI use the command npm install -g @angular/cli
How to know the version of node and CLI installed in your system?
To verify the version of Angular CLI installed on your machine execute the following command.
ng -v
ng -v
To verify the version of node installed on your machine.
node -v
node -v
How to create a new angular project using CLI?
Open the windows command prompt in Run as Administrative mode and execute the below command.
ng -new tells the CLI to create the new project and give your project name followed by this command.
ng new YourProjectName
See the below command: Press yes and CSS in the below command prompt window.
C:\WINDOWS\system32>ng new MyAngularTest
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? (Use arrow keys)
> CSS
SCSS [ http://sass-lang.com ]
SASS [ http://sass-lang.com ]
LESS [ http://lesscss.org ]
Stylus [ http://stylus-lang.com ]
Once successfully installed all the packages we will get the below message.
added 1102 packages in 347.571s
Directory is already under version control. Skipping initialization of git.
To run the Angular project type below commands in the command prompt.
C:\WINDOWS\system32>cd myangulartest
C:\Windows\System32\MyAngularTest>ng serve -o
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
10% building modules 3/3 modules 0 active
When successfully compiled it will open in your default browser using port number http://localhost:4200/ . When you make changes to your project code no need to compile each time. Save the code changes and CLI will take care of it. When we use ng serve -o , a lite server will start and when we will make any code changes and save it, immediately the code changes will reflect in the browser. See the below which is running and listening your code changes immediately.
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
To stop the lite server press CTRL + C and press ‘y’ to stop the lite server.
To check which version of angular you are working open the project code in Visual Studio Code. To open in Visual Studio Code execute below command:
code .
Open the package.json file and check for the dependencies and devDependencies code. There you will see the version of angular you are currently working. In our case we are working with Angular 7 as all of our dependencies are referring to “7.0.0” version. If you want to work in a particular version then we need to say the CLI and Node which version of angular you want to use in your angular project.
{
"name": "my-angular-test",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "~7.0.0",
"@angular/common": "~7.0.0",
"@angular/compiler": "~7.0.0",
"@angular/core": "~7.0.0",
"@angular/forms": "~7.0.0",
"@angular/http": "~7.0.0",
"@angular/platform-browser": "~7.0.0",
"@angular/platform-browser-dynamic": "~7.0.0",
"@angular/router": "~7.0.0",
"core-js": "^2.5.4",
"rxjs": "~6.3.3",
"zone.js": "~0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.10.0",
"@angular/cli": "~7.0.4",
"@angular/compiler-cli": "~7.0.0",
"@angular/language-service": "~7.0.0",
"@types/node": "~8.9.4",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~3.0.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.11.0",
"typescript": "~3.1.1"
}
}
What do you mean by below command?
ng new AngularTestProject --skip-tests true
Create a AngularTestProject using Angular CLI but do not create test files to be generated for the root component AppComponent, so we have set "skip-tests" option to true.
See the below lines executed in the command prompt and the executed result for it.
C:\Windows\System32\MyAngularTest>ng g c employees/listEmployees
CREATE src/app/employees/list-employees/list-employees.component.html (33 bytes)
CREATE src/app/employees/list-employees/list-employees.component.spec.ts (678 bytes)
CREATE src/app/employees/list-employees/list-employees.component.ts (300 bytes)
CREATE src/app/employees/list-employees/list-employees.component.css (0 bytes)
UPDATE src/app/app.module.ts (515 bytes)
In the above we are create a listEmployees component inside a employees//list-employees folder with out any restrictions. It is create .html, .spec.ts, .ts, .css files for it.
C:\Windows\System32\MyAngularTest>ng g c employees/listEmployees1 --spec false
CREATE src/app/employees/list-employees1/list-employees1.component.html (34 bytes)
CREATE src/app/employees/list-employees1/list-employees1.component.ts (304 bytes)
CREATE src/app/employees/list-employees1/list-employees1.component.css (0 bytes)
UPDATE src/app/app.module.ts (641 bytes)
In the above we are create a listEmployees1 component inside a employees//list-employees1 folder with restrictions not to create the spec file. It is create .html, .ts, .css files for it.
C:\Windows\System32\MyAngularTest>ng g c employees/listEmployees2 --spec false --flat true
CREATE src/app/employees/list-employees2.component.html (34 bytes)
CREATE src/app/employees/list-employees2.component.ts (304 bytes)
CREATE src/app/employees/list-employees2.component.css (0 bytes)
UPDATE src/app/app.module.ts (751 bytes)
In the above we are create a listEmployees2 component inside a employees folder with restrictions not to create the spec files and set --flat option to true as we do not want to place the ListEmployeesComponent files in its own dedicated folder. . It is create .html, .ts, .css files for it.
Describe below items and their purpose in Angular Application:
.component.css :
component.html :
.component.spec.ts :
.component.ts :
When you execute ng g c employees/listEmployees --spec false --flat true using Angular CLI what files are get updated automatically by Angular CLI?
It updates app.module.ts file as below. When ever any new component is create it must be register in app.module.ts file. Else you will get a compilation error.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ListEmployeesComponent } from './employees/list-employees.component';
@NgModule({
declarations: [
AppComponent,
ListEmployeesComponent,
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
How to install bootstrap to your angular project?
npm install bootstrap@3 –save
Where you need to refer bootstrap CSS files in your angular project?
Open the angular.json file and search for "styles": and place your bootstrap file all the places as follows: If you are not getting changes after adding bootstrap stop the lite development server and start it again. It will clean the old cache and create fresh output for you. The below lines may need to be changed a little bit, with different version of angular you working.
"styles": [
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
"styles.css"
]
How to implement Routing in Angular Application?
To implement routing in angular application, import the RouterModule into the application root module AppModule. The Router Module contains the Router service and Router directives such as (RouterLink, RouterLinkActive, RouterOutlet etc). So for us to be able to implement routing, we first need to import the Router Module in our AppModule. So in app.module.ts make the following changes.
// Import RouterModule
import { RouterModule } from '@angular/router';
// Include RouterModule in the "imports" array of the @NgModule() decorator
@NgModule({
declarations: [...
],
imports: [
BrowserModule,
RouterModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
If you are working or creating angular application with latest version angular CLI (My Version is Angular 7) you will get separate module for the routing i.e. app-routing.module.ts and it is imported in app.module.ts So we do not need to specify anything explicitly to enable routing in angular application. So our app.module.ts code will be as follows:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ListEmployeesComponent } from './employees/list-employees.component';
import { CreateEmployeeComponent } from './employees/create-employee.component';
@NgModule({
declarations: [
AppComponent,
ListEmployeesComponent,
CreateEmployeeComponent,
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
What is meaning of <router-outlet></router-outlet>
What is the meaning of the following in angular?
ngOnInit() { } : A lifecycle hook that is called after Angular has initialized all data-bound properties of a directive. Define an ngOnInit() method to handle any additional initialization tasks.
import { Component, OnInit } from '@angular/core';
Component: Supplies configuration metadata for an Angular component. Component decorator and metadata.
OnInit: A lifecycle hook that is called after Angular has initialized all data-bound properties of a directive. Define an ngOnInit() method to handle any additional initialization tasks.
<base href="/"> : All the URL are relative to the root of the application. This is used for local build.
The requested URL should be as follows:
<base href="/emp/"> : All the URL are relative to the emp folder. This is generally used for production and staging build. In production we deploy our code to a sub folder. So we have to specify the same folder name in the index.html. If we forget it, it will through an error in production. While we are building angular application for production build we can add this manually or in CLI.
To add it using CLI use the below command for production build.
ng build --base-href /emp/
The above command will create a separate folder with name “dist” for production build. Open the index.html file and you will find the /emp/ is added in base href. Now you copy this folder and deploy your code in production with sub folder emp.
What are different types of forms in Angular?
There are two types of forms in Angular
1. Template Driven Forms
2. Model Driven Forms (Commonly called Reactive Forms)
Template Driven Forms
|
Model Driven Forms or Reactive Forms
|
Template Driven forms are generally used to create simple forms.
|
Reactive forms are used to create complex forms.
|
|
Allows to add form controls dynamically or perform cross-field validation.
|
Template driven forms are heavy on the template. This means we do most of the work in the view template of the component.
|
|
|
|
Which import statement is required to create a Template Driven form in angular?
To create a Template driven form we need to import NgForm type from '@angular/forms' in app.module.ts .
import { FormsModule } from '@angular/forms';
Write code for a template driven form for a new component.
<form #employeeForm="ngForm" (ngSubmit)="saveEmployee(employeeForm)">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Create Employee</h3>
</div>
<div class="panel-body">
<div class="form-group">
<label for="fullName">Full Name</label>
<input id="fullName" type="text" class="form-control"
name="fullName" [(ngModel)]="fullName">
</div>
<div class="form-group">
<label for="email">Email</label>
<input id="email" type="text" class="form-control"
name="email" [(ngModel)]="email">
</div>
</div>
<div class="panel-footer">
<button class="btn btn-primary" type="submit">Save</button>
</div>
</div>
</form>
Now let discuss the each and every line of code which leds us to create a Template Driven form.
<form #employeeForm="ngForm" (ngSubmit)="saveEmployee(employeeForm)">
</form>
#employeeForm is called the template reference variable. Notice we have assigned "ngForm" as the value for the template reference variable employeeForm. So employeeForm variable holds a reference to the form. When Angular sees a form tag, it automatically attaches the ngForm directive to it. The ngForm directive supplements the form element with additional features. It holds all the form controls that we create with ngModel directive and name attribute, and monitors their properties like value, dirty, touched, valid etc. The form also has all these properties. We will discuss these properties at the individual control level and at the form level in detail in our upcoming videos.
The ngSubmit directive submits the form when we hit the enter key or when we click the Submit button. When the form is submitted, saveEmployee() method is called and we are passing it the employeeForm. We do not have this method yet. We will create it in the component class in just a bit.
The ngSubmit directive submits the form when we hit the enter key or when we click the Submit button. When the form is submitted, saveEmployee() method is called and we are passing it the employeeForm. We do not have this method yet. We will create it in the component class in just a bit.
The ngForm directive is provided by Angular FormsModule. So for us to be able to use it, we will have to import the FormsModule in our AppModule file (app.module.ts). So please make sure to include the following import statement. Also include "FormsModule" in the imports array of @NgModule decorator.
import { FormsModule } from '@angular/forms';
import { FormsModule } from '@angular/forms';
<div class="form-group">
<label for="fullName">Full Name</label>
<input id="fullName" type="text" class="form-control"
name="fullName" [(ngModel)]="fullName">
</div>
Except [(ngModel)] everything is bootstrap styles used to create the html controls.
The ngModel directive is used for creating two-way data binding i.e to keep the HTML element value and it's corresponding component property in sync.
Notice we have set ngModel directive to "fullName". We do not have "fullName" property in the component class. Angular automatically creates "fullName" property using the value of the "name" attribute of the HTML input element. This is why "name" attribute is also required when we use ngModel directive. If we remove the "name" attribute, we get the following error.
If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions
If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions
If you want an input element to be tracked by the form make sure to include both the name attribute and ngModel directive. Otherwise that input element will not be part of the Form model created by Angular.
How to add a Radio Button in Angular Form? Write the code.
<div class="form-group">
<label>Contact Preference</label>
<div class="form-control">
<label class="radio-inline">
<input type="radio" name="contactPreference" value="email"
[(ngModel)]="contactPreference">
Email
</label>
<label class="radio-inline">
<input type="radio" name="contactPreference" value="phone"
[(ngModel)]="contactPreference">
Phone
</label>
</div>
</div>
How to add a Textbox in angular form? Write the code.
<div class="form-group">
<label for="email">Email</label>
<input id="email" type="text" class="form-control" name="email" [(ngModel)]="email">
</div>
How to get a radio button checked by default in Angular? Write the code.
Consider the below lines of code written for radio buttons.
<div class="form-group">
<label>Contact Preference</label>
<div class="form-control">
<label class="radio-inline">
<input type="radio" name="contactPreference" value="email"
[(ngModel)]="contactPreference">
Email
</label>
<label class="radio-inline">
<input type="radio" name="contactPreference" value="phone"
[(ngModel)]="contactPreference">
Phone
</label>
</div>
</div>
<div class="form-group">
<label>Gender</label>
<div class="form-control">
<label class="radio-inline">
<input type="radio" name="gender" value="male" [(ngModel)]="gender">
Male
</label>
<label class="radio-inline">
<input type="radio" name="gender" value="female" [(ngModel)]="gender">
Female
</label>
</div>
</div>
If you will simply put the checked as below it will not work.
<input type="radio" name="gender" value="male" [(ngModel)]="gender" checked>
And
<label class="radio-inline">
<input type="radio" name="contactPreference" value="phone"
[(ngModel)]="contactPreference" checked>
To work checked we need to use two way data binding of angular. So go to the respective component class and initialize the values you need to checked when page lodes first time.
In our case I need to male and phone radio buttons need to be checked when page loads first time. So we need to define the initial values for this as below in the component class.
gender = 'male';
contactPreference='phone';
How to disable the radio buttons in angular? Write the code.
<div class="form-group">
<label>Gender</label>
<div class="form-control">
<label class="radio-inline">
<input type="radio" name="gender" value="male" [(ngModel)]="gender" disabled>
Male
</label>
<label class="radio-inline">
<input type="radio" name="gender" value="female" [(ngModel)]="gender" disabled>
Female
</label>
</div>
</div>
How to add a check box in angular? Write the code.
<div class="form-group">
<div class="form-control">
<label class="checkbox-inline">
<input type="checkbox" name="isActive" [(ngModel)]="isActive">
Is Active
</label>
<label class="checkbox-inline">
<input type="checkbox" name="inActive" [(ngModel)]="inActive">
In Active
</label>
</div>
</div>
How to get a check box checked by default in Angular? Write the code.
Intialize the value in respective componenet class as below.
isActive = true;
How to disable a checkbox ?
To disable a checkbox, use the disabled attribute
<input type="checkbox" name="isActive" [(ngModel)]="isActive" disabled>Is Active
How to add a select list / dropdown in angular form? Write the code.
<div class="form-group">
<label for="department">Department</label>
<select id="department" name="department"
[(ngModel)]="department" class="form-control">
<option value="1">Help Desk</option>
<option value="2">HR</option>
<option value="3">IT</option>
<option value="4">Paroll</option>
</select>
</div>
How to have one of the select list option selected by default? Write the code.
<div class="form-group">
<label for="department">Department</label>
<select id="department" name="department" class="form-control">
<option value="1">Help Desk</option>
<option value="2">HR</option>
<option value="3" selected>IT</option>
<option value="4">Paroll</option>
</select>
</div>
The above code will not work
To be selected when page loaded first time, initialize the value in the respective component class as below
department = '3'
How to disable a select list ?
To disable a select element, use the disabled attribute
<select id="department" name="department" [(ngModel)]="department"
class="form-control" disabled>
how to get the select list options from the component class, instead of having them hard-coded in the HTML?
Create a Department class and add below code.
export class Department {
id: number;
name: string;
}
Import the Department class when you want to put your dropdown/ select list.
import { Department} from '../models/Department';
Add the values to the Department class as follows.
department = '4';
departments: Department[] = [
{ id: 1, name: 'Help Desk' },
{ id: 2, name: 'HR' },
{ id: 3, name: 'IT' },
{ id: 4, name: 'Payroll' }
];
The first line of the code takes department = 4 which means when page loads first time Payroll will be displayed as default value. The next line of code assigns the value for the dropdown list. In the respective html page we need to add the below lines of code.
<div class="form-group">
<label for="department">Department</label>
<select id="department" name="department" [(ngModel)]="department"
class="form-control">
<option *ngFor="let dept of departments" [value]="dept.id">
{{dept.name}}
</option>
</select>
</div>
Look at the below code
<option *ngFor="let dept of departments" [value]="dept.id">
{{dept.name}}
</option>
It loops by using *ngFor directive and retrieves all the values for the dropdown list.
How to add a date picker to angular form? Write the code.
There are no of third party date picker controls are present in the web. We will use bootstrap date picker to get a consistent look and feel across the browsers.
First install the bootstrap and then install the ngx-bootstrap if not installed before.
npm install bootstrap@3 –save
npm install ngx-bootstrap –save
Using ngx-bootstrap datepicker in Angular :
Step 1 : In app.module.ts file, include the following import statement to import BsDatepickerModule
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
Also, include BsDatepickerModule in the imports array of @NgModule decorator as shown below
Also, include BsDatepickerModule in the imports array of @NgModule decorator as shown below
@NgModule({
imports: [BsDatepickerModule.forRoot(),...]
})
Step 2 : In ".component.html" file, make the following 2 changes to the HTML that displays the "Date of Birth" field
<div class="form-group">
<label for="dateOfBirth">Date of Birth</label>
<input id="dateOfBirth" name="dateOfBirth" [(ngModel)]="dateOfBirth"
type="text" bsDatepicker class="form-control" />
</div>
Step 3 : Include a reference to the bs-datepicker.css file in .angular-cli.json file.
"styles": [
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
"./node_modules/ngx-bootstrap/datepicker/bs-datepicker.css",
"src/styles.css"
],
If you want to add a date range then you can add the following code:
<div class="form-group">
<label for="dateWorkExperiance">Work Exprience</label>
<input id="dateWorkExperiance" name="dateWorkExperiance" [(ngModel)]="dateWorkExperiance"
type="text" bsDaterangepicker class="form-control" />
</div>
How to customize the date picker control in angular? Write the code.
How to change the theme of a data picker?
Import the below in the component class where you want to implement the theme customization.
import { BsDatepickerConfig } from 'ngx-bootstrap/datepicker';
Add the below code in component class:
datePickerConfig: Partial<BsDatepickerConfig>;
Add the below code in constructor of the component:
constructor() {
this.datePickerConfig = Object.assign({},
{ containerClass: 'theme-dark-blue' });
}
Add the below code in the respective html file.
<div class="form-group">
<label for="dateWorkExperiance">Work Exprience</label>
<input id="dateWorkExperiance" name="dateWorkExperiance" [(ngModel)]="dateWorkExperiance"
type="text" bsDaterangepicker [bsConfig]="datePickerConfig" class="form-control" />
</div>
Now you will get the blue theme for the date picker control.
Below are the themes you can apply for the bootstrap date picker:
· theme-default
· theme-green
· theme-blue
· theme-dark-blue
· theme-red
· theme-orange
How to show and hide the week numbers for a date picker control in angular? Write the code.
Add the below code in the constructor of the respective class where you want to implement the show and hide for the week number.
constructor() {
this.datePickerConfig = Object.assign({},
{
containerClass: 'theme-dark-blue',
showWeekNumbers: false
});
}
And call datePickerConfig in the respective html file for the date picker control.
<div class="form-group">
<label for="dateWorkExperiance">Work Exprience</label>
<input id="dateWorkExperiance" name="dateWorkExperiance" [(ngModel)]="dateWorkExperiance"
type="text" bsDaterangepicker [bsConfig]="datePickerConfig" class="form-control" />
</div>
How to set the min and max date for a date picker control in angular?
Add the below code in the constructor of the respective class where you want to implement the show and hide for the week number.
constructor() {
this.datePickerConfig = Object.assign({},
{
containerClass: 'theme-dark-blue',
showWeekNumbers: false,
minDate: new Date(2018, 0, 1),
maxDate: new Date(2018, 11, 31)
});
}
And call datePickerConfig in the respective html file for the date picker control.
<div class="form-group">
<label for="dateWorkExperiance">Work Exprience</label>
<input id="dateWorkExperiance" name="dateWorkExperiance" [(ngModel)]="dateWorkExperiance"
type="text" bsDaterangepicker [bsConfig]="datePickerConfig" class="form-control" />
</div>
How to change the data format for a date picker control in angular?
Add the below code in the constructor of the respective class where you want to implement the show and hide for the week number.
constructor() {
this.datePickerConfig = Object.assign({},
{
containerClass: 'theme-dark-blue',
showWeekNumbers: false,
minDate: new Date(2018, 0, 1),
maxDate: new Date(2018, 11, 31),
dateInputFormat: 'DD/MM/YYYY'
});
}
And call datePickerConfig in the respective html file for the date picker control.
<div class="form-group">
<label for="dateWorkExperiance">Work Exprience</label>
<input id="dateWorkExperiance" name="dateWorkExperiance" [(ngModel)]="dateWorkExperiance"
type="text" bsDaterangepicker [bsConfig]="datePickerConfig" class="form-control" />
</div>
How to enable browser native validation in angular 4 and later version?
By default browser native validation is disable in angular 4 and later versions to avoid inconsistency from browser to browser. I you want to enable the browser native validation we need to do enable it explicitly on each control or at form level as follows:
<form #employeeForm="ngForm" ngNativeValidate
(ngSubmit)="saveEmployee(employeeForm)">
Why is it better to disable browser built-in validation and use Angular to validate instead?
Different browser vendors implement browser validation differently and as a result, the end users have different experience depending on the browser they use. Because of this inconsistency it is better to disable browser native validation and use Angular instead to validate form fields.
Different browser vendors implement browser validation differently and as a result, the end users have different experience depending on the browser they use. Because of this inconsistency it is better to disable browser native validation and use Angular instead to validate form fields.
How to handle required validation in angular?
Lets we have text box and we want to apply required validation on it. When page loads first time and end user touches the textbox control and without entering any data leaves then it should trigger an error. See the below code:
<div class="form-group" [class.has-error]="fullNameControl.invalid && fullNameControl.touched">
<label for="fullName" class="control-label">Full Name</label>
<input id="fullName" required type="text" class="form-control" name="fullName" [(ngModel)]="fullName"
#fullNameControl="ngModel">
<span class="help-block" *ngIf="fullNameControl.invalid && fullNameControl.touched">
Full Name is required
</span>
</div>
In the above code look at the below lines of code which are handling the Required validation error.
[class.has-error]="fullNameControl.invalid && fullNameControl.touched"
<span class="help-block" *ngIf="fullNameControl.invalid && fullNameControl.touched">
How to disable the Save button when form is not valid?
<div class="panel-footer">
<button class="btn btn-primary" type="submit"
[disabled]="employeeForm.invalid">Save</button>
</div>
employeeForm is the name of the form. See the below code.
<form #employeeForm="ngForm" (ngSubmit)="saveEmployee(employeeForm)">
</form>
When page first loads Save button is disable by default as form is empty and not valid. When it satisfy all the validations defined in the form Save button got enabled automatically.
How to apply multiple validations in single Control in angular?
Let’s we have a Email field in our form. We want to validate this as Required and validate email. To make it required we can apply below code:
<div class="form-group" [class.has-error]="emailControl.invalid && emailControl.touched"
[class.has-success]="emailControl.valid">
<label for="email" class="control-label">Email</label>
<input id="email" required type="text" class="form-control" name="email" [(ngModel)]="email"
#emailControl="ngModel">
<span class="help-block" *ngIf="emailControl.invalid && emailControl.touched">
Email is required
</span>
</div>
To allow only the valid emails we can use angular email validator. This is available only angular 4 and above versions.
<div class="form-group" [class.has-error]="emailControl.invalid && emailControl.touched"
[class.has-success]="emailControl.valid">
<label for="email" class="control-label">Email</label>
<input id="email" required email type="text" class="form-control" name="email" [(ngModel)]="email"
#emailControl="ngModel">
<span class="help-block" *ngIf="emailControl.invalid && emailControl.touched">
Email is required
</span>
<span class="help-block" *ngIf="emailControl.errors?.email && emailControl.touched">
Email is Invalid
</span>
</div>
The problem with above code is it will trigger both the required and email validation errors when email field left empty. To fix this issue we can write the below:
<div class="form-group" [class.has-error]="emailControl.invalid && emailControl.touched"
[class.has-success]="emailControl.valid">
<label for="email" class="control-label">Email</label>
<input id="email" required [email]="employee.email!==''" type="text" class="form-control" name="email" [(ngModel)]="email"
#emailControl="ngModel">
<span class="help-block" *ngIf="emailControl.invalid && emailControl.touched">
Email is required
</span>
<span class="help-block" *ngIf="emailControl.errors?.email && emailControl.touched">
Email is Invalid
</span>
</div>
In the respective component class initialize the email field as empty string as follows:
employee: Employee = {
id: null,
name: null,
gender: null,
contactPreference: null,
phoneNumber: null,
email: null,
dateOfBirth: null,
department: null,
isActive: null,
photoPath: null
};
If you are working with older versions of angular then use pattern matching logic to validate email field. It is easy and straight forward.
<div class="form-group" [class.has-error]="emailControl.invalid && emailControl.touched" [class.has-success]="emailControl.valid">
<label for="email" class="control-label">Email</label>
<input id="email" required pattern="^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$" type="text" class="form-control"
name="email" [(ngModel)]="email" #emailControl="ngModel">
<span class="help-block" *ngIf="emailControl.invalid && emailControl.touched">
Email is required
</span>
<span class="help-block" *ngIf="emailControl.errors?.pattern && emailControl.touched">
Email is Invalid
</span>
</div>
If you want to allow a specific domain like .com, .in, .cc then you can define in pattern matching string. In the below code we are allowing only .com domains as valid email.
<div class="form-group" [class.has-error]="emailControl.invalid && emailControl.touched" [class.has-success]="emailControl.valid">
<label for="email" class="control-label">Email</label>
<input id="email" required
pattern="^[a-zA-Z0-9_.+-]+@(?:(?:[a-zA-Z0-9-]+\.)?[a-zA-Z]+\.)?\.com$"
type="text" class="form-control"
name="email" [(ngModel)]="email" #emailControl="ngModel">
<span class="help-block" *ngIf="emailControl.invalid && emailControl.touched">
Email is required
</span>
<span class="help-block" *ngIf="emailControl.errors?.pattern && emailControl.touched">
Email is Invalid
</span>
</div>
How to apply validations to Radio Buttons in angular?
Let’s we have a Radio Button Gender. If you want required field validation for this follow the below code.
<div class="form-group" [class.has-error]="gender.invalid">
<label class="control-label">Gender</label>
<div class="form-control">
<label class="radio-inline">
<input type="radio" name="gender" required #gender="ngModel" value="male" [(ngModel)]="employee.gender">
Male
</label>
<label class="radio-inline">
<input type="radio" name="gender" required #gender="ngModel" value="female" [(ngModel)]="employee.gender">
Female
</label>
</div>
<span class="help-block" *ngIf="gender.invalid">
Gender is required
</span>
</div>
How to add required validator dynamically?
Let’s we have Contact Preference Radio Buttons called Email and Phone number. If Email is selected then it will highlight the Email field and if Phone number is selected it should highlight the Phone number field. See the below code for this requirement.
<div class="form-group" [class.has-error]="contactPreference.invalid">
<label class="control-label">Contact Preference</label>
<div class="form-control">
<label class="radio-inline">
<input type="radio" required #contactPreference="ngModel" name="contactPreference"
value="email" [(ngModel)]="employee.contactPreference"> Email
</label>
<label class="radio-inline">
<input type="radio" required #contactPreference="ngModel" name="contactPreference"
value="phone" [(ngModel)]="employee.contactPreference"> Phone
</label>
</div>
<span class="help-block" *ngIf="contactPreference.errors?.required">
Contact Preference is required
</span>
</div>
<div class="form-group" [class.has-error]="email.invalid">
<label for="email" class="control-label">Email</label>
<input id="email" [required]="contactPreference.value=='email'"
type="text" class="form-control"
pattern="^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"
[(ngModel)]="employee.email" #email="ngModel" name="email">
<span class="help-block" *ngIf="email.errors?.required">
Email is required
</span>
<span class="help-block" *ngIf="email.errors?.pattern && email.touched">
Email is Invalid
</span>
</div>
<div class="form-group" [class.has-error]="phoneNumber.invalid">
<label for="phoneNumber" class="control-label">Phone Number</label>
<input id="phoneNumber" [required]="contactPreference.value=='phone'"
#phoneNumber="ngModel" class="form-control" type="text"
name="phoneNumber" [(ngModel)]="employee.phoneNumber">
<span class="help-block" *ngIf="phoneNumber.errors?.required">
Phone Number is required
</span>
</div>
How to implement validation for Checkboxes in angular?
See the below code to make a check box field required.
<div class="form-group" [class.has-error]="isActive.invalid && isActive.touched">
<div class="form-control">
<label class="checkbox-inline control-label">
<input type="checkbox" required name="isActive" #isActive="ngModel" [(ngModel)]="employee.isActive">
Is Active
</label>
</div>
<span class="help-block" *ngIf="isActive.errors?.required && isActive.touched">
Is Active is required
</span>
</div>
How to apply validation for Dropdown list in angular?
To apply validation for select list or dropdown list apply the below code.
<div class="form-group" [class.has-error]="department.touched && department.invalid">
<label for="department" class="control-label">Department</label>
<select id="department" required #department="ngModel" name="department" [(ngModel)]="employee.department"
class="form-control">
<option *ngFor="let dept of departments" [value]="dept.id">
{{dept.name}}
</option>
</select>
<span class="help-block" *ngIf="department.touched && department.invalid">
Department is required
</span>
</div>
How to add a text “ – Select List – “ in Dropdown when page loads first time in angular?
See the below code to add default text in Dropdown when page loads first time.
<div class="form-group" [class.has-error]="department.touched && department.invalid">
<label for="department" class="control-label">
Department
</label>
<select id="department" required #department="ngModel" name="department" [(ngModel)]="employee.department"
class="form-control">
<option value="-1">Select Department</option>
<option *ngFor="let dept of departments" [value]="dept.id">
{{dept.name}}
</option>
</select>
<span class="help-block" *ngIf="department.touched && department.invalid">
Department is required
</span>
</div>
The above code will give you blank text to the Dropdown. We need to tell the model binding in angular what to bind when page loads first time. Add the below code in respective component class.
employee: Employee = {
id: null,
name: null,
gender: null,
contactPreference: null,
phoneNumber: null,
email: null,
dateOfBirth: null,
department: '-1',
isActive: null,
photoPath: null
};
Comment the below line of code or remove it.
//department = '4';
Now when page loads first time it will show “Select Department” in the Dropdown list.
What is ngvalue in angular?
What is value in angular?
How to validate two input fields for equality check in angular?
In angular we can not apply any built in validator for equality checking. To achieve this we have to create custom validator using a directive. Validating email with confirm email field , validating password with confirm password are the examples. This is also called cross field validation in angular.
We can reuse this validation when ever we are validating two input controls. So this a reusable code. Create shared folder in your application and keep all reusable code in it. Create a typescript file in Shared folder “confirm-equal-validator.directive.ts” and add the below code.
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
import { Directive, Input } from '@angular/core';
@Directive({
selector: '[appConfirmEqualValidator]',
providers: [{
provide: NG_VALIDATORS,
useExisting: ConfirmEqualValidatorDirective,
multi: true
}]
})
export class ConfirmEqualValidatorDirective implements Validator {
@Input() appConfirmEqualValidator: string;
validate(control: AbstractControl): { [key: string]: any } | null {
const controlToCompare = control.parent.get(this.appConfirmEqualValidator);
if (controlToCompare && controlToCompare.value !== control.value) {
return { 'notEqual': true };
}
return null;
}
}
Add the import statement in app.module.ts as below
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ListEmployeesComponent } from './employees/list-employees.component';
import { CreateEmployeeComponent } from './employees/create-employee.component';
import { ConfirmEqualValidatorDirective } from './shared/confirm-equal-validator.directive';
@NgModule({
declarations: [
AppComponent,
ListEmployeesComponent,
CreateEmployeeComponent,
ConfirmEqualValidatorDirective
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
BsDatepickerModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Add the below line of code to the respective html file.
<div class="form-group" [class.has-error]="confirmPassword.touched && confirmPassword.invalid">
<label for="confirmPassword" class="control-label">Confirm Password</label>
<input name="confirmPassword" appConfirmEqualValidator="password" required id="confirmPassword" type="text"
class="form-control" [(ngModel)]="employee.confirmPassword" #confirmPassword="ngModel">
<span class="help-block" *ngIf="confirmPassword.touched && confirmPassword.errors?.required">
Confirm Password is required
</span>
<span class="help-block" *ngIf="confirmPassword.touched && confirmPassword.errors?.notEqual &&
!confirmPassword.errors?.required">
Password and Confirm Password does not match
</span>
</div>
At the moment we have a problem with confirm password field validation. It does not work in one of the scenarios. Here is the scenario.
If you first change PASSWORD field and then the CONFIRM PASSWORD field, the validation works as expected. Now if you go back and change the PASSWORD field, the validation will not be triggered and you will not see the validation error even if the passwords do not match.
This is because our custom validation directive is applied on the confirm password filed but not on the password. So our custom validation is triggered only when the confirm password field is changed and not when the password field is changed. To make this work, even when the password field is changed, we have to tell confirm password field to run its validation when password field is changed.
If you first change PASSWORD field and then the CONFIRM PASSWORD field, the validation works as expected. Now if you go back and change the PASSWORD field, the validation will not be triggered and you will not see the validation error even if the passwords do not match.
This is because our custom validation directive is applied on the confirm password filed but not on the password. So our custom validation is triggered only when the confirm password field is changed and not when the password field is changed. To make this work, even when the password field is changed, we have to tell confirm password field to run its validation when password field is changed.
We can use updateValueAndValidity() function to overcome this issue. When this method is called on a control, that control's validation logic is executed again. Notice the event binding in the example below. The change event of the password field triggers a call to confirm password field's updateValueAndValidity() function. This in turn runs the confirm password field validation.
Change the below code in passoword input control as follows:
<div class="form-group" [class.has-error]="password.touched && password.invalid">
<label for="password" class="control-label">Password</label>
<input id="password" required type="text" class="form-control" name="password" [(ngModel)]="employee.password"
#password="ngModel" (change)="confirmPassword.control.updateValueAndValidity()">
<span class="help-block" *ngIf="password.touched && password.errors?.required">
Password is required
</span>
</div>
How to add and remove validation styles to a group of elements in Angular?
Use the ngModelGroup directive and group the elements. Now we can add or remove validation styles from the group. This in turn adds or removes the validation styles from all the elements in that group.
No comments:
Post a Comment