Ammar Khan
Ammar Khan

Reputation: 2585

Hierarichal Grid with Angular JS 2

I am trying to implement Hierarchical Grid in my Angular 2 application similar to this one http://demos.telerik.com/kendo-ui/grid/hierarchy

So I started out by creating two components. The Parent Component is for parent table and Child Component is for child table. So when click on row from parent table, the child table will load right below it (like above example).

This is how my html looks like

<div class="row">
    <div class="col-md-12">
        <h1>{{pageTitle}}</h1>
        <table class="table table-striped">
            <thead>
                <tr>
                    <td></td>
                    <td>User Name</td>
                    <td>Email</td>
                    <td>Billing Method</td>
                </tr>
            </thead>
            <tbody>
                <tr class="master-row" *ngFor="#invoice of invoices; #i = index">
                    <td><button (click)="getDetail(invoice)"><i class="glyphicon glyphicon-chevron-right"></i></button></td>
                    <td>{{invoice.username}}</td>
                    <td>{{invoice.email}}</td>
                    <td>{{invoice.billingMethod}}</td>
                </tr>

            </tbody>
        </table>
    </div>
</div>

But I am having two issues:

1) How to load child table on a correct location in DOM? The problem is when my parent table render, all of it's rows gets created using ngFor directive. Now when click on a row, how to load it's child table right below it? How to identify the location?

2) In order to load child table, I was thinking to use DynamicComponentLoader Class, but looks like the communication between Components won't be possible when using DCL.

Please suggest

Upvotes: 0

Views: 2018

Answers (1)

Abdulrahman Alsoghayer
Abdulrahman Alsoghayer

Reputation: 16540

I was able to fulfill your requirements using the template syntax of ngFor

pre 2.0.0-beta.17 syntax:

<template ngFor #item [ngForOf]="items" #i="index">
    <tr>...</tr>
</template>

2.0.0-beta.17 syntax:

<template ngFor let-invoice [ngForOf]="invoices" let-i="index">
    <tr>...</tr>
</template>

Check out this plunker

In your situation it will be:

<template ngFor let-invoice [ngForOf]="invoices" let-i="index">
    <tr class="master-row" *ngFor="#invoice of invoices; #i = index">
        <td><button (click)="getDetail(invoice)"><i class="glyphicon glyphicon-chevron-right"></i></button></td>
        <td>{{invoice.username}}</td>
        <td>{{invoice.email}}</td>
        <td>{{invoice.billingMethod}}</td>
    </tr>
    <tr *ngIf="isInvoiceOpened(i)">
        <td colspan="100">
            <child-table [details]="details"></child-table>
        </td>
    </tr>
</template>

The isInvoiceOpened() function will return true if that particular row is opened. Which means you should have an array to hold opened rows indexes, i.e.

_openedDetails = [];

isInvoiceOpened(i){
  return this._openedDetails.indexOf(i)>-1;
}

getDetail(i){
  let index = this._openedDetails.indexOf(i);
  if(index > -1)
    this._openedDetails.splice(index,1);
  else
    this._openedDetails.push(i);
}

Upvotes: 1

Related Questions