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

18 posts, 0 answers
  1. DJo
    DJo avatar
    23 posts
    Member since:
    Nov 2012

    Posted 04 Jul 2013 Link to this post

    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.
  2. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2285 posts

    Posted 05 Jul 2013 Link to this post

    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!
  3. Kendo UI is VS 2017 Ready
  4. DJo
    DJo avatar
    23 posts
    Member since:
    Nov 2012

    Posted 05 Jul 2013 Link to this post

    Ideal! Thank you for the quick and clear answer.
  5. Brandon
    Brandon avatar
    15 posts
    Member since:
    Sep 2012

    Posted 08 May 2014 Link to this post

    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?
  6. Brandon
    Brandon avatar
    15 posts
    Member since:
    Sep 2012

    Posted 08 May 2014 Link to this post

    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.
  7. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2285 posts

    Posted 10 May 2014 Link to this post

    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!
     
  8. Brandon
    Brandon avatar
    15 posts
    Member since:
    Sep 2012

    Posted 13 May 2014 in reply to Nikolay Rusev Link to this post

    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.
  9. Oscar
    Oscar avatar
    173 posts
    Member since:
    Oct 2010

    Posted 14 May 2014 Link to this post

    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.

  10. Brandon
    Brandon avatar
    15 posts
    Member since:
    Sep 2012

    Posted 14 May 2014 in reply to Oscar Link to this post

    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.

  11. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2285 posts

    Posted 15 May 2014 Link to this post

    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!
     
  12. Brandon
    Brandon avatar
    15 posts
    Member since:
    Sep 2012

    Posted 15 May 2014 in reply to Nikolay Rusev Link to this post

    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.

  13. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2285 posts

    Posted 16 May 2014 Link to this post

    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!
     
  14. Brandon
    Brandon avatar
    15 posts
    Member since:
    Sep 2012

    Posted 16 May 2014 in reply to Nikolay Rusev Link to this post

    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.
  15. Brandon
    Brandon avatar
    15 posts
    Member since:
    Sep 2012

    Posted 16 May 2014 Link to this post

    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.
  16. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2285 posts

    Posted 20 May 2014 Link to this post

    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!
     
  17. DaveJ
    DaveJ avatar
    9 posts
    Member since:
    Nov 2014

    Posted 07 Jan 2015 Link to this post

    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?
  18. Nikolay Rusev
    Admin
    Nikolay Rusev avatar
    2285 posts

    Posted 08 Jan 2015 Link to this post

    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!
     
  19. Combinations
    Combinations avatar
    14 posts
    Member since:
    Jun 2012

    Posted 29 Jan Link to this post

    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.});

Back to Top
Kendo UI is VS 2017 Ready