Hierarchy Grid parent row data in childGrid actionCompleted

I have 3 hierarchy grids 1 mainGrid 2nd childGrid and 3rd secondChildGrid,
How could I know when adding a new row to secondChildGrid what childGrid row and its data is that spawned secondChildGrid? 

I think created() could be it but I have only seen the demo with main/child grid here https://ej2.syncfusion.com/angular/documentation/grid/hierarchy-grid#how-to-get-parent-detail-in-child-grid and I was unable to replicate it.

But even then I am unsure how I could get what comes from created() to be used in actionComplete without setting a global variable but that's is problematic because that would be wrong because when you create a secondChildGrid and go to create another one somewhere else from different branch of mainGrid and comeback to the first created instance it was already created and is not refreshed anymore?

To simplify the problem:
Is there is a way to correctly see on actionCompleted the parent row data?



<ejs-grid  #mainGrid (dataBound)="expandedIndexes($event)" (actionComplete)='actionCompleteMain($event)' [childGrid]='childGrid'  (commandClick)='commandClickInvoice($event)'  (load)='onLoad($event)' (detailDataBound)='detailDataBound($event)'  height="700" allowResizing="true"  [allowSorting]="true" [editSettings]='editSettings' [toolbar]='toolbar' [allowFiltering]='true' [filterSettings]="filterOption">
    <e-columns >
        <e-column field='carReg' headerText='Car Reg' width='120'    ></e-column>
        <e-column field='carMake' headerText='Car Make/Model' width='150'    ></e-column>
        <e-column field='clientName' headerText='Client Name' width='120'    ></e-column>
        <e-column field='address' headerText='Address' width='150'    ></e-column>
        <e-column field='mobile' headerText='Mobile' width='100'    ></e-column>
        <e-column field='email' headerText='Email' width='150'    ></e-column>
        <e-column field='milage' headerText='Milage' width='100'    ></e-column>
        <e-column field='vat' headerText='Vat' width='80'  foreignKeyValue='text' foreignKeyField='value' [dataSource]='dropdownVAT'   ></e-column>
        <e-column field='paymentType' headerText='Payment Type' width='100' foreignKeyValue='text'   foreignKeyField='text' [dataSource]='dropdownPaymentType'   ></e-column>
        <e-column field='status' headerText='Status' width='100' editType= 'dropdownedit'  [edit]='dropdownParams'   ></e-column>
        <e-column field='workers' headerText='Workers' width='150'    [allowEditing]="false"   ></e-column>
        <e-column headerText='' width=110 [commands]='commandsInvoice'></e-column>

    </e-columns>

</ejs-grid>

  public secondChildGrid: GridModel = {
    toolbar: ['Add', 'Delete'],
    queryString: 'key',
    allowResizing: true,
    editSettings: {
      allowEditing: true,
      allowAdding: true,
      allowDeleting: true,
      mode: 'Dialog',
    },
    columns: [
      {
        field: 'partName',
        headerText: 'Part Name',
        allowEditing: true,
      },
      {
        field: 'partPrice',
        headerText: 'Part Price',
        allowEditing: true,
      },
      {
        field: 'partSource',
        headerText: 'Part Source',
        allowEditing: true,
      },
    ],

    created: () => {},

    actionComplete: (args: any) => {
      console.log(args);
      switch (args.requestType) {
        case 'save':
          console.log(args);
          this.firebasedb.updatePart(
            JSON.parse(JSON.stringify(args.data)),
            this.parentKey,
            this.childKey
          );

          break;
        case 'delete':
          args.data.forEach((row: any) => {
            this.firebasedb.removePart(
              row.secondChildKey,
              this.parentKey,
              this.childKey
            );
          });

          break;
      }
    },
  };
  childKey;
  public childGrid: GridModel = {
    toolbar: ['Add', 'Delete'],
    queryString: 'key',
    allowResizing: true,
    editSettings: {
      allowEditing: true,
      allowAdding: true,
      allowDeleting: true,
      mode: 'Dialog',
    },
    columns: [
      {
        field: 'jobTitle',
        headerText: 'Job Title',
        textAlign: 'Right',
        allowEditing: true,
        width: 120,
      },
      {
        field: 'worker',
        headerText: 'Worker Name',
        width: 100,
        editType: 'dropdownedit',
        edit: this.userparams,
      },
      {
        field: 'rateType',
        headerText: 'Rate Type',
        width: 50,
        allowEditing: true,
        foreignKeyValue: 'text',
        foreignKeyField: 'value',
        dataSource: this.dropdownRates,
      },
      {
        field: 'rateQty',
        headerText: 'Hourly Rate',
        width: 50,
        allowEditing: true,
      },
      {
        field: 'mot',
        headerText: 'MOT',
        width: 50,
        allowEditing: true,
      },
      { field: 'oil', headerText: 'Oil', width: 50 },
      { field: 'webCost', headerText: 'Web Cost', width: 50 },
      {
        field: 'priceMulti',
        headerText: 'Part Price Multi',
        width: 50,
        allowEditing: true,
      },
      { field: 'time', headerText: 'Spent Time', width: 50 },
      {
        field: 'dateWorker',
        headerText: 'Worker Done Date',
        width: 70,
        type: 'date',
        format: 'dd/MM/yyyy',
        editType: 'datepickeredit',
      },
      {
        field: 'date',
        headerText: 'Salary Date',
        width: 70,
        type: 'date',
        format: 'dd/MM/yyyy',
        editType: 'datepickeredit',
      },

      { field: 'cof', headerText: 'Worker Cof', width: 50, allowEditing: true },

      {
        field: 'price',
        headerText: 'Final Price',
        width: 50,
        allowEditing: false,
      },
      {
        field: 'salary',
        headerText: 'Worker Salary',
        width: 50,
        allowEditing: false,
      },
      { field: 'profit', headerText: 'Profit', width: 50, allowEditing: false },
    ],
    childGrid: this.secondChildGrid,

    dataBound: (args: any) => {
      let workers: string[] = [];
      workers = [];
      this.childdatasource.forEach((row: any) => {
        if (row.worker) workers.push(row.worker);
      });
      this.firebasedb.updateWorkers(workers, this.parentKey);
    },

    detailDataBound: (args: any) => {
      console.log(args);
      let childKey = args.data.key;
      this.childKey = childKey;

      this.firebase
        .list(`/main/${this.parentKey}/children/${childKey}/secondChildren`)
        .snapshotChanges()
        .subscribe((users: any) => {
          var data = users;
          data.childKey = childKey;
          args.childGrid.query = new Query();
          args.childGrid.dataSource = data; // sync server data changes to grid
        });

      this.firebase
        .list(`/main/${this.parentKey}/children/${childKey}/secondChildren`)
        .valueChanges()
        .subscribe((users: any) => {
          var data = users;
          data.childKey = childKey;
          args.childGrid.query = new Query();
          args.childGrid.dataSource = data; // sync server data changes to grid
        });
    },

    actionComplete: (args: any) => {
      switch (args.requestType) {
        case 'save':
          this.firebasedb.updateJobs(
            JSON.parse(JSON.stringify(args.data)),
            this.parentKey
          );
          this.storeExpandedIndexes();
          //   let workers: string[] = [];
          //   workers = [];
          //  args.data.forEach((row: any) => {
          //     if (row.data.worker) workers.push(row.data.worker);
          //   });
          //   this.firebasedb.updateWorkers(workers, this.parentKey);
          break;
        case 'delete':
          args.data.forEach((row: any) => {
            this.firebasedb.removeJob(row.key, this.parentKey);
          });

          // this.firebasedb.updateWorkers(workers, this.parentKey);
          break;
      }
    },
  };
















3 Replies

HS Hemanthkumar S Syncfusion Team October 19, 2023 03:42 AM UTC

Hi Frank Alberts,


Greetings from Syncfusion support.


Query: I have 3 hierarchy grids 1 mainGrid 2nd childGrid and 3rd secondChildGrid, How could I know when adding a new row to secondChildGrid what childGrid row and its data is that spawned secondChildGrid? Is there is a way to correctly see on actionCompleted the parent row data?


Based on the information you provided, it seems you want to access the parent (childGrid) row data of the child grid (secondChildGrid) when adding a new row. In response to your request, we have created a sample-level solution. We recommend obtaining the parent (childGrid) row data of the child grid (secondChildGrid) in the actionComplete event of the child grid (secondChildGrid) specifically when the action and requestType parameters are set to add and save respectively.


For more information, please refer to the code example, video, and sample.


[app.component.ts]

 

    this.secondChildGrid = {

      dataSource: this.secondChildGridData,

      queryString: 'CustomerID',

      editSettings: {

        allowEditing: true,

        allowAdding: true,

        allowDeleting: true,

        mode: 'Normal',

        newRowPosition: 'Top',

      },

      toolbar: ['Add''Edit''Delete''Update''Cancel'],

      columns: [

        {

          field: 'ID',

          headerText: 'ID',

          textAlign: 'Right',

          width: 75,

          isPrimaryKey: true,

        },

        {

          field: 'CustomerID',

          headerText: 'Customer ID',

          textAlign: 'Right',

          width: 75,

        },

        { field: 'Phone'headerText: 'Phone'width: 100 },

        { field: 'Address'headerText: 'Address'width: 120 },

        { field: 'Country'headerText: 'Country'width: 100 },

      ],

      actionComplete: (args=> {

        if (args.action === 'add' && args.requestType === 'save') {

          const form = args.form;

          const secondChildGridElementId = form.id.split('EditForm')[0];

          const secondChildGridElement = document.getElementById(

            secondChildGridElementId

          );

          const childGridRowElement = closest(secondChildGridElement'tr');

          const childGridParentRowElement =

            childGridRowElement.previousElementSibling;

          const childGridElement = closest(

            childGridParentRowElement,

            '.e-grid'

          );

          const childGridInstance = (childGridElement as any).ej2_instances[0];

          const uid = childGridParentRowElement.getAttribute('data-uid');

          const rowObject = childGridInstance.getRowObjectFromUID(uid);

          const rowData = rowObject.data;

          console.log(rowData);

        }

      },

    };

 


Sample: https://stackblitz.com/edit/angular-uj5bca-vvdvzt?file=src%2Fapp.component.ts


Please feel free to contact us if you require any further assistance. We are always available and eager to help you in any way we can.


Regards,

Hemanth Kumar S


Attachment: video_c1e01ef8.zip


JB Jonas Blazinskas October 20, 2023 12:54 AM UTC

Thanks Hemanth,

The above works well.

But I just realised my problems do not stop here, and I need to know the main grid(top level Grid) data as well, I was using detailDataBound event before but now I am realising it only triggers once when I expand the main grid first time. So if I go and expand another child and come back to expand the first child I do not get an event triggering and I cant read the associated main grids data from its children.

Do you recommend doing something similar to your code to climb a layer higher?(maybe you could elaborate how it's done as I do not think I can easily transform your code to work with one layer higher)





HS Hemanthkumar S Syncfusion Team October 26, 2023 03:08 PM UTC

Hi Frank Alberts,


Query: Do you recommend doing something similar to your code to climb a layer higher?


From your shared information, we understand that you want to get the n-level of parent row data. Based on your update we have prepared a sample-level solution and this sample demonstrates how to get the n-level of parent row data.


For more information, please refer to the code example, video, and sample.


[app.component.ts]

 

      actionComplete: (args=> {

        if (args.action === 'add' && args.requestType === 'save') {

          this.getNLevelOfGridData(args);

        }

      },

 

  getNLevelOfGridData(args) {

    const nLevelDataany[] = [];

    const form = args.form;

    const currentChildGridElementId = form.id.split('EditForm')[0];

    let currentChildGridElementany = document.getElementById(

      currentChildGridElementId

    );

    while (

      currentChildGridElement &&

      currentChildGridElement.ej2_instances[0].parentDetails

    ) {

      nLevelData.push(

        currentChildGridElement.ej2_instances[0].parentDetails.parentRowData

      );

      const currentChildGridRowElement = closest(currentChildGridElement'tr');

      currentChildGridElement = closest(currentChildGridRowElement'.e-grid');

    }

    console.log(nLevelData);

  }

 


Sample: https://stackblitz.com/edit/angular-uj5bca-hcfkvw?file=src%2Fapp.component.ts


Please feel free to contact us if you require any further assistance. We are always available and eager to help you in any way we can.


Regards,

Hemanth Kumar S


Attachment: video_dda88075.zip

Loader.
Up arrow icon