Search code examples
angularangular-componentsangular-bootstrapangular-library

Angular 2+ add ng-bootstrap Modal to component library


I'm working with ng-bootstrap and I would like to add a reuseable modal to the component library I've built.

I have my template

<p>
<ng-template #messageModal let-closeModal="close('Cross click')">
    <div id="resultModal">
        <div class="modal-header">
            <h4 class="mt-3">{{header}}
            </h4>
            <button id="messageModalClose" type="button" class="close" aria-label="Close" (click)="closeModal">
                <span aria-hidden="true">&times;</span>
            </button>
        </div>
        <div class="modal-body">
           {{message}}
        </div>
    </div>

</ng-template>

</p>

and Component

import { Component, OnInit, ViewEncapsulation, Input } from '@angular/core';
import { NgbModal, NgbModalOptions } from '@ng-bootstrap/ng-bootstrap';

 @Component({
  selector: 'ms-modal',
  templateUrl: './ms-modal.component.html',
  styleUrls: ['./ms-modal.component.scss'],
  encapsulation: ViewEncapsulation.None,
})
export class MsModalComponent implements OnInit {
  @Input() header: string;
  @Input() message:string;

  private _modalOptions: NgbModalOptions = {
    backdrop: 'static',
    keyboard: false,
    size: 'lg',
    centered: true
  };


  constructor(private modalService: NgbModal) { }

  ngOnInit() {
  }
  OpenModal(_messageModal) {
    this.modalService.open(_messageModal, this._modalOptions);
  }

}

I've added @Inputs for the header and message My component library builds fine

In my application that I import my component library into I've added the modal tag

<ms-modal *ngIf="showModal==true" [header]="header" [message]="message"> 
</ms-modal>

When I set showModal=true nothing happens.

showModal:any = false;

this.showModal = "true";

I guess I'm not sure how to get this wired up correctly to use my modal from my component library in my various applications.


Solution

  • Okay, I have got this working and I had several things wrong.

    Please remember that I am working in a Component Library not just the application.

    Inside my Component Library...

    I have my template

     <div class="modal-header">
         <h4 class="mt-3">
            {{header}}
         </h4>
         <button id="messageModalClose" type="button" class="close" aria-label="Close" 
             (click)="closeModal()">
             <span aria-hidden="true">&times;</span>
         </button>
      </div>
      <div class="modal-body">
          {{message}}
      </div>
    

    and Component

    import { Component, OnInit, ViewEncapsulation, Input } from '@angular/core';
    import { NgbModal, NgbModalOptions, NgbActiveModal } from '@ng-bootstrap/ng- 
    bootstrap';
    
    @Component({
      selector: 'ms-modal',
      templateUrl: './ms-modal.component.html',
      styleUrls: ['./ms-modal.component.scss'],
      //encapsulation: ViewEncapsulation.None,
    })
    export class MsModalComponent implements OnInit {
      @Input() header: string;
      @Input() message:string;
    
      private _modalOptions: NgbModalOptions = {
        backdrop: 'static',
        keyboard: false,
        size: 'lg',
        centered: true
      };
    
    
      constructor(public activeModal: NgbActiveModal) { }
    
      ngOnInit() {
    
      }
      closeModal() {
        this.activeModal.close();
      }
    }
    

    I import my component into my app module import {msModalModule } from 'ms-components';

    I add 'msModalModule' to the @NgModule imports array and also add the component referenced by the module to entryComponents

    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
         BrowserModule,
         AppRoutingModule,
         BrowserAnimationsModule,
         HttpClientModule,
         FormsModule,
         msModalModule    
      ],
    bootstrap: [AppComponent],
    entryComponents:[MsModalComponent]
    

    }) export class AppModule {}

    Now in my app.component.ts I add a function to handle opening the Modal and pass in the input values

    OpenModal(header,message){
    
    ***NgbModalOptions is optional
    const modalOptions: NgbModalOptions = {
      backdrop: 'static',
      keyboard: false,
      size: 'lg',
      centered: true,
    };
    
    
     const modalRef = this.modalService.open(MsModalComponent,modalOptions)
     modalRef.componentInstance.header = header;
     modalRef.componentInstance.message = message;
    

    }