absingharora
absingharora

Reputation: 134

Dropdown HTML table

Expected behavior:

Clicking on headings should open sub-content for that specific heading.

Current State:

Clicking on headings open sub-content for all headings.

app.component.html

<ul *ngFor="let audience of mockAudiences | keysPipe">
    <li (click)="toggleAudienceHeader(audience)" class="audience-type-th">
        {{audience.key}}
    </li>
    <li>
        <table *ngIf="showAudience" class="table">
            <tbody>
                <tr *ngFor="let data of audience.value">
                    <td></td>
                    <td>{{data.name}}</td>
                    <td>{{data.amount}}</td>
                    <td>
                        <input class="select-audience" type="checkbox" />
                    </td>
                </tr>
            </tbody>
        </table>
    </li>
</ul>

app.component.ts

import {Component} from '@angular/core';
import {bootstrap} from '@angular/platform-browser-dynamic';

@Component({
  selector: 'material-app',
  templateUrl: 'app.component.html'
})
export class AppComponent {
  showAudience: boolean = false;
  private version: any;
  audience = { selected: false };
  mockAudiences = [
        { 
            'In-Market': [
                { 'name': 'Automobile Buyers', 'amount': '8392384' },
                { 'name': 'Automobile Buyers', 'amount': '8392384' },
                { 'name': 'Automobile Buyers', 'amount': '8392384' },
                { 'name': 'Automobile Buyers', 'amount': '8392384' },
                { 'name': 'Automobile Buyers', 'amount': '8392384' }
            ]
        },
        { 
            'Lifestyle': [
                { 'name': 'Automobile Buyers', 'amount': '8392384' },
                { 'name': 'Automobile Buyers', 'amount': '8392384' },
                { 'name': 'Automobile Buyers', 'amount': '8392384' },
                { 'name': 'Automobile Buyers', 'amount': '8392384' },
                { 'name': 'Automobile Buyers', 'amount': '8392384' }
            ]
        }
    ];

  constructor() {
  }

  toggleAudienceHeader( audience ){
    console.log("audience key:: ", audience.key);
    this.showAudience = !this.showAudience;
    }

}

keys.pipe.ts

import { Injectable, Pipe, PipeTransform } from "@angular/core";

@Pipe({name: 'keysPipe'})
@Injectable()
export class KeysPipe implements PipeTransform {
    transform(array, args:string[]) : any {
        let keys = [];
        for (let obj in array) {
            for (let key in array[obj]){
                keys.push({key: key, value: array[obj][key]});
            }
        }
        console.log("keys:: ", keys);
        return keys;
    }
}

main.ts

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {HttpModule} from '@angular/http';
import {AppComponent} from './app.component';
import {MaterialModule} from '@angular/material';
import { KeysPipe } from './keys.pipe';


@NgModule({

  imports: [
    BrowserModule,
    CommonModule,
    HttpModule,
    MaterialModule,
    BrowserAnimationsModule
  ],

  declarations: [AppComponent, KeysPipe],
  bootstrap: [AppComponent],
  providers: []
})
export class PlunkerAppModule {}

platformBrowserDynamic().bootstrapModule(PlunkerAppModule);

Plunker:

http://plnkr.co/edit/U5Jk0sEpeKab4gv6J5nZ?p=info

Upvotes: 2

Views: 80

Answers (1)

developer033
developer033

Reputation: 24894

The problem is that you have a toggle variable to handle multiple "audiences". You could create a variable to store the index of clicked item, like this:

currIndex: number = -1;

Here we manipulate this index:

toggleAudienceHeader(index: number): void {
  if (this.currIndex === index) { // Clicked on an already open audience
    this.currIndex = -1;
  } else {
    this.currIndex = index;
  }
  // this.currIndex = this.currIndex === index ? -1 : index;
}

So, in template:

<ul *ngFor="let audience of mockAudiences | keysPipe, let i = index">
  <li (click)="toggleAudienceHeader(i)" class="audience-type-th">
    {{audience.key}}
  </li>
  <li>
    <table class="table">
      <tbody>
        <tr *ngFor="let data of audience.value">
          <ng-container *ngIf="currIndex === i">
            <td></td>
            <td>{{data.name}}</td>
            <td>{{data.amount}}</td>
            <td>
              <input class="select-audience" type="checkbox" />
            </td>
          </ng-container>
        </tr>
      </tbody>
    </table>
  </li>
</ul>

Forked PLUNKER

Update #1:

Here's the plunker to satisfy the condition of multiple open headers.

Upvotes: 1

Related Questions