5
votes

I'm trying to populate a KendoUI grid with JSON data where the server returns the total number of rows along with the data, but I'm having some trouble getting serverPaging to work properly. I create and assign the dataSource of the grid as follows:

                var oDS = new kendo.data.DataSource({
                    schema: {
                        data:  "data",
                        total: "total"
                    },
                    data: self.grdTableData,
                    serverPaging: true,
                    pageSise: 50,
                    total: joOutput["TotalRecords"]
                });

                grdTableResults.setDataSource(oDS);

and the first page shows the first 50 of 939 records but there is only ever 1 page (the navigation arrows never respond to anything) and I see NaN - NaN of 939 items and the rotating circle of dots in the centre of the grid that never goes away.

One thing that is different in all the examples I've looked at is that my $.ajax call and the the processing of the JSON data in .done doesn't use "transport: read" but I'm thinking how I send the data and get it back shouldn't matter (or does it because every page request is a new server read?). But I don't think I'm doing enough to handle the server paging properly even though it seems I'm setting data source values similar to those set in the example at http://jsfiddle.net/rusev/Lnkug/. Then there's the "take" and "skip" values that I'm not sure about, but I do have "startIndex" and "rowsPerPage" that I'm sending to the server that can be used there. I assume the grid can tell me what page I'm on show I can set my "startIndex" appropriately and if I have an Items per Page" drop down I can reset my "rowsPerPage" value?

Anyway, sorry for all the newbie questions. Any help and suggestions is genuinely appreciated. Thanks!

2
There are few questions that I do not understand: You mention server paging but it actually seems to me that your data comes from a JavaScript array called self.grdTableData if so, it doesn't make sense saying serverPaging, this is for remote servers. - OnaBai
There is a typo error in pageSize where you wrote pageSise, is it also in the code? - OnaBai
Why do you define a schema? It doesn't seem that you need it keeping in mind the actual definition. - OnaBai
While the client and the server are the same machine now for testing purposes, eventually the server will be remote. Perhaps I'm not understanding if serverPaging is really necessary--the data is still a JavaScript array no matter where it comes from. I guess I'm just needing a mechanism to read blocks of data so that I can read and page data data more efficiently that having potentially thousands of rows of data. - user2030159
That was indeed a typo, which got rid of the rotating circles and now I see multple page numbers and 1 - 50 of 939 items instead of NaN - NaN of 939 items, but still no response from clicking on any numbers or arrows. Thanks for caching that. - user2030159

2 Answers

7
votes

transport: read

You should be able to use "transport: read" even if you have custom logic by setting the value to a function. I have created a JS Fiddle to demonstrate this functionality.

dataSource: {
    serverPaging: true,
    schema: {
        data: "data",
        total: "total"
    },
    pageSize: 10,
    transport: {
        read: function(options) {
            var data = getData(options.data.page);
            options.success(data);
        }
    },
    update: function() {}
}

Your read function contains a parameter that contains the following paging properties: page, pageSize, skip, take. Keep in mind that all transport operations need to be functions if one operation contains a function.

startIndex and rowsPerPage

If your server accepts these parameters, you should be able to submit them in the read function. Create a new ajax call that post customized data

var ajaxPostData = { startIndex: options.data.skip, rowsPerPage: options.data.pageSize }
2
votes

This is the code for server side wrapper that I'm using to implement server paging with kendo grid:

@(Html.Kendo().Grid<IJRayka.Core.Utility.ViewModels.ProductDto>()
.Name("productList")
.Columns(columns =>
{
    columns.Bound(prod => prod.Name);
    columns.Bound(ord => ord.Brand);
    columns.Bound(ord => ord.UnitPackageOption);
    columns.Bound(ord => ord.CategoryName);
    columns.Bound(ord => ord.Description);
})
.Pageable(pager => pager.PageSizes(true))
.Selectable(selectable => selectable.Mode(GridSelectionMode.Multiple))
.PrefixUrlParameters(false)
.DataSource(ds => ds.Ajax()
            .Model(m => m.Id(ord => ord.ID))
            .PageSize(5)
            .Read(read => read
                .Action("FilterProductsJson", "ProductManagement")
                .Data("getFilters"))
            )
)

Where getFilters is a javascript function that passes my custom filter parameters to the grid when it wants to get data from url/service:

function getFilters() {
    return {
        brand: $("#Brand").val(),
        name: $("#Name").val(),
        category: $("#CategoryName").val()
    };
}

In addition you should implement your controller's action method using kendo's DataSourceRequest class like below, or otherwise it won't work the way you want:

public JsonResult FilterProductsJson([DataSourceRequest()] DataSourceRequest request,
                                // three additional paramerters for my custom filtering
                                string brand, string name, string category)
{
    int top = request.PageSize;
    int skip = (request.Page - 1) * top;
    if(brand != null)
        brand = brand.Trim();
    if(name != null)
        name = name.Trim();
    if(category != null)
        category = category.Trim();

    var searchResult = new ManageProductBiz().GetPagedFilteredProducts(brand, name, category, top, skip);
    // remove cyclic references:
    searchResult.Items.ForEach(prd => prd.Category.Products = null);

    return Json(new DataSourceResult { Data = searchResult.Items, Total = searchResult.TotalCount }, JsonRequestBehavior.AllowGet);
}