12

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']
    })
  }
}
Aravind
  • 40,391
  • 16
  • 91
  • 110
Bala Karthik
  • 1,353
  • 2
  • 17
  • 26

3 Answers3

36

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

Aravind
  • 40,391
  • 16
  • 91
  • 110
  • 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. – Richard Matsen May 27 '17 at 03:05
  • @RichardMatsen do you need some help from me? – Aravind May 27 '17 at 05:58
  • 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. – Richard Matsen May 27 '17 at 07:26
  • @Aravind.... can you please help me out with this query..https://stackoverflow.com/questions/49535102/deleting-selected-items-from-mat-list-not-working-in-angular-2-using-angular-mat/49541113#49541113 – Heena Mar 29 '18 at 07:20
1

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 { }
Arjun Sunil Kumar
  • 1,781
  • 3
  • 28
  • 46
0

Now (v1.8.1+) you can do it easier by using modal service you can use templates and components for creating modals http://valor-software.com/ngx-bootstrap/#/modals#service-section

valorkin
  • 1,329
  • 9
  • 20