Skip to content

nowzoo/nz-bs-modal

Repository files navigation

NzBsModal

Bootstrap modal library for Angular 6. Built on top of the Bootstrap js, with full support for modal styling, animations, options and events.

Demo Site

NB: By design this library depends on jQuery, popper.js, bootstrap.js and bootstrap.css. You need to include those scripts and styles in your build. If you are looking for a native Angular implementation, look at ngx-bootstrap or ng-bootstrap.

Get Started

Install the Library & Dependencies

npm i --save nzbs-modal jQuery popper.js bootstrap

Include the JS and CSS Dependencies in Your Build

Add the following entries in the styles and scripts sections of your project in angular.json. Real-life example.

"styles": [
  "node_modules/bootstrap/scss/bootstrap.scss",
  "src/styles.scss"
],
"scripts": [
  "node_modules/jquery/dist/jquery.slim.min.js",
  "node_modules/popper.js/dist/umd/popper.min.js",
  "node_modules/bootstrap/dist/js/bootstrap.min.js"
]

Alternately, you can include the Bootstrap styles in your app stylesheet...

// src/styles.scss...
@import "~bootstrap/scss/bootstrap";
// more styles...

Usage

The library comes with:

  • The NzBsModalService code which your components will use to show modals. The service's show() method returns an instance of INzBsModalInstance, which has properties and methods to manipulate the modal once it is shown.
  • The NzBsModalComponent. You only need one of these in your app, and it should be placed as high up in the DOM as possible, for example, at the end of your AppComponent template. You can pass in some default options if you don't like the built in ones. After that, you really don't have to worry about it.

Import the ModalModule in your app module

We only want to have one instance of the Modal Service, so call NzBsModalComponent.forRoot().

// src/app/app.module.ts
import { NzBsModalModule } from 'nzbs-modal';

@NgModule({
  imports: [
    // other imports
    NzBsModalModule.forRoot()
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Full example.

Add the ModalComponent to your app component

Insert the component selector <nz-bs-modal></nz-bs-modal> at the bottom of app.component.html.

<!-- app.component.html -->
<div style="padding-top:56px">
  <router-outlet></router-outlet>
</div>
<nz-bs-modal></nz-bs-modal>

Full example.

Minimal Example: Use the service to display modals from other components

Demo Source

First, add an <ng-template> to your component's template. Make sure to reference it with a template reference variable, e.g. #modal. It should probably contain at least a .modal-body div.

<!-- minimal.component.html -->
<div class="d-flex align-items-center mb-2">
  <div>
    <button type="button" class="btn btn-primary btn-lg" (click)="showModal()">
      Show Modal
    </button>
  </div>
</div>
<ng-template #modal>
  <div class="modal-content">
    <div class="modal-header">
      <h5 class="modal-title" [attr.id]="modalLabelledById">What's Up?</h5>
      <button type="button" class="close" data-dismiss="modal" aria-label="Close">
        <span aria-hidden="true">&times;</span>
      </button>
    </div>
    <div class="modal-body">
      <p>Hey! Here's some modal content.</p>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-primary"
        data-dismiss="modal">Close Modal</button>
    </div>
  </div>
</ng-template>

Instantiate your component class with the NzBsModalService and a reference to the modal template and provide some method to show the modal...

// minimal.component.ts
import { Component, TemplateRef, ViewChild } from '@angular/core';
import { NzBsModalService } from 'nzbs-modal';
@Component({
  selector: 'app-minimal',
  templateUrl: './minimal.component.html',
  styleUrls: ['./minimal.component.scss']
})
export class MinimalComponent {

  @ViewChild('modal') modal: TemplateRef<any>;
  constructor(
    private modalService: NzBsModalService
  ) { }

  showModal() {
    this.modalService.show(this.modal);
  }
}

Note: In the minimal example above, we used the native Bootstrap data-dismiss="modal" attribute to close the modal. Modals can also be closed programmatically, for example, after a successful form submission. ModalService.show() returns an instance of IModalInstance, which comes with a hide() method.

API

INzBsModalInstance

This is what the modal service returns from the show() method. This interface exposes several methods and properties to manipulate the modal after it is shown.

  • events: EventEmitter<Event> exposes the native Bootstrap modal events. Demo | Demo code
  • handleUpdate(): void exposes the native Bootstrap method. You should call this whenever the height of your modal content changes. Demo | Demo code
  • shown(): Promise<void> returns a promise that resolves when the modal is completely shown.
  • hidden(): Promise<void> returns a promise that resolves when the modal is completely hidden.
  • hide(): void hides the modal programmatically. Demo for shown(), hidden() and hide() | Demo code

INzBsModalOptions

The set of options that you can pass into the service's show() method. You can also pass your own defaults into the NzBsModalComponent instance if you don't like the following defaults.

Note: All of the Bootstrap modal options and classes except show are supported. In addition, we add the Angular-specific dismissOnRouteChange option.

Note: All of the following keys are optional.

  • animate?: boolean Default: true. Whether or not to animate the modal in and out. Demo | Demo code

  • size?: 'sm' | 'lg' | null Default: null. The size of the modal. Demo | Demo code

  • centered?: boolean Default: false. Whether to center the modal vertically in the viewport. Demo | Demo code

  • backdrop?: boolean | 'static' Default: true. Whether to display a backdrop, and if so whether clicking on it dismisses the modal. Demo | Demo code

    • true — backdrop dismisses the modal
    • static — backdrop doesn't dismiss
    • false — no backdrop
  • keyboard?: boolean Default: true. Whether or not pressing the esc key dismisses the modal. Demo | Demo code

  • focus?: boolean Default: true. Whether or not to focus the modal when shown. Note that you can also use the modalInstance.shown() promise to automatically focus inputs within the modal. Demo | Demo code

  • dismissOnRouteChange?: boolean Default: true. whether or not to dismiss the modal when the route changes. Demo | Demo code

NzBsModalComponent

This is the "singleton" component that you should place near the top of the DOM. It only has one input:

  • @Input() defaultOptions: INzBsModalOptions Use this if to globally override the default options shown above.

NzBsModalService

The service for showing modals.

  • show(templateRef: TemplateRef<any>, options?: INzBsModalOptions): INzBsModalInstance Show a modal given a template and (optionally) a modal options object.
  • getLabelledById(): string This is meant to allow you to set the id of the <h5 class="modal-title">Title</h5>, so as to match the modal element's aria-labelledby attribute. See Bootstrap modal accessibility.

Development

PRs, suggestions and issues are welcome.

This project was generated with Angular CLI version 6.0.3.

NB Library support in the CLI is (IMHO) still a work in progress and less than intuitive. Any ideas on how to restructure the project are more than welcome.

  • The library code is found in projects/nz-bs-modal/src.
  • The demo code (i.e., the app) is found in app/src.
  • In order to develop both the library and and the demo code simultaneously, change all the library imports in the demo code from nzbs-modal (which should pick up the node module) to @nzbs-modal (which is defined as a path in tsconfig.json.)

Unit tests

  • Run ng test nz-bs-modal to execute the unit tests for the library
  • Run ng test to execute the unit tests for the demos.

Development server

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.

License

MIT