naoru
naoru

Reputation: 2227

PrimeNG angular 2 modal not working when called from another component

I have a table with many rows defined in a component I want to achieve that when pressing a row on the table a modal (dialog) will appear. So i've created a separate component for the dialog yet its not working

the table component code is here (relevant parts)

import { SwatModalComponent } from '../swat-modal/swat-modal.component';

modal: SwatModalComponent;

  constructor(private alertService : AlertService) {
    if(alertService.filteredParam){
      //we have a filtered processAlertSwitchName
      this[alertService.filteredParam.name] = alertService.filteredParam.value;
      alertService.filteredParam = null;
    }
    this.registerEvents();
    this.modal = new SwatModalComponent();
  }

showModal() {
    this.modal.showDialog();
  } 

The dialog code is basically copy paste from the doc's

import { Component, OnInit } from '@angular/core';

import {DialogModule} from 'primeng/primeng';

@Component({
  selector: 'app-swat-modal',
  templateUrl: './swat-modal.component.html',
  styleUrls: ['./swat-modal.component.sass']
})
export class SwatModalComponent implements OnInit {

  display: boolean = false;

    showDialog() {
        this.display = true;
    }

  constructor() { }

  ngOnInit() {
  }

}

and the html code is here

<p-dialog header="Alert Dialog" [(visible)]="display" modal="modal" width="300" responsive="true">
    <header>
        Header content here
    </header>
    Content
    <footer>
        Footer content here
    </footer>
</p-dialog>

on debugging i see that the SwatModalComponent attribute of display is being set to true, yet no modal appears on the screen.

Upvotes: 2

Views: 8699

Answers (2)

Falk Atmanspacher
Falk Atmanspacher

Reputation: 21

I had the same issue, the following two-way binding works for me. No need for shared service.

  1. Catch the the onAfterClose event from primeng base dialog.
  2. Define an output change EventEmitter.
  3. Emit the event in the onAfterClose handler.

EditDialogComponent:

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'edit-dialog',
  templateUrl: './edit-dialog.component.html',
  styleUrls: ['./edit-dialog.component.css']
})
export class EditDialogComponent implements OnInit {


  @Input() item: ItemClass; // you entity to edit
  @Input() visible: boolean = false;
  @Output() visibleChange:EventEmitter<any> = new EventEmitter();

  constructor() { }

  ngOnInit() {
  }

  afterHide() {
    this.visibleChange.emit(false);
  }
}

Template:

<p-dialog header="Godfather I" [(visible)]="visible" (onAfterHide)="afterHide()" modal="modal" responsive="true">
    <p>Some content....</p>
        <p-footer>
            <div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
                <button type="button" pButton icon="fa-close" (click)="visible=false" label="Cancel"></button>
                <button type="button" pButton icon="fa-check" (click)="visible=false" label="OK"></button>
            </div>
        </p-footer>
</p-dialog>

Then you can use your EditDialogComponent by instantiating in the parent component's template, not in typescript code.

<edit-dialog [(visible)]="displayEditDialog" [item]="selectedItem"></edit-dialog>

In the component's code you can call the dialog by setting the display attribute to true. No import if EditDialogComponent is needed.

...  
    selectedItem: ItemClass; // selected by table

    changeItem() {
        this.displayEditDialog = true;
    }
...

Hope this helps.

Upvotes: 2

naoru
naoru

Reputation: 2227

so in case in helps someone

create a new component for the dialog and placed its selector in the wrapper component html file

<app-mac-dialog></app-mac-dialog>

now you need some kind of event to fire that component Im using a shared service with EventEmitter to pass data to the dialog component and basically turn its display attribute to true

Upvotes: 0

Related Questions