Abrar Ahamed
Abrar Ahamed

Reputation: 199

angular 2 - tree view expanding all nodes how to make it expand only child

I have json file as below

{
    "transactions": [{
        "Transaction ref : 321916010424": {
            "request": [{
                "Field": "DE-000",
                "length": "004",
                "value": "0100"
            }, {
                "Field": "DE-001",
                "length": "016",
                "value": "11110010 00111100 01000100 10000001 10001000 11100001 10000000 00001000                       00000000 00000000 00000000 00000000 00000000 00000000 00000001 11000000 "
            }],
            "response": [{
                "Field": "DE-000",
                "length": "004",
                "value": "0110"
            }, {
                "Field": "DE-001",
                "length": "008",
                "value": "00110010 00111010 00000000 00000000 00001110 11000001 10000000 00000010 "
            }, {
                "Field": "DE-003",
                "length": "006",
                "value": "003000"
            }]
        }
    }, {
        "Transaction ref : 000463000046": {
            "request": [{
                "Field": "DE-000",
                "length": "004",
                "value": "0100"
            }, {
                "Field": "DE-001",
                "length": "016",
                "value": "11110010 00111100 01000100 10000001 10101000 11100001 10000010 00001000                       00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000 "
            }],
            "response": [{
                "Field": "DE-000",
                "length": "004",
                "value": "0110"
            }, {
                "Field": "DE-001",
                "length": "008",
                "value": "00110010 00111010 00000000 00000000 00001110 11000001 10000000 00000010 "
            }, {
                "Field": "DE-063",
                "length": "009",
                "value": "AMXHZGWJ7"
            }]
        }
    }]
}

my html file is

<ul  style="border: none" class="list-unstyled">
  <li *ngFor="let a of acquirer_response | keys ">
    <ul class="list-unstyled" >
      <li *ngFor="let b of a.value | keys ">
        <ul class="list-unstyled">
          <li *ngFor="let c of b.value | keys " class="list-group">
            <strong  (click)="isCollapsedContent = !isCollapsedContent">
              <span class="glyphicon glyphicon-plus-sign"></span>
              {{c.key}}</strong>

            <ul class="list-unstyled" *ngIf="isCollapsedContent">
              <li *ngFor="let d of c.value | keys " class ="list-group-item list-group-item-info" (click)="isCollapsedContent = !isCollapsedContent"  >
                <strong>
                  <span class="glyphicon glyphicon-plus-sign"></span>
                  {{d.key}}</strong>

                <ul class="list-unstyled" *ngIf="isCollapsedContent">
                  <li *ngFor="let e of d.value | keys " class ="list-group-item list-group-item-info">
                    <ul class="list-unstyled" (click)="isCollapsedContent = !isCollapsedContent" >
                      <li *ngFor="let f of e.value | keys " class ="list-group-item list-group-item-info"  >
                        {{f.value}}
                    </ul>

                  </li>
                </ul>

              </li>
            </ul>

          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>



import {Directive, Input, HostBinding} from '@angular/core';


@Directive({selector: '[collapse]'})
export class Collapse {
  // style
  @HostBinding('style.height')
  private height:string;
  // shown
  @HostBinding('class.in')
  @HostBinding('attr.aria-expanded')
  private isExpanded:boolean = true;
  // hidden
  @HostBinding('attr.aria-hidden')
  private isCollapsed:boolean = false;
  // stale state
  @HostBinding('class.collapse')
  private isCollapse:boolean = true;
  // animation state
  @HostBinding('class.collapsing')
  private isCollapsing:boolean = false;

  @Input()
  private set collapse(value:boolean) {
    this.isExpanded = value;
    this.toggle();
  }

  private get collapse():boolean {
    return this.isExpanded;
  }

  constructor() {
  }

  toggle() {
    if (this.isExpanded) {


      this.hide();
    } else {
      this.show();
    }
  }

  hide() {
    this.isCollapse = false;
    this.isCollapsing = true;

    this.isExpanded = false;
    this.isCollapsed = true;
    setTimeout(() => {
      this.height = '0';
      this.isCollapse = true;
      this.isCollapsing = false;
    }, 4);
  }

  show() {
    this.isCollapse = false;
    this.isCollapsing = true;

    this.isExpanded = true;
    this.isCollapsed = false;
    setTimeout(() => {
      this.height = 'auto';

      this.isCollapse = true;
      this.isCollapsing = false;
    }, 4);
  }
}

now I got the tree structure as expected like this

+ Transaction ref : 321916010424

+ Transaction ref : 000463000046

but when i click + Transaction ref : 321916010424 it expands all the items including the next transaction ref items and child nodes . the same is happening when i try to expand child node. pls help how can restrict the expand and collapse for a particular node only.

collapse component file

import {Directive, Input, HostBinding} from '@angular/core';


@Directive({selector: '[collapse]'})
export class Collapse {
  // style
  @HostBinding('style.height')
  private height:string;
  // shown
  @HostBinding('class.in')
  @HostBinding('attr.aria-expanded')
  private isExpanded:boolean = true;
  // hidden
  @HostBinding('attr.aria-hidden')
  private isCollapsed:boolean = false;
  // stale state
  @HostBinding('class.collapse')
  private isCollapse:boolean = true;
  // animation state
  @HostBinding('class.collapsing')
  private isCollapsing:boolean = false;

  @Input()
  private set collapse(value:boolean) {
    this.isExpanded = value;
    this.toggle();
  }

  private get collapse():boolean {
    return this.isExpanded;
  }

  constructor() {
  }

  toggle() {
    if (this.isExpanded) {


      this.hide();
    } else {
      this.show();
    }
  }

  hide() {
    this.isCollapse = false;
    this.isCollapsing = true;

    this.isExpanded = false;
    this.isCollapsed = true;
    setTimeout(() => {
      this.height = '0';
      this.isCollapse = true;
      this.isCollapsing = false;
    }, 4);
  }

  show() {
    this.isCollapse = false;
    this.isCollapsing = true;

    this.isExpanded = true;
    this.isCollapsed = false;
    setTimeout(() => {
      this.height = 'auto';

      this.isCollapse = true;
      this.isCollapsing = false;
    }, 4);
  }
}

Upvotes: 0

Views: 1716

Answers (2)

Abrar Ahamed
Abrar Ahamed

Reputation: 199

finally achieved the result as i want just by modifying html. if anyone interested pls see below if you see my existing one and this modified html you can know what i changed

    <ul class="list-unstyled">
  <li *ngFor="let t of acquirer_response | keys">
    <ul class="list-unstyled"  class="list-group" >
      <li *ngFor="let b of t.value | keys ">
        <ul class="list-unstyled"  >
          <span class="glyphicon glyphicon-plus-sign" (click)="t.isCollapsedContent =!t.isCollapsedContent"></span> {{b.key}}
          <div *ngIf="t.isCollapsedContent">
            <li *ngFor="let c of b.value | keys ">
              <div *ngIf="c.key == 'request'"  style="border: none">
                <ul  class="list-unstyled"  class="list-group-item list-group-item-info">
                  <strong  class="list-group-item list-group-item-info" style="border: none" (click)="c.value.isCollapsedContent =!c.value.isCollapsedContent" >
                    <span class="glyphicon glyphicon-plus-sign"  ></span>{{c.key}}{{c.value.isCollapsedContent }}
                  </strong>
                  <div  *ngIf="c.value.isCollapsedContent">
                    <li *ngFor="let d of c.value | keys" class="list-group-item list-group-item-info">
                      <ul class="list-unstyled" >
                        <li *ngFor="let e of d.value | keys"  class="list-group-item list-group-item-info">
                          <td>{{e.key }}{{e.value}}</td>
                        </li>
                      </ul>
                    </li>
                  </div>
                </ul>
              </div>
              <div *ngIf="c.key == 'response'">
                <ul  class="list-unstyled"  class="list-group-item list-group-item-info">
                  <strong  class="list-group-item list-group-item-info" style="border: none" (click)="c.value.isCollapsedContent =!c.value.isCollapsedContent">
                    <span class="glyphicon glyphicon-plus-sign"></span>Response Response</strong>
                  <div  *ngIf="c.value.isCollapsedContent">
                    <li *ngFor="let d of c.value | keys" class="list-group-item list-group-item-info">
                      <ul class="list-unstyled" >
                        <li *ngFor="let e of d.value | keys"  class="list-group-item list-group-item-info">
                          <td>{{e.key }}{{e.value}}</td>
                        </li>
                      </ul>
                    </li>
                  </div>
                </ul>
              </div>
            </li>
          </div>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Upvotes: 0

Ranjeeth Rao
Ranjeeth Rao

Reputation: 155

The reason all nodes expand is that you are having a common variable ('isCollapsedContent') to indicate if it is collapsed or not. This logic is suitable if you need an 'Expand All/Collapse All' button.

The remedy for your solution is to have an 'isCollapsedContent' attribute for each node. So that based on the click they toggle only the clicked node.

Upvotes: 1

Related Questions