Search code examples
twitter-bootstrapangularngx-bootstrap

ngx-bootstrap How to open a modal from another component?


What I'm trying to do is open a modal from another component, however I keep getting this error TypeError: Cannot create property 'validator' on string 'test1' when component1.html loads because childModal is included. How can I get rid of these errors and implement this properly?

component1.html

<button type="button" class="btn btn-outline-primary btn-lg" (click)="modal.showModal()">Test
......
<child-modal #childModal ></child-modal>

component1.ts

 @ViewChild('childModal') childModal: ModalComponent;

modal.html

<div bsModal #childModal="bs-modal" class="modal fade" tabindex="-1" role="dialog>
    <div class="modal-dialog modal-lg">
      <div class="modal-content">
          <input type="text" formControl="test1">
          <input type="text" formControl="test2">
          </div>
     </div>
</div>   

modal.component.ts

constructor(private modalService: BsModalService) {
    this.form = new FormGroup({
      'test':                     new FormControl(),
      'test2':                    new FormControl()
      }) 
 }

Solution

  • If you're trying to open a Modal Component from another Component, then this is the right way to do it with ngx-bootstrap:

    import { Component } from '@angular/core';
    import { BsModalService } from 'ngx-bootstrap/modal';
    import { BsModalRef } from 'ngx-bootstrap/modal/modal-options.class';
    
    /* This is the Component from which we open the Modal Component */
    @Component({
      selector: 'my-component',
      templateUrl: './service-component.html'
    })
    export class MyComponent {
      bsModalRef: BsModalRef;
      constructor(private modalService: BsModalService) {}
    
      public openModalWithComponent() {
        /* this is how we open a Modal Component from another component */
        this.bsModalRef = this.modalService.show(ModalContentComponent);
      }
    }
    
    /* This is the Modal Component */
    @Component({
      selector: 'child-modal',
      template: `
        <div class="modal-header">
          <h4 class="modal-title pull-left">Title</h4>
          <button type="button" class="close pull-right" aria-label="Close" (click)="bsModalRef.hide()">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div class="modal-body">
          ...
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" (click)="bsModalRef.hide()">Close</button>
        </div>
      `
    })
    export class ChildModalComponent {
      constructor(public bsModalRef: BsModalRef) {}
    }
    

    template of the Component which is calling the Modal:

    <button type="button" class="btn btn-primary" (click)="openModalWithComponent()">Create modal with component</button>
    

    So you should NOT include the Modal Component in the template like this:

     <child-modal #childModal ></child-modal>
    

    Official doc:

    https://valor-software.com/ngx-bootstrap/#/modals#service-component