Angular – Pass data into ngbmodal instance in angular 2/4 from the parent component

angularng-bootstrap

I am not aware if this is even possible in Angular 2/4. I have a Modal Component which in turn has a Modal Content Component. I also have a service which allows to open/close the modal instance. I am using ngbModal.

The modal Content template needs to show/hide some fields based on the boolean parameter.

My Page component has a button which on click needs to open the modalInstance with the boolean parameter.

Here is what i have,

page.component.html

 <div class="bar-sec">
   <action-bar [options]="btnOpts" (select) = 
      "actionBarSelectHandler($event)">
   </action-bar>
</div>
<div class="grid-sec">
</div>
 **<app-ad-search [userOnly]='userOnly'></app-ad-search>**

page.component.ts

 import {Component, ViewChild} from '@angular/core';
 import { NgbDropdownConfig } from '@ng-bootstrap/ng-bootstrap';
 import { SearchModalComponent} from '../../X/search-modal.component';
 import { SearchContentComponent} from '../../X/search-content.component';
 import { XModalService} from '../../X/x-modal.service';

@Component ({
  selector: 'page-test',
  templateUrl: './page.component.html',
  providers: [XModalService]
})

 export class VCenterMachinesComponent {
   XModalService: XModalService;
   filterText: String = '';
   machines: any[];
   btnOpts: {};
   **userOnly:boolean = true;**

  **@ViewChild(SearchModalComponent) private 
       SearchModalComponent:SearchModalComponent;**

 constructor(E:XModalService) {
  this.XModalService = E;
  **this.userOnly = true;**
 }

 actionBarSelectHandler(data) {
    if (data.item.id === 'assignuser') {
        **this.XModalService.openSearchModal()**.then(() => {
            console.log('close');
        }, () => {
            console.log('dismiss');
        });
     }
  }

 ngOnInit() {
    this.machines = [];
   this.filterText = '';
   this.btnOpts = {
     data: [{
                id: "assignuser",
                label: "Assign User...",
                enabled: true
            }]
   };

  }
 }

search-modal.component.ts

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

    import { SearchContentComponent } from './search-content.component';

        @Component({
            selector: 'app-ad-search',
            template: `
                <modal-header (onClose)="activeModal.dismiss();">
                    <span>{{modalTitle}}</span>
                </atk-modal-header>
                <modal-body>
                    <search-content>
                    </search-content>
                </modal-body>
                <modal-footer [buttons] = "modalBtns" 
      (onClick)="btnClick($event)">
                </modal-footer>
            `
        })
        export class SearchModalComponent{
            @Input()
            private modalBtns: any[] | any = [{
                id: 'ok',
                label: 'OK',
                primary: true,
                disabled: true
            }, {
                id: 'cancel',
                label: 'Cancel',
                primary: true,
                disabled: false
            }];
            @Input()
            **public userOnly:boolean = false;**

            @Input()
            public modalTitle: string = (this.userOnly) ? 'XXX':'YYY';


            constructor(private activeModal: NgbActiveModal) { }

            btnClick(btn) {
                if (btn.id === 'ok') {
                    this.activeModal.close(this.selectedRows);
                } else {
                    this.activeModal.dismiss();
                }
            }


        }

search-content.component.ts

  import { Component, OnInit, OnDestroy, Input, Output, EventEmitter } from 
    '@angular/core';
            @Component({
              selector: 'ad-search-content',
              template: '<div class="form-group row" *ngIf="!userOnly">
                    <label class="col-sm-4 col-form-label">Type:</label>
                    <div class="col-sm-8">
                        <label class="custom-control custom-checkbox">
                            <input type="checkbox" class="custom-control-
       input" [(ngModel)]="filters.type.users" name="usersType">
                        </label>
                    </div>
                </div>
                <div class="form-group row">
                    <label class="col-sm-4 col-form-label">Domian:</label>      
                </div>'
            })
            export class SearchContentComponent implements OnInit, OnDestroy 
        {

                constructor() { }

                ngOnInit() {}
                ngOnDestroy() {}

            }

x-modal.service.ts

        import { Injectable } from '@angular/core';
        import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

        import { SearchModalComponent } from './search-modal.component';


        @Injectable()
        export class XModalService {
            constructor(private modalService: NgbModal) {}

            **openSearchModal() {**
                return this.modalService.open(SearchModalComponent, 
          {backdrop: 'static'}).result;
            }
        }

Here I tried using the opensearchModal() method from the Xmodalservice to open the modal instance with the boolean value set to true in the typescript file. But i dont even see the page . It complains No provider for NgBActiveModal!

Please let me know as to how could i pass teh boolean to the modal instance that i open?

Best Answer

Check out this example on the official ng Bootstrap docs:

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

@Component({
  selector: 'ngbd-modal-content',
  template: `
    <div class="modal-header">
      <h4 class="modal-title">Hi there!</h4>
      <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
        <span aria-hidden="true">&times;</span>
      </button>
    </div>
    <div class="modal-body">
      <p>Hello, {{name}}!</p>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
    </div>
  `
})
export class NgbdModalContent {
  @Input() name;

  constructor(public activeModal: NgbActiveModal) {}
}

@Component({
  selector: 'ngbd-modal-component',
  templateUrl: './modal-component.html'
})
export class NgbdModalComponent {
  constructor(private modalService: NgbModal) {}

  open() {
    const modalRef = this.modalService.open(NgbdModalContent);
    modalRef.componentInstance.name = 'World';
  }
}

Look at the final two statements of the code: you can save the modalRef returned by ModalService.open() and then access @Input()s using modalRef.componentInstance.

Related Topic