Updating parent data grid from child grid

1 Answer 7 Views
Data Source Grid
Y
Top achievements
Rank 1
Y asked on 10 Jun 2025, 11:22 AM

Hello

I have a grid and each row can be expanded, using detailInit, to show an inner grid. 

I fetch the data beforehand so that I can populate the grid using local data.

In inner grid I have a column with a delete button  - using template I call a delete function passing this as a parameter.



// column definition
 {
                    field: "delete",
                    title: "Delete",
                    width: 50,
                    template: "<span class='delete' onclick='delete(this)'><img src='.delete_icon.png'/></span>"
},

my delete function :


function delete(e) {
            let Loader = KENDO.KendoLoader($("body"));
            try {
                Loader.Show();
                let row = $(e).closest("tr");
                let grid = $(e).closest(".innerGrid");

                let dataItem = KENDO.KendoGrid(grid).GetDataItem(row);
                let innerRowId= dataItem.id;

                let parentRow = row.parent().closest(".k-detail-row").prev();
                let parentDataItem = KENDO.KendoGrid($("#ParentGrid")).GetDataItem(parentRow);

                KENDO.KendoGrid(grid).DeleteUI([innerRowId]); // DeleteUI gets array of ids to delete , implemented below
               
                // if no rows remain in inner grid, I need to update a column's value in the parent row
                if (KENDO.KendoGrid(grid).HasRows() == false) {
                    grid.hide();
                    grid.siblings(".noRecordsFound").show();

                     let updatedDataObj = {
                            id: parentDataItem.id,
                            someColumnOnParentRow: null
                        }

                        KENDO.KendoGrid($("#ParentGrid")).UpdateUI([updatedDataObj]); // UpdateUI gets array of objects to update, implemented below
                }
            }
            catch (error) {
                debugger;
                console.log(error.message);
            }
            finally {
                Loader.Hide();
            }
        }

We have created a own KENDO wrapper script for different widgets. Here is the kendoGrid code: 


let KENDO = {
  KendoComponent(jQueryElement, component, options = null) {

        let kendoComponent = {};

        kendoComponent.InitKendoComponent = function () {
            let kComponent = jQueryElement.data(component);
            if (!kComponent) {
                if (options) {
                    kComponent = jQueryElement[component](options).data(component);
                }
                else {
                    kComponent = jQueryElement[component]().data(component);
                }
            }
            return kComponent;
        };

        return kendoComponent;
    },

   KendoGrid(jQueryElement, options = null) {

        let kendoGrid = {};

        let kGrid = KENDO.KendoComponent(jQueryElement, "kendoGrid", options).InitKendoComponent();
        if (options)
            kGrid.setOptions(options);

        kendoGrid.SetOptions = function (options) {
            kGrid.setOptions(options);
            return kendoGrid;
        }

        kendoGrid.GetData = function () {
            return Array.from(kGrid.dataSource.data());
        }

        kendoGrid.GetDataItem = function (jQueryTableRow) {
            return kGrid.dataItem(jQueryTableRow);
        }

        kendoGrid.UpdateUI = function (dataToUpdate = []) {
            dataToUpdate.forEach(obj => {
                let dataItem = kGrid.dataSource.get(obj.id);
                if (dataItem) {
                    for (let prop in obj) {
                        if (prop !== "id") {
                            dataItem.set(prop, obj[prop]);
                        }
                    }
                } 
            });
            return kendoGrid;
        }

        kendoGrid.DeleteUI = function (idsToDelete = []) {
            idsToDelete.forEach(id => {
                let dataItem = kGrid.dataSource.get(id);
                if (dataItem)
                    kGrid.dataSource.remove(dataItem);
            });
            return kendoGrid;
        };

        kendoGrid.HasRows = function () {
            return kGrid.dataSource.data().length > 0;
        }

        return kendoGrid;
    }
  
}

It appears that UpdateUI does not function as it should.

When I test I notice that when the last remaining row of inner grid is deleted, the parent row's column is indeed updated to null, the No Records Found message is shown instead of the inner grid, the parent row gets collapsed, and when I expand it the inner grid is shown with the last remaining row.

Suprisingly, if I comment out the UpdateUI line, the inner grid's row gets deleted, without collapsing the inner grid and the No Records Found message is shown as intended (the parent row's column does not get updated in this case, obviously).

Is it a bug in Kendo ? or am I doing something wrong?

1 Answer, 1 is accepted

Sort by
0
Neli
Telerik team
answered on 13 Jun 2025, 07:47 AM

Hi,

It is really hard to be sure about the reason for the observed behavior, as in the provided snippet, there is quite a lot of custom implementation, and the code is not runnable. To be able to help appropriately, it would be very helpful if you could provide us with a runnable example that demonstrates the issue. This way, we could investigate locally and provide assistance. 

However, below you will find some suggestions on the things that you could check on your end:

  • Unexpected Collapse: The issue arises when the UpdateUI function is called, causing the parent row to collapse after updating the parent grid's column to null. This behavior suggests that the grid's data-binding mechanism might be reacting to the data update in a way that triggers the collapse.

Possible Solutions

  1. DataSource Synchronization: Ensure that the data source of the parent grid is correctly synchronized after the update. The collapse might be triggered by how the grid's data source handles changes.

  2. Avoid UI Triggers: Consider restructuring your UpdateUI logic to avoid triggering events that may cause the collapse. You could update the data directly in the data source without invoking methods that might lead to unintended UI updates.

  3. Manual Refresh: After updating the parent row, manually refresh the grid using the refresh() method to ensure that the UI reflects the changes correctly without collapsing.

  4. Conditional UI Update: Add a condition to prevent the collapse of the parent row. Check if the inner grid is empty before updating the parent row, and ensure the inner grid remains visible with the "No Records Found" message.

Code Adjustments

Here's a code snippet illustrating how to handle the manual refresh:

function delete(e) {
    let Loader = KENDO.KendoLoader($("body"));
    try {
        Loader.Show();
        let row = $(e).closest("tr");
        let grid = $(e).closest(".innerGrid");
       .....

        if (KENDO.KendoGrid(grid).HasRows() == false) {
            grid.hide();
            grid.siblings(".noRecordsFound").show();
            let updatedDataObj = {
                id: parentDataItem.id,
                someColumnOnParentRow: null
            };
            KENDO.KendoGrid($("#ParentGrid")).UpdateUI([updatedDataObj]);
            KENDO.KendoGrid($("#ParentGrid")).refresh(); // Refresh the parent grid
        }
    } catch (error) {
        console.log(error.message);
    } finally {
        Loader.Hide();
    }
}

The behavior you are experiencing is not necessarily a bug but could be related to how the data source updates are handled within the grid. By implementing the suggested solutions, you should be able to prevent the unexpected collapse of the parent row.

Regards,
Neli
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tags
Data Source Grid
Asked by
Y
Top achievements
Rank 1
Answers by
Neli
Telerik team
Share this question
or