1

I have this simple grid:
enter image description here

The values in ChildColumn DropDown list depend on which option the user chose in the DropDown list in parent component.
For example: User chooses Option2 in parent column. List2 will get displayed in ChildColumn.
enter image description here
However, in order for the List2 to get displayed I have refresh the ChildColumn. For now, I am doing it with the "Refresh grid" button. However, I want it to happen automatically whenever the user chooses a new option in the ParentColumn.
I couldn't find a way to do this.

Here's the grid.component.ts code:

    import {Component, OnInit} from '@angular/core';
    import { FirstCellRendererComponent } from './first-cell-renderer/first-cell-renderer.component';
    import { SecondCellRendererComponent } from './second-cell-renderer/second-cell-renderer.component';
    import {ParentComChildDropValue} from './parentComChildDropValue.service'

    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
      constructor(private data: ParentComChildDropValue
        ) { }
      columnDefs = [
        {
              headerName: "ParentColumn",
              field: "prtCol",
              cellRenderer:'parentColCellRenderer'
            },
            {
              headerName: "ChildColumn",
              field: "chdCol",
              cellRenderer:  (params) => {
                return(
                       `       <select class="form-control">
                    <br>`
                    +`<option>` +
                    this.receivedChosenOptionfromCol1[0]
                    +`</option>`
                    +`<option>` +
                    this.receivedChosenOptionfromCol1[1]
                    +`</option>` +
                    `<option>` +
                    this.receivedChosenOptionfromCol1[2]
                    +`</option>` +
                    `<option>` +
                    this.receivedChosenOptionfromCol1[3]
                    +`</option>` +
                  `</select>
                `)
              }
            }
      ];
      rowData = [{}];
      frameworkComponents = {
        parentColCellRenderer: FirstCellRendererComponent,
        childColCellRenderer: SecondCellRendererComponent,
      };
      receivedChosenOptionfromCol1:string[];
      ngOnInit() {
        this.data.currentOption.subscribe(receivedOption => (this.receivedChosenOptionfromCol1 = receivedOption));
      }
      /**THIS CODE IS RESPONSIBLE FOR REFRESHING THE GRID AFTER VALUES HAVE BEEN CHANGED */
      private gridApi;
      onGridReady(params) {
        this.gridApi = params.api;
        params.api.sizeColumnsToFit();
      }
      public refreshCol2() {
        const params = { force: true, columns: ["chdCol"] };
        this.gridApi.refreshCells(params);
      }
    }

Here's the grid.component.html:

    <button (click)="refreshCol2()">Refresh grid</button>
    <ag-grid-angular
      style="width: 500px; height: 500px;"
      class="ag-theme-balham"
      [enableSorting]="true"
      [enableFilter]="true"
      [pagination]="true"
      [rowData]="rowData"
      [columnDefs]="columnDefs"
      [frameworkComponents]="frameworkComponents"
      (gridReady)="onGridReady($event)"
    >
    </ag-grid-angular>

This is the ParentColumn Custom cell renderer.ts:

    import { Component, OnInit } from '@angular/core';
    import {ParentComChildDropValue} from '../parentComChildDropValue.service'
    @Component({
      selector: 'app-first-cell-renderer',
      templateUrl: './first-cell-renderer.component.html',
      styleUrls: ['./first-cell-renderer.component.css']
    })
    export class FirstCellRendererComponent{
      /**PS THE FOLLOWING CODE IS CRUCIAL FOR THE CELL RENDERER TO WORK */
      params: any;
      agInit(params: any): void {
        this.params = params;
      }
      /**!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
      /**COMMUNICATION BETWEEN CELL RENDERERS CODE */
      constructor(private data: ParentComChildDropValue) { }
      /**§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§ */
      colTwoList:string[]=[]
      public populateListInColTwo(chosenOption){
        // I added the following line because without it the colTwoList gets all the accumulated chosen lists
        this.colTwoList=[]
        console.log('HERE THE CHOSEN OPTION' + chosenOption.value)
        if (chosenOption.value==="ParentList_Option1"){
        this.colTwoList.push('List1_Option1')
        this.colTwoList.push('List1_Option2')
        this.colTwoList.push('List1_Option3')
        this.colTwoList.push('List1_Option4')
        console.log('List One was populated')
        }
        else if (chosenOption.value==="ParentList_Option2"){
          this.colTwoList.push('List2_Option1')
          this.colTwoList.push('List2_Option2')
          this.colTwoList.push('List2_Option3')
          this.colTwoList.push('List2_Option4')
        console.log('List Two was populated')
        }
        else if (chosenOption.value==="ParentList_Option3"){
          this.colTwoList.push('List3_Option1')
        this.colTwoList.push('List3_Option2')
        this.colTwoList.push('List3_Option3')
        this.colTwoList.push('List3_Option4')
        console.log('List Three was populated')
        }
        else if (chosenOption.value==="ParentList_Option4"){
          this.colTwoList.push('List4_Option1')
          this.colTwoList.push('List4_Option2')
          this.colTwoList.push('List4_Option3')
          this.colTwoList.push('List4_Option4')
        console.log('List Four was populated')
        }
        this.data.changeList(this.colTwoList)
      }
    }

This is the ParentColumn custom cell renderer html:

    <select class="form-control" (change)="populateListInColTwo($event.target)">
      <br>
      <option id="1"></option>
      <option id="1">ParentList_Option1</option>
      <option id="2">ParentList_Option2</option>
      <option id="3">ParentList_Option3</option>
      <option id="4">ParentList_Option4</option>
    </select>

This is service.ts responsible of sending the data from the ParentColumn custom cell renderer to the grid to be displayed in childColumn:

    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs';

    @Injectable()
    export class ParentComChildDropValue {
      private optionSource = new BehaviorSubject<string[]>([]);
      currentOption = this.optionSource.asObservable();
      constructor() {}
      changeList(receivedOption: string[]) {
        this.optionSource.next(receivedOption)
        console.log('changeOption works and this is the string list in the service '+receivedOption)
      }
    }

I really couldn't find a way to make refresh the list in ChildColumn whenever the user chooses an option in ParentColumn. I already have an event that gets fired whenever the user chooses an option in ParentColumn. But, how can I make use of it in ChildColumn?
Thank you!

Bernardo Marques
  • 925
  • 2
  • 10
  • 33
Ahmed Ghrib
  • 695
  • 4
  • 13
  • 29
  • Are you asking about two concatenated dropdown?. It are only a few options, take a look to https://stackoverflow.com/questions/56012665/how-to-display-datas-with-angular/56019168#56019168 – Eliseo May 09 '19 at 16:05
  • @Eliseo I did manage to implement concatenated dropdowns lists with my code. My problem is with the refresh part. I want the second dropDown list to be refreshed as soon as the user chooses a certain option from the first dropDown list. – Ahmed Ghrib May 10 '19 at 07:38
  • @Eliseo I have just found a way to do this and posted an answer. Please check it out and tell me what you think – Ahmed Ghrib May 10 '19 at 08:30

1 Answers1

1

I found a tricky way to get around this. It's not a perfect solution. You can use it until we found a better one :)
What I did is create a boolean variable called refresh that would be set to true everytime the user changes the option in the dropDown list in the parentColumn.
Then, when the gridComponent detects that this variable has been set to true. It refreshs the grid and then resets refresh to false.
The (bad)trick I used is:
The method that would refresh the grid will be launched everytime the user selects that row.

service.ts

 /** TESTING GRID_REFRESH USING A BOOLEAN REFRESH VARIABLE */
  private refreshSource = new BehaviorSubject<boolean>(false);
  currentRefresh = this.refreshSource.asObservable();
  changeRefresh(receivedRefresh: boolean) {
    this.refreshSource.next(receivedRefresh)
    console.log('changeOption works and this is the refresh value in the service '+receivedRefresh)
  }
  /** TESTING GRID_REFRESH USING A BOOLEAN REFRESH VARIABLE */

parentColComponent.ts: Add this method to the dropDown listener

  this.data.changeRefresh(false)

GridComponent.html: add this to the grid definition

  (rowClicked)="testShit()"

GridComponent.ts Subscribe to the service:

ngOnInit() {
    this.data.currentRefresh.subscribe(receivedRefresh => (this.receivedRefreshfromCol1 = receivedRefresh));
  }

Refresh method in GridComponent.ts:

 public testShit() {
    if (this.receivedRefreshfromCol1===true){
    const params = { force: true, columns: ["chdCol"] };
    this.gridApi.refreshCells(params);

  }
  this.data.changeRefresh(false)

}

Hope this helps :)

Ahmed Ghrib
  • 695
  • 4
  • 13
  • 29
  • 1
    Can you please have a look at this once - https://stackoverflow.com/questions/56231178/angular-ag-grid-undo-selected-row-changes-on-button-click – Olivia May 21 '19 at 14:36