[Fixed] Angular/PrimeNG open one modal dialog at index/value whenever clicking on that table value

Issue

**HTML CODE:**

<p-table [value]="SourcesEntities" styleClass="p-datatable-gridlines">
  <ng-template pTemplate="caption">
    <h2>Entities</h2>

    <div class="container">
      <div class="row">
        <div class="col-xs-12">
          <app-create-entity></app-create-entity>
        </div>
      </div>
    </div>
  </ng-template>
  <ng-template pTemplate="header">
      <tr>
          <th>Entity Name</th>
          <th>Type</th>
          <th>Source</th>
          <th>Retrieval Frequency</th>
      </tr>
  </ng-template>
  <ng-template pTemplate="body" let-entity let-rowIndex="rowIndex">
      <tr>
          <td>
            <button pButton
            label="{{entity.Ename}}"
            (click)="showDialog()"
            icon="pi pi-external-link"></button>
          </td>
          <td>{{entity.type}}</td>
          <td>{{entity.source}}</td>
          <td>{{entity.frequency}}</td>
      </tr>
      <!-- <p-dialog
      header="{{entity.Ename}} Attributes"
      [(visible)]="display"
      [breakpoints]="{'960px': '75vw', '640px': '100vw'}"
      [style]="{width: '50vw'}"></p-dialog> -->
  </ng-template>
</p-table>


***TS code:***

import { Component, OnInit, OnDestroy } from '@angular/core';
import {SourcesService} from '../sources.service';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-sources-entities',
  templateUrl: './sources-entities.component.html',
  styleUrls: ['./sources-entities.component.css']
})
export class SourcesEntitiesComponent implements OnInit {

  SourcesEntities = [];
  SourcesAttributes =  [];
  display: boolean = false;
      

  showDialog(){
    //this function should get the index from which entity is clicked
    //then return a dialog with the content of that index + its attributes!
    //ngFor somehow breaks the table
    console.log('entity clicked')
    this.display = true;
  }
}

***Service.ts code:***

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { SourcesLogService } from './Sourceslog.service';

@Injectable()
export class SourcesService {

  private  SourcesEntities = [
    {Ename: 'Employees', type:'DB Table', source: 'sourceA', frequency: 'RF'},
    {Ename: 'Product', type: 'Web Service', source: 'sourceB', frequency: 'RF'},
    {Ename: 'Movies', type: 'Source file', source: 'sourceC', frequency: 'RF'}
  ];
  
  //These are the attributes that should be shown when you click on an entity Ename. One for
  //each row. i.e. George for Employees


  private SourcesAttributes = [
    {name: 'George', type: 'sofware dev'},
    {name: 'PC', type:'gaming'},
    {name: 'Star-Wars: The Phantom Menace', type: 'Sci-fy'}
  ]   
}

So in Summary I want when click on a value in Entity Name column to
pop a dialog just for that one entity cell/row that will consists of that entity’s attributes
{Name,Description}.
Instead I am getting
multiple dialogs one for each row/entity name I have in my table. Hope
that helps, Let me know if I should make my question more clear or if
something doesnt make sense please

I have tried using *ngFor="" but messes up with my table somehow…Probably I have used it
on the wrong element or something. I am really new to angular so….

  [1]: https://i.stack.imgur.com/TMfb4.png  

You can see in the image my attributeData declared as

attributeData = [{
                   header: [],
                   data: [{name:''},{type:''}]
                }]

If I dont declare it that way wont work. But still that way even if it works on my html attributeData.data.name data is not recognized. Sorry is just kind of confusing for me:/

> Blockquote

Solution

  1. Update the showDialog() function by passing the header name & rowIndex to it.

    ** HTML Template **
    (click)="showDialog(entity.Ename, rowIndex)" 
    
    ** Component TS File **
    attributeData = {};
    showDialog(headerText, rowIndex) {
        this.attributeData['header'] = headerText;
        this.attributeData['data'] = this.SourcesAttributes[rowIndex];
        this.display = true;
    }
    
  2. Place the p-dialog after the closing tag of p-table.

    </p-table>
    <p-dialog
     header="{{attributeData.header}} Attributes"
     [(visible)]="display"
     [breakpoints]="{'960px': '75vw', '640px': '100vw'}"
     [style]="{width: '50vw'}">
         Content Goes Here
         {{attributeData.data.name}}
         {{attributeData.data.type}}
    </p-dialog>
    

Leave a Reply

(*) Required, Your email will not be published