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

Kendo Grid Binding With Custom Navigation

3 Answers 217 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Steven
Top achievements
Rank 1
Steven asked on 17 May 2017, 07:14 PM
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)

3 Answers, 1 is accepted

Sort by
0
Boyan Dimitrov
Telerik team
answered on 19 May 2017, 01:03 PM

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.
0
Steven
Top achievements
Rank 1
answered on 23 May 2017, 09:14 PM

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?

0
Konstantin Dikov
Telerik team
answered on 25 May 2017, 08:11 AM
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.
Tags
Grid
Asked by
Steven
Top achievements
Rank 1
Answers by
Boyan Dimitrov
Telerik team
Steven
Top achievements
Rank 1
Konstantin Dikov
Telerik team
Share this question
or