How to implement Modal Dialog in Angular 2 and above

33,590

Solution 1

Your common child modal component will be as below

import {Component,Input, ViewChild} from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap';

@Component({
  selector: 'common-modal',
  template: `
   <div bsModal #childModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-sm">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title pull-left">{{title}}</h4>
        <button type="button" class="close pull-right" aria-label="Close" (click)="hideChildModal()">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <ng-content select=".modal-body"> </ng-content>
      </div>

      <div class="modal-footer">
        <div class="pull-left">
          <button class="btn btn-default" (click)="hide()"> Cancel </button>
        </div>
      </div>
    </div>
  </div>
</div>
  `,
})
export class CommonModalComponent {
   @ViewChild('childModal') public childModal:ModalDirective;
   @Input() title:string;
  constructor() {
  }
  show(){
    this.childModal.show();
  }
  hide(){
    this.childModal.hide();
  }
}

Using the child component in your parent component will look as below

import {Component, ViewChild, NgModule,ViewContainerRef} from '@angular/core'
import { BrowserModule } from '@angular/platform-browser';
import { ModalDirective,ModalModule } from 'ngx-bootstrap';
import {CommonModalComponent} from './child.modal';
@Component({
  selector: 'my-app',
  template: `
    <button type="button" class="btn btn-primary" (click)="childModal.show()">Open modal</button>
    <common-modal  #childModal [title]="'common modal'"> 
    <div class="modal-body">
    Hi heloo </div>
    </common-modal> 

  `,
})
export class AppComponent {
  @ViewChild('childModal') childModal :CommonModalComponent;
  constructor(private viewContainerRef: ViewContainerRef) {
  }

}

Using the above code you can have a separate common modal dialog which can be reused, so that your header & footer remains the same and you can use Content-Projection to use change the body of the modal dialog.

LIVE DEMO

Solution 2

The below answer is in reference to the latest ng-bootstrap

Component Controller

import { TemplateRef, ViewChild } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'app-app-registration',
  templateUrl: './app-registration.component.html',
  styleUrls: ['./app-registration.component.css']
})

export class AppRegistrationComponent implements OnInit {

  @ViewChild('editModal') editModal : TemplateRef<any>; // Note: TemplateRef

  constructor(private modalService: NgbModal) { }

  openModal(){
    this.modalService.open(this.editModal);
  }

}

Component HTML

<ng-template #editModal let-modal>

<div class="modal-header">
  <h4 class="modal-title" id="modal-basic-title">Edit Form</h4>
  <button type="button" class="close" aria-label="Close" (click)="modal.dismiss()">
    <span aria-hidden="true">&times;</span>
  </button>
</div>

<div class="modal-body">
  <!-- YOUR FORM DATA -->
</div>

<div class="modal-footer">
  <button type="button" class="btn btn-outline-dark" (click)="modal.close()">Save</button>
</div>

</ng-template>

app.module.ts

import {NgbModule} from '@ng-bootstrap/ng-bootstrap';

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...

    NgbModule

  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Share:
33,590
Bala Karthik
Author by

Bala Karthik

Ruby on Rails Developer

Updated on July 05, 2022

Comments

  • Bala Karthik
    Bala Karthik almost 2 years

    I am a newbie to angular.

    I have used bootstrap modal using the package ng2-bootstrap.

    My View file is

    <div bsModal #lgModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
      <div class="modal-dialog modal-lg">
        <div class="modal-content">
          <div class="modal-header">
            <h4 class="modal-title pull-left">Area Master</h4>
            <button type="button" class="close pull-right" (click)="lgModal.hide();" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            Modal Content here...
    
          </div>
          <div class="modal-footer">
            <button type="submit" class="btn btn-primary">Add</button>
          </div>
        </div>
      </div>
    </div>
    

    I need to know how to show/hide this modal from the component (type script file).

    Type script file is

    import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
    import { Router } from '@angular/router';
    import { FormGroup, Validators, FormBuilder, FormControl } from '@angular/forms';
    import { Area } from './area';
    import { AreaService } from './area.service';
    @Component({
    
      moduleId: module.id,
      selector: 'my-areas',
      templateUrl: './areas.component.html',
      styleUrls: ['./areas.component.css']
    })
    
    export class AreasComponent implements OnInit {
      area_form: FormGroup;
      new_area: Area;
      areas: Area[];
      @ViewChild('lgModal') lgModal:ElementRef;
      constructor(
        private areaService: AreaService,
        private router: Router,
        private form_builder: FormBuilder) { }
    
      getAreas(): void {
        this.areaService
          .getAreas()
          .then(areas => this.areas = areas);
      }
    
      submit(area: Area): void {
        console.log(area);
        this.areaService.create(area)
          .then(area => { this.areas.push(area) })
      }
    
      ngOnInit(): void {
        this.getAreas();
        this.lgModal.show();
        this.area_form = this.form_builder.group({
          name: ['', Validators.required],
          pincode: ['', Validators.required],
          status: ['Active'],
          type: ['Busines Service Area']
        })
      }
    }
    
  • Richard Matsen
    Richard Matsen almost 7 years
    Playing with the plunker, it works if AppComponent @ViewChild is commented out, but not if the viewContainerRef is removed. What is viewContainerRef doing? there's no obvious usage of it in the code. This is the first time I've seen it mentioned in connection to ModalDirective.
  • Aravind
    Aravind almost 7 years
    @RichardMatsen do you need some help from me?
  • Richard Matsen
    Richard Matsen almost 7 years
    Cheers, looking at the plunker, could you say what ViewContainerRef injected into the AppComponent does? I'm using ng2-bootstrap v1.3.3 with import syntax ModalModule.forRoot(), which provides ComponentLoaderFactory & PositioningService, but I can't figure out why you inject ViewContainerRef and if I need it with my version.
  • Heena
    Heena about 6 years
    @Aravind.... can you please help me out with this query..stackoverflow.com/questions/49535102/…