Changing grid template with virtual scroll enabled

8 posts, 0 answers
  1. Joel
    Joel avatar
    78 posts
    Member since:
    Oct 2012

    Posted 28 Dec 2011 Link to this post

    On change template in code, the repainting of the grid doesn't seem to expand and produce scrollbars to match the new height of the update grid display.

    Here's an example. To reproduce the issue, click on the 'Change Template' button:
    http://jsfiddle.net/65kWY/20/

    PS. Setting scrollable to true (non-virtual) works just fine.

  2. Joel
    Joel avatar
    78 posts
    Member since:
    Oct 2012

    Posted 30 Dec 2011 Link to this post

    Is there a way to get access to the VirtualScrollable object of the grid, once it's set up? I think calling the refresh method on that object would help me fix this issue.
  3. Kendo UI is VS 2017 Ready
  4. Dustin
    Dustin avatar
    6 posts
    Member since:
    Sep 2010

    Posted 25 Jun 2013 Link to this post

    I realize this is an old thread, but I'm having a very similar issue with a hierarchy. With the virtual scroll, when rows are expanded, they push things down but the scroll bar doesn't update.
  5. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 28 Jun 2013 Link to this post

    Hi Dustin,

     
    You should refresh the grid virtualScrollable object on each detail row collapse / expand: 

    grid = $("#grid").data("kendoGrid")
     
    //reset the cached rowHeight:
    grid._rowHeight = undefined;
    //refresh the virtualScrollable option
    grid.virtualScrollable.refresh();
    Kind Regards,
    Vladimir Iliev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Dustin
    Dustin avatar
    6 posts
    Member since:
    Sep 2010

    Posted 28 Jun 2013 Link to this post

    Okay, I added your code to the detailExpand and detailCollapse events, but it appears to be working backwards. When I expand the last row in the grid, the details expand under the end of the grid and the scrollbar doesn't move, when I collapse, the event fires off before the actual collapse, so the scroll bar gets bigger, but there is nothing to scroll down to now. Then when I expand again, the even fires before the actual details come out, so the scroll bar shrinks back down, is there an event that happens after expand and after collapse?

    EDIT: Also, I just noticed on a grid with a lot of data, if I virtual scroll to the bottom, then click to expand the bottom row, it jumps my position up about 100 rows and when your scroll to a new "page" it closes all your expanded items.
    <div id="grid"></div>
     
        <script type="text/javascript">
     
            function getHeight() {
                return $(window).height() - 100 - $('.CustomHeader').height();
            }
     
     
            function resizeVirtualScroll() {
     
                grid = $("#grid").data("kendoGrid");
     
                //reset the cached rowHeight:
                grid._rowHeight = undefined;
                //refresh the virtualScrollable option
                grid.virtualScrollable.refresh();
     
            }
     
     
            // setup grid
            $(document).ready(function() {
     
                $("#grid").kendoGrid({
                    dataSource: aumData,
                    navigatable: true,
                    selectable: 'row',
                    filterable: true,
                    sortable: true,
                    resizable: true,
                    scrollable: { virtual: true },
                    detailInit: acctDetailInit,
                    height: getHeight(),
                    detailExpand: function() { resizeVirtualScroll(); },
                    detailCollapse: function () { resizeVirtualScroll(); },
                    columns: [
                        { field: "id", filterable: false, width: 65, },
                        { field: "name", title: "Name" },
                        { field: "aum", title: "Current Value", format: "{0:C}", attributes: { style: "text-align:right;" } }
                    ]
                });
            });
     
            // datasource
            var aumData = new kendo.data.DataSource({
                pageSize: 100,
                sort: { field: "name", dir: "asc" },
                transport: {
                    read: {
                        url: '<%= Common.GetAppSetting( "WebApiBaseUrl" ) %>Portfolio/Clients/Value',
                        dataType: "json",
                        beforeSend: function(req) {
                            req.setRequestHeader("Authorization", "Session <%= Common.WebApiToken %>");
                        }
                    }
                },
                schema: {
                    model: {
                        fields: {
                            id: { type: "number" },
                            name: { type: "string" },
                            value: { type: "number" }
                        }
                    }
                },
                errors: function(e) {
                    console.log(e.errors);
                }
            });
     
            // detail grid and datasource
            function acctDetailInit(e) {
                $("<div/>").appendTo(e.detailCell).kendoGrid({
                    dataSource: {
                        transport: {
                            read: {
                                url: '<%= Common.GetAppSetting( "WebApiBaseUrl" ) %>Portfolio/Clients/' + e.data.id + '/Accounts/Value',
                                dataType: "json",
                                beforeSend: function(req) {
                                    req.setRequestHeader("Authorization", "Session <%= Common.WebApiToken %>");
                                }
                            }
                        }
                    },
                    detailExpand: function(e) {
                        console.log(e.masterRow, e.detailRow);
                         
                    },
                    navigatable: true,
                    selectable: 'row',
                    filterable: true,
                    sortable: true,
                    scrollable: false,
                    resizable: true,
                    columns: [
                        { field: "id", filterable: false, width: 65, },
                        { field: "name", title: "Account" },
                        { field: "aum", title: "Current Value", format: "{0:C}", attributes: { style: "text-align:right;" } }
                    ]
                });
            }
  7. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 03 Jul 2013 Link to this post

    Hi Dustin,

     
    Basically the solution that I provide with my previous reply is a custom one and you can use it as a baseline to achieve the desired behavior. In current case you can use for example the setTimeout method to execute the provided code after the current expand / collapse is fully completed. 

    Kind Regards,
    Vladimir Iliev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  8. Dustin
    Dustin avatar
    6 posts
    Member since:
    Sep 2010

    Posted 03 Jul 2013 Link to this post

    I would try the setTimeout as a workaround, but depending on the user, the amount of data coming back can be greatly different and take longer. I would hate to have to put a huge delay, which in the end may not be long enough at times.

    I wrote a custom solution on my own, which I thought would work, but when I expand enough items (in my scenerio about 3000px of expanded detail grids) then scroll down, my Chrome browser would throw an error and need to refresh the page.

    This code stores the height of the detail grid the first time it is loaded and since the event on dataBound is after it is expanded, the virtual scrollbar height can be changed right then. On subsequent expands, since the detailExpand event fires off before the detail grid has its height, I had to use the stored height from the first expansion.

    So this code almost works other than Chrome dying on me after large amounts are expanded.
    //resize logic
               $(window).trigger(
    'resize');
     
            function getHeight() {
                return $(window).height() - 100 - $('.CustomHeader').height();
            }
     
            function resizeGrid(args) {
                $('#grid').height(getHeight());
                var gridElement = $("#grid"),
                    dataArea = gridElement.find(".k-grid-content:first"),
                    gridHeight = gridElement.innerHeight(),
                    otherElements = gridElement.children().not(".k-grid-content:first"),
                    otherElementsHeight = 0;
     
                otherElements.each(function () {
                    otherElementsHeight += $(this).outerHeight();
                    });
                dataArea.height(gridHeight - otherElementsHeight);
                return args;
            }
     
            $(window).resize(function() {
                resizeGrid();
            });
     
            function resizeVirtualScroll(firstTime, expand) {
                var grid = $("#grid").data("kendoGrid");
     
                // on initial load this will fire off and be null
                if (grid == null) return;
                 
                // when expanding for first time, the expand event will kick off then the databound
                if ($(grid.select()).attr("data-height") == null && !firstTime) return;
     
                var detailHeight = 0;
                var newHeight = $(".k-grid-content div table").height();
                console.log("grid height:" + newHeight);
                 
                if (firstTime) {
                    detailHeight = $(grid.select()).next(".k-detail-row").children(":first").height();
                    console.log("detail height:" + detailHeight);
                    $(grid.select()).attr("data-height", detailHeight);
                     
                } else {
                    //get selected row data height
                    detailHeight = parseFloat($(grid.select()).attr("data-height"));
                    console.log("detail height:" + detailHeight);
                     
                    if (expand) {
                        newHeight += detailHeight;
                    } else {
                        newHeight -= detailHeight;
                    }
                }
                 
                console.log("final height:" + newHeight);
     
                var bar = $(".k-scrollbar.k-scrollbar-vertical div");
                bar.height(newHeight);
            }
     
     
            // setup grid
            $(document).ready(function() {
     
                $("#grid").kendoGrid({
                    dataSource: aumData,
                    navigatable: true,
                    selectable: 'row',
                    filterable: true,
                    sortable: true,
                    resizable: true,
                    scrollable: { virtual: true },
                    dataBound: resizeGrid,
                    detailInit: acctDetailInit,
                    height: getHeight(),
                    detailExpand: function() { resizeVirtualScroll(false, true); },
                    detailCollapse: function () { resizeVirtualScroll(false, false); },
                    columns: [
                        { field: "id", filterable: false, width: 65, },
                        { field: "name", title: "Name" },
                        {
                            field: "aum", title: "Current Value", format: "{0:C}", attributes: { style: "text-align:right;" }, width: 120,
                            headerAttributes: {
                                style: "text-align: right;"
                            }
                        }
                    ]
                });
            });
     
            // datasource
            var aumData = new kendo.data.DataSource({
                pageSize: 300,
                sort: { field: "name", dir: "asc" },
                transport: {
                    read: {
                        url: '<%= Common.GetAppSetting( "WebApiBaseUrl" ) %>Portfolio/Clients/Value?usedOnly=1',
                        dataType: "json",
                        beforeSend: function(req) {
                            req.setRequestHeader("Authorization", "Session <%= Common.WebApiToken %>");
                        }
                    }
                },
                schema: {
                    model: {
                        fields: {
                            id: { type: "number" },
                            name: { type: "string" },
                            value: { type: "number" }
                        }
                    }
                },
                errors: function(e) {
                    console.log(e.errors);
                }
            });
     
            // account level detail grid
            function acctDetailInit(e) {
                $("<div/>").appendTo(e.detailCell).kendoGrid({
                    dataSource: {
                        sort: { field: "name", dir: "asc" },
                        transport: {
                            read: {
                                url: '<%= Common.GetAppSetting( "WebApiBaseUrl" ) %>Portfolio/Clients/' + e.data.id + '/Accounts/Value?usedOnly=1',
                                dataType: "json",
                                beforeSend: function(req) {
                                    req.setRequestHeader("Authorization", "Session <%= Common.WebApiToken %>");
                                }
                            }
                        }
                    },
                    detailExpand: function(e) {
                        console.log(e.masterRow, e.detailRow);
                         
                    },
                    navigatable: true,
                    selectable: 'row',
                    filterable: true,
                    sortable: true,
                    scrollable: false,
                    dataBound: function(e) {
                        resizeVirtualScroll(true, true);
                    },
                    resizable: true,
                    columns: [
                        { field: "id", filterable: false, width: 65, },
                        { field: "name", title: "Account" },
                        { field: "number", title: "Account #" },
                        { field: "managementStyle", title: "Management Style" },
                        {
                            field: "value", title: "Current Value", format: "{0:C}", attributes: { style: "text-align:right;" }, width: 120,
                            headerAttributes: {
                                style: "text-align: right;"
                            }
                        }
                    ]
                });
            }
  9. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2172 posts

    Posted 08 Jul 2013 Link to this post

    Hi Dustin,

     
    Please note that supporting custom solutions is out-of-scope of our support service as it covers the build-in functionality of the controls only. If you'd like to receive custom code from Telerik, I would suggest to check our premium services.

    Kind Regards,
    Vladimir Iliev
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Back to Top
Kendo UI is VS 2017 Ready