Ngx-bootstrap: Pass data to modal and open it from parent

Created on 9 Jun 2016  路  5Comments  路  Source: valor-software/ngx-bootstrap

Hi,

I'm using the Modal Component in a Parent-Child Relation. I've a list of items which are shown in a list.

By clicking on a button in the list of the parent component I want to trigger a modal, which will display the current item.

I already achieved it with some smaller issues I also want to fix. Here is my code.

ListComponent (Parent)

@Component({
    selector: 'app-list',
    directives: [DetailComponent]
})

export class ListComponent {
    books: Array<Object>;
    book: Object;
}

List Template

 <div *ngFor="let book of books">
  <div class="row">
    <div class="col-xs-6" (click)="showDetail(book)">
      <img src="assets/books/[email protected]" alt="">
    </div>
    <detail *ngIf="book != null" [book]="book"></detail>
  </div>
</div>

DetailComponent

@Component({
    moduleId: module.id,
    selector: 'detail',
    directives: [MODAL_DIRECTVES, CORE_DIRECTIVES],
    viewProviders: [BS_VIEW_PROVIDERS],
    templateUrl: 'detail.component.html',
    styleUrls: ['detail.component.css']
})

export class DetailComponent {
    @Input() book: Object;
}

Detail Template

<button (click)="bookModal.show()">Detail</button>
<div bsModal #bookModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
    book info goes here
</div>

2 Issues remain:

1) Is it ok to generate the detail container/tag within the ng-for of the parent template? I thought of another solution like calling a showDetail-method on the parent class and passing the current book to the child component?

2) Due to the fact that I've put the detail containter/tag into the ng-for, i am also not able to open the modal from outside. So at the moment there is a button in the detail template which will trigger the show()-method of the modal. But this doesnt really fit to desired layout of the app.

Thx 4 help!

Most helpful comment

@crebuh
I tried this and its working fine for me.
Below is added in parent html :
<custom-modal #modal></custom-modal>
then on click of below is the snipped added in parent html :
<a (click)="modal.showModal(description)" class="more">
then below is the modal component :

import {MODAL_DIRECTVES, BS_VIEW_PROVIDERS} from 'ng2-bootstrap/ng2-bootstrap';
import {Component, ViewChild, ElementRef} from "@angular/core";

@Component({
    selector: 'custom-modal',
    moduleId: module.id,
    templateUrl: './modal.component.html',
    styleUrls: ['./modal.component.css'],
    directives: [MODAL_DIRECTVES],
    viewProviders: [BS_VIEW_PROVIDERS]
})

export class ModalComponent {
    modalBody:string;
    @ViewChild('lgModal') modal:ElementRef;

    showModal(modalBody:string) {
        if (modalBody != undefined) {
            this.modalBody = modalBody;
            this.modal.show();
        }
    }
}

and modal template 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">
                <button type="button" class="close" (click)="lgModal.hide()" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title">Description</h4>
            </div>
            <div class="modal-body">
                {{modalBody}}
            </div>
        </div>
    </div>
</div>

Please let me know your thoughts on it.
Working fine for me.

All 5 comments

@crebuh
I tried this and its working fine for me.
Below is added in parent html :
<custom-modal #modal></custom-modal>
then on click of below is the snipped added in parent html :
<a (click)="modal.showModal(description)" class="more">
then below is the modal component :

import {MODAL_DIRECTVES, BS_VIEW_PROVIDERS} from 'ng2-bootstrap/ng2-bootstrap';
import {Component, ViewChild, ElementRef} from "@angular/core";

@Component({
    selector: 'custom-modal',
    moduleId: module.id,
    templateUrl: './modal.component.html',
    styleUrls: ['./modal.component.css'],
    directives: [MODAL_DIRECTVES],
    viewProviders: [BS_VIEW_PROVIDERS]
})

export class ModalComponent {
    modalBody:string;
    @ViewChild('lgModal') modal:ElementRef;

    showModal(modalBody:string) {
        if (modalBody != undefined) {
            this.modalBody = modalBody;
            this.modal.show();
        }
    }
}

and modal template 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">
                <button type="button" class="close" (click)="lgModal.hide()" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title">Description</h4>
            </div>
            <div class="modal-body">
                {{modalBody}}
            </div>
        </div>
    </div>
</div>

Please let me know your thoughts on it.
Working fine for me.

@harishrohokale Thank you this is great.

Hi,

I have been trying to get this work out, but i receive the message that the
import {MODAL_DIRECTVES, BS_VIEW_PROVIDERS} from 'ng2-bootstrap/ng2-bootstrap'; does not exist.

I am using 1.6.6 version, maybe this is different now?

Thanks in advance

you should use ngx-bootstrap
so import {MODAL_DIRECTVES} from 'ngx-bootstrap'

Use InitialState to pass data:
https://ngx-universal.herokuapp.com/modals

In your showDetails method put
const initialState = {
//data you want to pass
data1 : foo
}

Then call show() to display modal and pass initial state as object
Something like
this.service.openComponentModal(modalComponentName, {initialState})

Then in your modal component, put the fields you passed

public data1;

And the data will be there

Was this page helpful?
0 / 5 - 0 ratings