The goal of this proof is to implement the Bootstrap modal component. Current project requires a modal to display some application information.
View and edit in Stackblitz
![StackBlitz icon](https://raw.githubusercontent.com/mkultra329/buildmotion-modal/master/blitz-logo.png)
Or, you can create the application using the Angular CLI.
ng new modal-proof
Update the index.html
file to reference the Bootstrap Css - using the CDN.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
The web application will require the @ng-bootstrap-bootstrap
package and any dependencies.
npm install --save @ng-bootstrap/ng-bootstrap@1.0.2
Create a new component ModalComponent
as a generic modal component. We will only need to provide the component a title
and reference a specific component
as content for the body
of the modal dialog.
ng generate component modal
Next, update the component with the following.
- update the import to include
@Input
- add the
@Input() title
with a default title value.
- add the
- inject the
public activeModal: NgbActiveModal
in the constructor.- allows the modal to hide
import { Component, Input, OnInit } from '@angular/core';
import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.css']
})
export class ModalComponent implements OnInit {
@Input() title = `Information`;
constructor(
public activeModal: NgbActiveModal
) {}
ngOnInit() {
}
}
The modal template uses Bootstrap classes for styling. The main sections of the modal are:
- modal-header
- modal-title
- modal-body
- modal-footer
The modal-body
section includes an ng-content
directive to allow for components to be rendered in the body.
<div role="document" class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">{{title}}</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ng-content></ng-content>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
</div>
</div>
Now that we have a generic template for the modal. In our sample, we will have an About
component display in the modal
. This will demonstrate that we can use any component in our application as content for the modal-body
.
Create a new About
component. This component will represent any
of our application components that we would like to render as modals.
ng g component about
The template is updated to include some additional content with formatting - you get the idea. In my production application, the about component will retrieve application information using a RESTful API call and display more useful information.
<h1>Does it really?</h1>
<p>
about works!
</p>
Next, let's create a new component called AboutModalComponent
.
ng g component modalAbout
Now the fun part. Update the template for the AppModalComponent
. We are wrapping the AboutComponent
in the ModalComponent
.
- add a
title
attribute (matches the @Input of the ModalComponent) so that you can supply a title for the modal.
<app-modal title="About the App">
<app-about></app-about>
</app-modal>
Now that we have all of the working parts of a modal and content to view. We need to trigger the modal to popup. We will add a simple button to invoke a (click)
event. When the button is clicked the open()
method will handle the click event.
<button class="btn btn-lg btn-outline-primary" (click)="open()">Launch demo modal</button>
We'll need to update the consumer of the modal. Notice that there is no other modal component references or HTML in the template of the AppComponent
. We only have the button. We will dynamically load a component using the NgbModal
injected as modalService
in the component constructor.
import { Component } from '@angular/core';
import {NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { ModalComponent } from './modal/modal.component';
import { ModalAboutComponent } from './modal-about/modal-about.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
constructor(private modalService: NgbModal) {}
open() {
// const modalRef = this.modalService.open(ModalComponent);
const modalRef = this.modalService.open(ModalAboutComponent);
modalRef.componentInstance.title = 'About';
}
}
The modal service will open
the specified component ModalAboutComponent
. In order to enable the ModalAboutComponent
to be used in this manner, you
will need to update the AppModule
configuration
entryComponents: [
ModalAboutComponent
]
Before we can run the application, you will need to make sure the components
are imported and declared.
- import
import { NgbModule, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
- add
NgbModule.forRoot()
to theimports
array. - provide:
NgbActiveModal
in theproviders
array.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { ModalComponent } from './modal/modal.component';
import { NgbModule, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { AboutComponent } from './about/about.component';
import { ModalAboutComponent } from './modal-about/modal-about.component';
@NgModule({
declarations: [
AppComponent,
ModalComponent,
AboutComponent,
ModalAboutComponent
],
imports: [
BrowserModule,
NgbModule.forRoot()
],
providers: [
NgbActiveModal
],
bootstrap: [AppComponent],
entryComponents: [
ModalAboutComponent
]
})
export class AppModule { }
This project was generated with Angular CLI version 1.6.8.
Run ng serve
for a dev server. Navigate to http://localhost:4200/
. The app will automatically reload if you change any of the source files.
Run ng generate component component-name
to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module
.
Run ng build
to build the project. The build artifacts will be stored in the dist/
directory. Use the -prod
flag for a production build.
Run ng test
to execute the unit tests via Karma.
Run ng e2e
to execute the end-to-end tests via Protractor.
To get more help on the Angular CLI use ng help
or go check out the Angular CLI README.