This is a migrated thread and some comments may be shown as answers.

DataItem set collapses detail row (annoying): how to expand it?

17 Answers 1542 Views
Grid
This is a migrated thread and some comments may be shown as answers.
DJo
Top achievements
Rank 1
DJo asked on 04 Jul 2013, 09:07 PM
I have a grid with detail rows. When I set the dataItem of a master row it causes it to collapse.

Is there a way to prevent the collapse on setting the master row dataItem? This seems like bad default behaviour.

Also: I can't seem to expand it again:
var parentRow = $(input).closest('.k-detail-row').prev('.k-master-row')[0];
var parentGrid = $(parentRow).closest('div.k-grid').data("kendoGrid");
var parentDataItem = parentGrid.dataItem($(parentRow).closest('tr'));
parentDataItem.set("QTY", newParent.QTY);
parentGrid.expandRow(parentRow);
The expandRow function isn't accepting the parentRow as an argument.

17 Answers, 1 is accepted

Sort by
0
Nikolay Rusev
Telerik team
answered on 05 Jul 2013, 06:55 AM
Hello David,

Calling set method of the ObservableObject will trigger change event that will bubble up to the DataSource and the Grid will repaint in order to show the changes.

That said the reference to the row you keep (in the code snippet) is to the old DOM element before the refresh. This is why the expand does not work - as the element is no longer in the DOM tree.

To workaround you can keep the index of the item before calling set and before calling expand to get DOM element for that index.

Regards,
Nikolay Rusev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
DJo
Top achievements
Rank 1
answered on 05 Jul 2013, 04:27 PM
Ideal! Thank you for the quick and clear answer.
0
Brandon
Top achievements
Rank 1
answered on 08 May 2014, 09:41 PM
Has there been any change in this behavior since this thread was created?

I have a grid where the detail expansion is being used as an edit view for the row, so that multiple rows can be expanded and compared/edited simultaneously.

However, as detailed above, when I save the changes back to the server and then attempt to update the local dataItem (since detail views are not bound to the viewmodel, I have to manually update the client side data), *all* detail views collapse despite only one rows' data being updated at a time. It makes sense that the row being edited should collapse as the user is finished with their changes to that row, but the entire grid is being redrawn when any data change is made.

Is there any way to prevent this?
0
Brandon
Top achievements
Rank 1
answered on 08 May 2014, 09:49 PM
In addition (I cannot edit my previous post for some reason), the other detail views lose all their changes when they are unnecessarily collapsed, again, since I cannot save the data back to the viewmodel without it collapsing the detail views.
0
Nikolay Rusev
Telerik team
answered on 10 May 2014, 07:38 AM
Hello Brandon,

This behavior is fundamental for how the Grid widget works and there aren't any changes. You can control this behavior by not updating the data item directly on every change from the UI, but rather on click of some global save button.

Regards,
Nikolay Rusev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Brandon
Top achievements
Rank 1
answered on 13 May 2014, 02:57 PM
I'm not saving changes to the dataItem after every UI change.

Each row and it's detail expansion is treated as it's own entity, and is managed individually. The changes are saved on a per-row basis. The issue here is that the dataSource is triggering the grid to refresh/read all data instead of the row that was modified.

This is counter-intuitive. You can edit/add/delete/template/select/expand a row but you can't update a row. You can only update the data source.
0
Oscar
Top achievements
Rank 1
answered on 14 May 2014, 02:04 PM
This is an old unresolved thread.

In this link, Editable fields in grid details you can find more information about editing the dataItem fields of a grid in detailRow with no success. When you update the originalModel of a row, the grid collapses all the expanded detailRows and this  makes losing the data entered by the user in other detailRows.
Alexander told me that "this is by desing".
Hope this helps.

Oscar.

0
Brandon
Top achievements
Rank 1
answered on 14 May 2014, 02:48 PM
Well, I'm glad I'm not the only one attempting to do this, but I am disappointed that no one has a workaround.

Quite simply, when you have as much data to display as I do (64 data points by my last count), the built in edit modes are insufficient. We supply an "at a glance" view of the most useful data points in the grid itself and use the detail expansion to provide a form-like editor where multiple rows can be expanded at once.

Using inline or batch would just be insane. No one is going to deal with a 64 column grid.
Popup would be OK if we could popup multiple rows for comparison/copying, but it still wouldn't solve the issue that I am having saving data on a per-row basis and losing the work on other expanded rows that may or may not actually need to be saved.

0
Nikolay Rusev
Telerik team
answered on 15 May 2014, 07:33 AM
Hello,

In such scenarios you basically have two options:
 - e.preventDefault() inside grid dataBinding handler - this will prevent grid repaint
 or 
 - collect expanded rows indices on dataBinding event, and expand them back on dataBound event. 

Regards,
Nikolay Rusev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Brandon
Top achievements
Rank 1
answered on 15 May 2014, 03:15 PM
Thanks for the reply Nikolay,

We are getting somewhere now. The e.preventDefault sounds promising.

If we can prevent the grid repaint, I should only need two more things to get to my intended behavior.

1. A way to detect what triggered the dataBind event so I can differentiate a dataSource read from a local data update. This would let filtering/paging/sorting through properly, but stop it from happening when I'm refreshing the data on my own.
2. A way to refresh the front end grid cells manually.

0
Nikolay Rusev
Telerik team
answered on 16 May 2014, 11:25 AM
Hello Brandon,

You can assert against the `action` argument what action has happened. For example `itemchange` will be triggered when you modify model field via set method.
dataBinding: function(e) {
 if (e.action == "itemchange") {
  console.log(e.items);
 }
}


Regards,
Nikolay Rusev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Brandon
Top achievements
Rank 1
answered on 16 May 2014, 07:21 PM
Thanks to your help, Nikolay, I now have a workable solution in place:

Here is the source code for my grid's dataBinding handler:

dataBinding: function (e) {
    if (e.action == "itemchange") {
        e.preventDefault();
 
        var item = e.items[0];
 
        //get the current column names, in their current order
        var grid = $('#' + currentViewModel.gridId).data('kendoGrid');
        var columns = grid.columns;
        var columnNames = $.map(columns, function (column) {
            return column.field;
        });
 
        //get the column tds for update
        var masterRow = $('#' + currentViewModel.gridId + ' > div.k-grid-content > table > tbody > tr[data-uid="' + item.uid + '"]');
        var tds = masterRow.find('td:not(.k-hierarchy-cell)');
 
        //collapse the detail row that was saved.
        grid.collapseRow(masterRow);
 
        //update the tds with the value from the current item stored in items
        for (var i = 0 ; i < tds.length ; i++) {
            $(tds[i]).html(item[columnNames[i]]);
        }
    }
}

It's not perfect, but the general idea is to get the current state of the columns, since I have column customizations enabled, find the master row tds by using the uid of the items[0] object, then set the tds value to the items current state.

I also collapse the row here, but this isn't necessary, and would actually work better for the OP.

I still need to run certain columns through formatters and templates, but that's small potatoes compared to getting this far.
0
Brandon
Top achievements
Rank 1
answered on 16 May 2014, 07:27 PM
Also, I would also like to point out that neither e.items or e.action is documented as part of the Kendo UI Grid dataBinding event documentation.

http://docs.telerik.com/kendo-ui/api/web/grid#events-dataBinding

These two fields were instrumental in getting a workable solution. They really should be added there for others' future reference.
0
Nikolay Rusev
Telerik team
answered on 20 May 2014, 03:22 PM
Hello Brandon,

We will definitely update the docs in order to address the missing parts.

We are also open for contribution on our documentation portal. You can find more details here: Update the Documentation at GitHub.

Regards,
Nikolay Rusev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
DaveJ
Top achievements
Rank 1
answered on 07 Jan 2015, 07:26 AM
Sorry to reopen an old post, but unfortunately I found a side effect to using e.preventDefault(), and I'm hoping to get a resolution to it.

If I use e.preventDefault(), then the grid does not repaint, which is good. However, I'm encountering a problem using these series of steps (on a two level grid - a master grid and a detail grid):

1. Expand master grid
2. Edit an item in the child grid (works well - the grid does not repaint)
3. Change the filter on the dataSource, while will cause the grid to repaint (as expected)
4. After the repaint, try to expand the master grid again <--- PROBLEM IS HERE

Basically, when doing Step 4, the grid will "expand", but in reality it will just show an empty child grid container. The child grid will not actually render. I've narrowed this down to being caused by using e.preventDefault() on the dataBinding event. This ONLY happens when repainting the grid (such as by filtering, as above) after editing a cell. In addition, if after the filtering, I edit one of the master rows, and THEN expand the master grid, then it works. Or, I can also try to expand a different master row after the initial failure, and this will work too. 

So, the problem is in the FIRST expand event after the dataSource is refreshed and the grid is repainted. Subsequent expansions, or just editing a cell before trying the first expand, fixes the issue. Do you guys have any suggestions as to how to resolve this issue?
0
Nikolay Rusev
Telerik team
answered on 08 Jan 2015, 12:30 PM

Hello Yaron,

 

e.preventDefault() on dataBinding event will not render any data in the Grid. This is expected. However I'm not sure about implementation. Thus I'll suggest you opening separate forum thread/support ticket and attach some example of your implementation. 

 

Regards,
Nikolay Rusev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Combinations
Top achievements
Rank 1
answered on 29 Jan 2016, 01:16 PM

I have also had similar problems with nested grids when using the checkbox-column solution proposed by Telerik (http://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/Templates/grid-with-checkbox-column).

I solved it by triggering a click on the "edit-cell's" checkbox instead of using dataItem.set():

01.$("#grid .k-grid-content").on("change", "input.chkbx", function (e) {
02.    // Get the parent grid of the checkbox. This can either be the master grid or the detail grid.
03.    var parentGrid = $(e.target).closest('div[data-role="grid"]').data("kendoGrid");
04.    // Get the clicked cell.
05.    var td = $(e.target).closest("td");
06.    // Enter the cell's edit mode.
07.    parentGrid.editCell(td);
08.    // Find the checkbox in the cell (which now is in "edit-mode").
09.    var checkbox = td.children("input[type=checkbox]");
10.    // Trigger a click (which will toggle check/uncheck).
11.    checkbox.trigger("click");
12.});

Tags
Grid
Asked by
DJo
Top achievements
Rank 1
Answers by
Nikolay Rusev
Telerik team
DJo
Top achievements
Rank 1
Brandon
Top achievements
Rank 1
Oscar
Top achievements
Rank 1
DaveJ
Top achievements
Rank 1
Combinations
Top achievements
Rank 1
Share this question
or