Simple CRUD functionality using Angular 5 with Bootstrap 4
In this post let’s see how to create a simple Angular 5 project with Bootstrap 4 for performing the CRUD operation.
The following are prerequisites for this project:
· Node.js
· Node package manager (NPM)
· Visual Studio code (Optional)
Open the visual studio code editor with Integrated Terminal window (View > Integrated Terminal).
Make sure both Node and NPM are installed on your system by using the following command.
node -vnpm -v
It shows version number if it’s installed already as seen below.
Installing Angular CLI latest version. (https://cli.angular.io)
npm install --save-dev @angular/cli@latest
It takes a couple of minutes for installation. Once installed, make sure CLI is installed properly.
ng -v
It shows Angular CLI version as seen below.
Create a new angular 5 project. The name of the project will be angular5bootstrap4 (use any name).
ng new angular5bootstrap4 --routing
— routing flag adding routing functionality to project.
It also takes a couple of minutes for creating a project.
Once the project is created, change the current directory into the newly created project directory.
cd angular5bootstrap4
The project file structure is created as seen below.
Run the application.
ng serve
Now the web server is started and the application can be accessed on http://localhost:4200 as you see in the below screenshot.
Let’s add Bootstrap 4 functionality.
Install Bootstrap 4 library by using the below command.
npm install --save bootstrap@next
Bootstrap 4 library added into the folder node_modules/bootstrap.
Import bootstrap.css file into the project by adding the below line in style.css file.
@import "~bootstrap/dist/css/bootstrap.css";
Need to Install Bootstrap 4 directives (https://ng-bootstrap.github.io) for angular. Since we will use few Bootstrap components in this application.
Use the below comment to install Bootstrap 4 components.
npm install --save @ng-bootstrap/ng-bootstrap
After installation, NgbModule must be imported in app.module.js.
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
The NgbModule also needs to be added to the imports array with forRoot() method as seen below.
@NgModule({declarations: [AppComponent],imports: [BrowserModule,AppRoutingModule,NgbModule.forRoot()],providers: [],bootstrap: [AppComponent]})
Create navbar, home, and registration components. The syntax for creating a new angular component is “ng generate component nameofthecomponent”
ng generate component navbarng generate component homeng generate component registration
Copy the below html code and paste into the home.component.html file.
<div class=”container”><div class=”template”><h1>Simple CRUD functionality using Angular 5 with Bootstrap 4</h1></div></div>
Copy the below NavBar bootstrap html code and paste into the navbar.component.html.
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"><a class="navbar-brand" href="#">Logo</a><button class="navbar-toggler" type="button" data-toggle="collapse" (click)="isCollapsed = !isCollapsed" data-target="#navbarsExampleDefault"aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarsExampleDefault" [ngbCollapse]="isCollapsed"><ul class="navbar-nav mr-auto"><li class="nav-item"><a class="nav-link" routerLink="">Home<span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link" routerLink="registration">Registration</a></li></ul><form class="form-inline my-2 my-lg-0"><input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search"><button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button></form></div></nav>
Copy and paste the below code in app.component.html file.
<app-navbar></app-navbar><router-outlet></router-outlet>
Add the below css code in style.css.
body {padding-top: 80px;}.template {padding: 3rem 1.5rem;text-align: center;}
Enable routing
Import both Home and Registration components in app-routing.module.ts.
import { HomeComponent } from './home/home.component';import { RegistrationComponent } from './registration/registration.component';
Replace the “const routes: Routes = []” with below code
const routes: Routes = [{path: '',component: HomeComponent},{path: 'registration',component: RegistrationComponent}];
The path:’’ code sets default path to HomeComponent Hence the Home view template will be displayed when the application loads first.
After the above change, we can see the below output in the browser.
Now everything works fine without NavBar collapse functionality. By default it will not be working.
Add the below code in navbar.component.ts to make it work.
isCollapsed: Boolean = true;
Replace the below code in navbar.component.html
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"><a class="navbar-brand" href="#">Logo</a><button class="navbar-toggler" type="button" data-toggle="collapse" (click)="isCollapsed = !isCollapsed"data-target="#navbarsExampleDefault"aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarsExampleDefault" [ngbCollapse]="isCollapsed"><ul class="navbar-nav mr-auto"><li class="nav-item"><a class="nav-link" routerLink="">Home<span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link" routerLink="registration">Registration</a></li></ul><form class="form-inline my-2 my-lg-0"><input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search"><button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button></form></div></nav>
Here after let’s see how to create a simple Registration form with CRUD operation. We will use both Bootstrap Datepicker and Dropdown components in the registration form.
Import FormsModule in app.module.js
import { FormsModule } from '@angular/forms';
The FormsModule also needs to be added to the imports array as seen below.
@NgModule({declarations: [AppComponent,NavbarComponent,HomeComponent,RegistrationComponent],imports: [BrowserModule,AppRoutingModule,NgbModule.forRoot(),FormsModule],providers: [],bootstrap: [AppComponent]})
We need to do the below changes in registration.component.ts
Import NgbDateStruct for Bootstrap Datepicker functionality.
import {NgbDateStruct} from '@ng-bootstrap/ng-bootstrap';
Create Registration class as per below code.
class Registration {constructor(public firstName: string = '',public lastName: string = '',public dob: NgbDateStruct = null,public email: string = '',public password: string = '',public country: string = 'Select country') {}}
Define the following binding variable inside the RegistrationComponent class.
// It maintains list of Registrationsregistrations: Registration[] = [];// It maintains registration ModelregModel: Registration;// It maintains registration form display status. By default it will be false.showNew: Boolean = false;// It will be either 'Save' or 'Update' based on operation.submitType: string = 'Save';// It maintains table row index based on selection.selectedRow: number;// It maintains Array of countries.countries: string[] = ['US', 'UK', 'India', 'UAE'];
Add below code inside the RegistrationComponent constructor for default registration data.
// Add default registration data.this.registrations.push(new Registration('Johan', 'Peter', {year: 1980, month: 5, day: 12}, 'johan@gmail.com', 'johan123', 'UK'));this.registrations.push(new Registration('Mohamed', 'Tariq', {year: 1975, month: 12, day: 3}, 'tariq@gmail.com', 'tariq123', 'UAE'));this.registrations.push(new Registration('Nirmal', 'Kumar', {year: 1970, month: 7, day: 25}, 'nirmal@gmail.com', 'nirmal123', 'India'));
Add below code for New functionality.
// This method associate to New Button.
// This method associate to New Button.onNew() {// Initiate new registration.this.regModel = new Registration();// Change submitType to 'Save'.this.submitType = 'Save';// display registration entry section.this.showNew = true;}
Add below code for Save/Update functionality.
// This method associate to Save Button.onSave() {if (this.submitType === 'Save') {// Push registration model object into registration list.this.registrations.push(this.regModel);} else {// Update the existing properties values based on model.this.registrations[this.selectedRow].firstName = this.regModel.firstName;this.registrations[this.selectedRow].lastName = this.regModel.lastName;this.registrations[this.selectedRow].dob = this.regModel.dob;this.registrations[this.selectedRow].email = this.regModel.email;this.registrations[this.selectedRow].password = this.regModel.password;this.registrations[this.selectedRow].country = this.regModel.country;}// Hide registration entry section.this.showNew = false;}
Add below code for Edit functionality.
// This method associate to Edit Button.onEdit(index: number) {// Assign selected table row index.this.selectedRow = index;// Initiate new registration.this.regModel = new Registration();// Retrieve selected registration from list and assign to model.this.regModel = Object.assign({}, this.registrations[this.selectedRow]);// Change submitType to Update.this.submitType = 'Update';// Display registration entry section.this.showNew = true;}
Add below code for Delete functionality.
// This method associate to Delete Button.onDelete(index: number) {// Delete the corresponding registration entry from the list.this.registrations.splice(index, 1);}
Add below code for Cancel functionality.
// This method associate to Cancel Button.onCancel() {// Hide registration entry section.this.showNew = false;}
Add below code for dropdown change functionality.
// This method associate to Bootstrap dropdown selection change.onChangeCountry(country: string) {// Assign corresponding selected country to model.this.regModel.country = country;}
Need to do the following changes in registration.component.html
Add the below code
<div class=”container”></div>
Add the below code inside the container div.
<div class="reglist"><table class="table table-striped"><thead><tr><th>#</th><th>First Name</th><th>Last Name</th><th>DOB</th><th>Email</th><th>Country</th><th></th><th></th></tr></thead><tbody><tr *ngFor="let registration of registrations; let i = index"><th scope="row">{{ i + 1 }}</th><td>{{ registration.firstName }}</td><td>{{ registration.lastName }}</td><td>{{ registration.dob.day + '/' + registration.dob.month + '/' + registration.dob.year}}</td><td>{{ registration.email }}</td><td>{{ registration.country }}</td><td><button type="button" class="btn btn-info" (click)="onEdit(i)">Edit</button></td><td><button type="button" class="btn btn-danger" (click)="onDelete(i)">Delete</button></td></tr></tbody></table><div class="text-right"><button type="submit" class="btn btn-primary" (click)="onNew()">New</button></div></div><br>
The above code displays the saved registration in the table. The *ngFor loop through registrations array and displays all the registration property’s value. The onNew, onEdit, and onDelete methods associate to corresponding buttons through click event binding.
Add below code next to reglist div.
<div class="regentry" *ngIf="showNew"><form (ngSubmit)="onSave()"></form></div>
Associate onSave method to form element through ngSubmit event binding.
Add each field one by one inside the form element. Each field associate to corresponding model property through form ngModel two way binding. It’s a must to define name property value for each input control for two way binding.
First Name (Input control)
<div class="form-group row"><label for="firstname-input" class="col-2 col-form-label">First Name</label><div class="col-10"><input class="form-control" type="text" [(ngModel)]="regModel.firstName" name="firstName"></div></div>
Last Name (Input control)
<div class="form-group row"><label for="lastname-input" class="col-2 col-form-label">Last Name</label><div class="col-10"><input class="form-control" type="text" [(ngModel)]="regModel.lastName" name="lastName"></div></div>
DOB (Bootstrap datepicker control)
Need to include ngbDatepicker directive.
<div class="form-group row"><label for="dob-input" class="col-2 col-form-label">DOB</label><div class="col-3 input-group"><input type="text" class="form-control" placeholder="yyyy-mm-dd" name="dob" [(ngModel)]="regModel.dob" ngbDatepicker #dob="ngbDatepicker"><button class="input-group-addon" (click)="dob.toggle()" type="button"><img src="assets/img/calendar-icon.svg" style="width: 1.2rem; height: 1rem; cursor: pointer;" /></button></div></div>
Email (Input control)
<div class="form-group row"><label for="example-email-input" class="col-2 col-form-label">Email</label><div class="col-10"><input class="form-control" type="email" [(ngModel)]="regModel.email" name="email"></div></div>
Password (Input control)
<div class="form-group row"><label for="example-password-input" class="col-2 col-form-label">Password</label><div class="col-10"><input class="form-control" type="password" [(ngModel)]="regModel.password" name="password"></div></div>
Country (Bootstrap dropdown control)
Need to include ngbDropdown, ngbDropdownToggler, and ngbDropdownMenu.
<div class="form-group row"><label for="city-input" class="col-2 col-form-label">Country</label><div class="col-10 dropdown" ngbDropdown myDrop="ngbDropdown"><button type="button" class="btn btn-outline-primary" id="dropdownManual" name="country" ngbDropdownToggle>{{regModel.country}}</button><div ngbDropdownMenu aria-labelledby="dropdownManual"><button type="button" class="dropdown-item" *ngFor="let country of countries" (click)="onChangeCountry(country)">{{country}}</button></div></div></div>
Associate onChangeCountry method through click event binding for changing the selected country.
Finally add the below code for Save and Cancel Button.
<button type="submit" class="btn btn-success">{{submitType}}</button><button type="submit" class="btn btn-primary" (click)="onCancel()">Cancel</button>
Now we can see Registration form as seen below.
You can find all the source code in the below repository.
Live Demo