1

Is it possible to have a ngBootstrap modal as a shared component and use an instance of it in other components.

I'd like to have one Modal that prompts the user to delete a record and I'd like to re-use it across multiple components with different record types.

ngBootstrap site shows a "Components As Content" example but in that example it looks like the ModalComponent dictates whether to open or close the ModalContents. I'd like the ability to open/close an instance of a modal from another (arbitrary) component.

Is this possible?

2 Answers 2

2
  1. Create a CommonModule as below,

    import { NgModule} from '@angular/core';
    import { CommonModalComponent } from './modal.component';
    import { ModalDirective,ModalModule } from 'ng2-bootstrap/ng2-bootstrap';
    @NgModule({
      imports:[ModalModule],
      declarations: [ CommonModalComponent ],
      exports:[CommonModalComponent]
    })
    export class CommonModule {}
    
  2. As you can see, CommonModalComponent is a declaration in CommonModule, Create that component as below,

    import {Component,Input, ViewChild} from '@angular/core';
    import { ModalDirective } from 'ng2-bootstrap/ng2-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();
      }
    }
    
  3. Using the CommonModule and its components in the AppModule as below,

    import {Component, ViewChild, ViewContainerRef, NgModule} from '@angular/core';
    import {BrowserModule} from '@angular/platform-browser';
    import {CommonModule} from './common.module';
    import {CommonModalComponent} './modal.component';
    @Component({
      selector: 'my-app',
      template: `
        <div>
          <h2>Hello {{name}}</h2>
          <button type="button" class="btn btn-primary" (click)="childModal.show()">Open modal</button>
        <common-modal  #childModal [title]="'common modal'"> 
        </common-modal>
        </div>
      `,
    })
    export class App {
      @ViewChild('childComponent') childComponent:CommonModalComponent;
      name:string;
      constructor(private viewContainerRef: ViewContainerRef) {
        this.name = 'Angular 2 Common Module with ModalComponent'
      }
    }
    
    @NgModule({
      imports: [ BrowserModule,CommonModule ],
      declarations: [ App ],
      bootstrap: [ App ]
    })
    export class AppModule {}
    

LIVE DEMO

Additional Information:

  1. This common module can be used any where to reproduce your needs with the help of ContentProjection in Angular 2 which can be seen in below line

    <ng-content select=".modal-body"> </ng-content>
    
  2. In your AppComponent, you can use this and add items to your CommonModal as,

    <div class="modal-body"> 
            Some Form Controls or Displaying content
    </div>
    

    This can be seen in this LIVE DEMO

  3. Since, you want modal for warning messages or confirmation you can reuse the common-modal and create another WarningModalComponent and use that across application

Sign up to request clarification or add additional context in comments.

4 Comments

I don't think that's the same ng-bootstrap he was asking about.
Read the post carefully, by this re-use it across multiple components yo u can reuse anywhere creating any number of modal components for any number of features.
He was asking about ng-boostrap from angular-ui and from what I see, you're actually using ng2-bootstrap from valor software.
@Aravind thats exactly what i was looking for but Adnan is right in that I use the ng-bootstrap library and what you wrote above doesn't apply even though it's exactly what I need
0

Well, per their documentation when you instantiate the modal, you get the NgbModalRef instance. This instance has a property of the componentInstance that is, obviously, the instance of the component your using for your modal content.

For that to work, the component instance has to be injected with ActiveModal instance in its constructor which can give you access to its methods that you can later use.

open() {
  const modalRef = this.modalService.open(NgbdModalContent);

  // you should have access to the activeModal methods like dismiss
  modalRef.componentInstance.activeModal.dismiss("some reason");
}

You can use this to create a shared service that will keep the reference to the modal and manipulate it from any component.

1 Comment

I've seen that demo on their site but it doesn't quite make sense when sharing one template across two or more components...unless you got a working example

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.