Change value in parent row, traverse detail table applying change, then gather results and apply to parent row

1 Answer 180 Views
Grid
Keith
Top achievements
Rank 1
Iron
Iron
Keith asked on 19 Sep 2023, 09:47 PM | edited on 19 Sep 2023, 10:02 PM

So we have a need that in a parent row we change a value (a percentage) and then take that new value and potentially apply to rows in detail table.  Once that is all complete need to take results from the applying the percentage to details rows and update another value in the parent row,.

Basically Parent has a discount percentage. Change the value from say 10% to 20%.

Now go row by row in detail table and potentially discount the price of the each row if they meet a criteria.

I have this working already. At the end do a detailGrid.datasource.sync() and looks good.

Next need to go through the detail table and grab all the changed prices and total them up and put in the parent row total column.

I keep the total during the updating of the detail rows.

Thought doing a parentRowModel.set("Total",newTotal) and then parentGrid.datasource.sync() would do it, but no luck.

Also at the very end we dont want the parentGrid.datasource.sync() to close the detail table. Want it to remain expanded.

 

What I think is happening is the parentGrid.datasource.sync() is causing the detail table to be restored to original value.

Expect:

User changes parent.

Code changes all of the detail rows that meet a criteria
Code syncs detailGrid to update the UI 
Code syncs the parentGrid to update the parent row changed from calculations
User reviews the changes and manually saves to push changes back to database.
User needs to be able to make changes to multiple parents and details before committing change to database.

1 Answer, 1 is accepted

Sort by
0
Ivan Danchev
Telerik team
answered on 22 Sep 2023, 12:24 PM

Hello Keith,

This requirement: "User needs to be able to make changes to multiple parents and details before committing change to database." is not really viable, because of 2 reasons:

1. Parent and child grids are independent from one another. They have their own dataSources. You can think of the parent row as a container, in which a nested Grid is displayed.

2. Syncing changes results in rebinding and re-rendering of the respective Grid. This means that every time you have a change in the data of the Grid, if you call its .dataSource.sync() method, it will send a request to the server with the changed record/-s and when the response to that request is received back on the client, the Grid will rebind (its dataBound event will fire) and it will re-render. This is the reason you notice the detail row collapsing after a .dataSource.sync() call. Since the Grid is re-rendered, this means that you now have a new instance of the detail Grid in the row (as if you've just initialized the parent Grid).

These specifics mean that, if you want a parent Grid to show the latest data in the nested Grids, those nested Grids must have already been updated and their data must have been synced and saved in the database. The parent Grid's .dataSource.sync() call must be made afterwards, so that it can request the latest data. Otherwise it will show old data, because the parent Grid is not aware of changes in the nested Grids. It re-binds and re-renders after a .dataSource.sync(), so if the changes in the detail Grids have not been reflected in the database, the parent will simply request the current data available in the database.

As for the Total field in the parent Grid. On setting it with the set() method and calling .dataSource.sync(), the Grid should send a request to the specified Update action with the new value of the Total field. The Update action should persist the new value in the database, otherwise, on subsequent request of data, the Grid will once again show the current value available in the database, i.e. if it hasn't been updated, the old value will be displayed.

In summary, changes in the rows of the respective Grids (parent or detail) should be persisted in the database whenever they are made. There is no built-in functionality that allows saving multiple changes across different Grids at once. There is Batch editing, which allows saving multiple changes in the records of a single Grid: https://demos.telerik.com/aspnet-core/grid/editing This does not include changes in nested detail Grids. As mentioned above, they are independent from their parent Grid.

If you are syncing changes in a detail Grid and want to sync the parent, this must be done after the detail Grid has been synced. Consider calling the parent's  .dataSource.sync() method in the the RequestEnd event of the nested Grid's DataSource. This event will fire when the request sent by the detail Grid has finished: https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/events/requestend

Regards,
Ivan Danchev
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages. If you're new to the Telerik family, be sure to check out our getting started resources, as well as the only REPL playground for creating, saving, running, and sharing server-side code.

Keith
Top achievements
Rank 1
Iron
Iron
commented on 22 Sep 2023, 01:26 PM | edited

Maybe my question wasnt clear. So to clear a couple things up.

I was under impression I needed to call Sync to update the UI. Wasnt doing it to send to backend. 

After much trial and error I have achieved what I wanted. I did this yesterday evening after a few days of trial and error. Have I come up with the best solution? I dont know.

Number one thing that would have helped would be guidance and examples of traversing the heirarchy of grids with Javascript on the client.  I suggest Telerik put together a FAQ or something to move around grids with Javascript. Start at a parent row then visit all the child rows, maybe even grandchild rows. Inspect and change data. Then the reverse start at a child and move around siblings and move up to parent and its siblings and maybe even the childs grandparents.  

I was able to achieve changing one parent and all its children change then move to another parent and make changes to all its children.  The reverse is my next task to accomplish. If a user changes a child then the parent needs to rollup the changes. I havent put in any effort to save the results yet.

Ivan Danchev
Telerik team
commented on 27 Sep 2023, 10:05 AM

Keith,

The sync() method makes a call to the backend. The Grid has another API method - refresh() that refreshes it with the current data items, without making a call to the backend: https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/methods/refresh

With regard to traversing the records of a parent and child Grids, or traversing a multi-level hierarchy of Grids, then programmatically changing some of the records based on a condition/-s, this is a matter of specific use cases and custom logic.

What the available API provides is a data() method of the DataSource: https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/data This method returns the data items (records data) that are currently loaded in the Grid. Calling the parent Grid's dataSource data() method returns the data items in the parent Grid's data. Calling a specific child Grid's dataSource data() method will return that child Grid's data items, etc.

A parent row's dataItem can be accessed from a child Grid's events, for example here's how to get it in the child Grid's dataBound event:

function dataBoundChild(e) {
    var childGridElement = e.sender.wrapper; 
    var parentGrid = $("#grid").data("kendoGrid");
    var parentRowDataItem = parentGrid.dataItem(childGridElement.parents("tr").prev())
    console.log(parentRowDataItem);
}

 

Tags
Grid
Asked by
Keith
Top achievements
Rank 1
Iron
Iron
Answers by
Ivan Danchev
Telerik team
Share this question
or