Kendo Grid Binding With Custom Navigation

4 posts, 0 answers
  1. Steven
    Steven avatar
    11 posts
    Member since:
    Sep 2015

    Posted 17 May 2017 Link to this post

    We are facing an issue in telerik grid when we bind it using the .BindTo() and set the .ServerOperation(false).

    If we sort our grid or select the next page, it appears that the data source for the grid is still associated to the original data source and we lose the indexing in the grid.
    As our grid also requires keyboard navigation through the arrow keys (selecting the down arrow should select the next row in the grid and selecting the up arrow should go to the previous row), we wrote some custom JavaScript to achieve that. (We know we can achieve the navigation also through selecting down or up arrow and spacebar, but due to business needs we want it to be a one key operation).However, we cannot accomplish this after a sort or page as the data source still points to original data source before sort and the selection jumps to the next index in the original data source instead of the adjacent row.

    So our question is how to set the data source to point to the sorted data source?
    We did try re-reading the data source and refreshing it but that points it all back to the original data source and the grid loses all its sorting or paging as well.
    dataSource.read();
    dataSource.refresh();

    Here is the custom code we have in our JavaScript which is executed when a user clicks the arrow key to select the next row in the grid

    function nextRow() {
        var gridService = $(gridId).data("kendoGrid");
        if (gridService !== undefined) {
            var rowCount = gridService.dataSource.data().length;
            if (rowCount !== undefined) {
                var rows = gridService.items();
                var currSelRowIndex = rows.index(gridService.select());
                var nextRowIndex = rowCount - 1;
                if (currSelRowIndex < rowCount - 1) {
                    nextRowIndex = currSelRowIndex + 1;
                    selectServiceLineRow(nextRowIndex, true);
                }
               else {
                    nextRowIndex = 0;
                    var pageService = gridService.dataSource.page();
                    var pageSizeService = gridService.dataSource.pageSize();
                    if ((pageService) * pageSizeService < gridService.dataSource.total()) {
                        gridService.dataSource.page(pageService + 1);
                        selectServiceLineRow(nextRowIndex, true);
                    }
                }
            }
        }
    }

    function selectServiceLineRow(serviceLineRowIndex, withFocus) {
        var gridService = $(gridId).data("kendoGrid");
        var rowAt = gridService.dataSource.at(serviceLineRowIndex);
        var rowuid = rowAt.uid;
        var row = gridService.tbody.find("tr[data-uid='" + rowuid + "']");
        gridService.select(row);
        var cell = row.find('td:eq(0)');
        gridService.current(cell);
        if (withFocus) {
            cell.focus();
        }
        serviceLinesGridCalcPrevNextButton(serviceLineRowIndex);
    }


    The grid’s datasource is bined in cshtml like this.


                .DataSource(d => d
                    .Ajax()
                    .Events(e => e.Error("onWebApiError").Change("ResetGridScrollbar(\"#ServiceLinesGrid\")"))
                    //Remove .ServerOperation when paging is added
                    .ServerOperation(false)
                    .Model(m => m.Id(e => e.LineNumber)))
                .BindTo(Model.ServiceLines)
  2. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    2062 posts

    Posted 19 May 2017 Link to this post

    Hello Steven,

    As mentioned in the Server Binding article using he BindTo method will use server-binding mechanism of the grid. The Grid makes HTTP GET requests to the action method which initially renders the view. The Grid page, sort, filter, and group information is passed as query string parameters.

    With the server-binding approach the DataSource will not work as it works with ajax binding. In order to use ajax binding and bind the grid to a collection of items sent to the view I would suggest to take a look at the Grid / Binding to local data demo. 

    @model IEnumerable<Kendo.Mvc.Examples.Models.ProductViewModel>
     
    @(Html.Kendo().Grid(Model)
        .Name("Grid")
    ....

    Regards,
    Boyan Dimitrov
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Steven
    Steven avatar
    11 posts
    Member since:
    Sep 2015

    Posted 23 May 2017 in reply to Boyan Dimitrov Link to this post

    Even after removing the .BindTo and doing client side binding, the navigation on the grid by the up and down arrow keys does not work as expected. The code below still cannot find the next row in the grid. And the selection still looks at the original loaded grid data and not the grid data after a sort.

    function nextRow() {
        var gridService = $(gridId).data("kendoGrid");
        if (gridService !== undefined) {
            var rowCount = gridService.dataSource.data().length;
            if (rowCount !== undefined) {
                var rows = gridService.items();
                var currSelRowIndex = rows.index(gridService.select());
                var nextRowIndex = rowCount - 1;
                if (currSelRowIndex < rowCount - 1) {
                    nextRowIndex = currSelRowIndex + 1;
                    selectServiceLineRow(nextRowIndex, true);
                }
               else {
                    nextRowIndex = 0;
                    var pageService = gridService.dataSource.page();
                    var pageSizeService = gridService.dataSource.pageSize();
                    if ((pageService) * pageSizeService < gridService.dataSource.total()) {
                        gridService.dataSource.page(pageService + 1);
                        selectServiceLineRow(nextRowIndex, true);
                    }
                }
            }
        }
    }

    Any ideas why our navigation in accessing the row still does not work and points to the original loaded grid data when trying to determine the next row?

  4. Konstantin Dikov
    Admin
    Konstantin Dikov avatar
    2466 posts

    Posted 25 May 2017 Link to this post

    Hello Steven,

    If you are disabling server operations of the DataSource you will need to use the view method instead of the data method of the DataSource in order to get the data items from the current view (including the sort, filter, etc.): 
    var rowCount = gridService.dataSource.view().length;

    As for the navigation, please try to create a dojo example demonstrating your current implementation, so we could have a better idea of the exact scenario.


    Regards,
    Konstantin Dikov
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top