I need to implement server side pagination in Angular-Kendo grid. I couldn't get a clear understanding on how to do that from Angular side.
Could anyone please help?
kendo:grid-pageable-messagesThe text messages displayed in pager. Use this option to customize or localize the pager messages.
Solution. Calculate the number of rows that will fit in the available space by subscribing to the resize event of the window element. Change the pageSize by using the pageSize method of the dataSource.
You can get page number by calling function page() on the dataSource object in kendo grid you have, and page size by calling function pageSize() of that object.
With the newest version of Kendo UI out (in Beta right now) there is another way we can implement server side paging, using the $http.post
method Angular provides with the Kendo Grid read function.
This is an example using a MVC 5 controller as your endpoint for the data you get from the data source. It simulates server paging by sending the page
and pageSize
to the controller, you could also send the take
and skip
if needed and handle it however you like.
HTML Markup
<div ng-controller="MyCtrl">
<kendo-grid k-options="mainGridOptions"></kendo-grid>
</div>
JavaScript
function MyCtrl($scope, $http) {
$scope.mainGridOptions = {
dataSource: {
schema: {
data: "Data",
total: "Total"
},
transport: {
read: function (e) {//You can get the current page, pageSize etc off `e`.
var requestData = {
page: e.data.page,
pageSize: e.data.pageSize,
type: "hello"
};
console.log(e);
$http({ method: 'POST', url: 'Home/DataSourceResult', data: requestData }).
success(function (data, status, headers, config) {
e.success(data);
//console.log(data.Data);
}).
error(function (data, status, headers, config) {
alert('something went wrong');
console.log(status);
});
}
},
pageSize: 1,
serverPaging: true,
serverSorting: true
},
selectable: "row",
pageable: true,
sortable: true,
groupable: true
}
}
You can get the current pageSize, page, take, skip and a lot more off of the argument e
in the read: function(e){}
declaration.
Because the post values reference the arguments from the read function, they update every time the page is updated on the grid. This is what you can use to update your post values every time the grid makes a change. The grid then re-binds itself.
Home/DataSourceResult Controller
[HttpPost]
public ActionResult DataSourceResult(int page, string type, int pageSize)
{
ResponseData resultData = new ResponseData();
string tempData = "";
if (page == 1)
{
tempData = "[{\"NAME\": \"Example Name 1\", \"DESCRIPTION\": \"Example Description 1\"},{\"NAME\": \"Example Name 2\",\"DESCRIPTION\": null}]";
}
else if (page == 2)
{
tempData = "[{\"NAME\": \"Example Name 3\", \"DESCRIPTION\": \"Example Description 3\"},{\"NAME\": \"Example Name 4\",\"DESCRIPTION\": \"Example Description 4\"}]";
}
resultData.Data = tempData;
resultData.Total = "4";
string json = JsonConvert.SerializeObject(resultData);
json = json.Replace(@"\", "");
json = json.Replace("\"[{", "[{");
json = json.Replace("}]\"", "}]");
return Content(json, "application/json");
}
Very basic, but exactly what I needed, and may help you as well. This uses the native Angular http.get
functionality while still allowing the Kendo Grid to do most of your heavy lifting.
The Kendo grid intrinsically supports server side paging, at least it has a handy built in API to help out there, so you just need to hook all the pieces together. Here's what I came up with, my grid's datasource:
$scope.myGrid.dataSource = new kendo.data.DataSource({
transport:{
read:{
url: '/api/mygridapi?orderId=113',
dataType: 'json'
}
},
pageSize: 5,
serverPaging: true,
serverSorting: true,
serverFiltering: true,
serverGrouping: true,
serverAggregates: true,
schema:{
total: function(response) {
return 13; // call some function, or some scope variable that know the total items count
},
model: {
id: "id",
fields: {
'id': { type: "number", editable: false },
'name': { type: "string", editable: true, nullable: false, validation: { required: true } },
'price': { type: "number", editable: true, nullable: false, validation: { required: true } },
}
}
}
});
and my grid markup:
<div kendo-grid k-pageable='{ "pageSize": 5, "refresh": true, "pageSizes": false }'
k-height="'250px'" k-column-menu="false" k-filterable="true" k-sortable="true" k-groupable="true"
k-data-source="myGrid.dataSource" k-options="{{myGrid.gridOpts}}" k-on-change="onSelectHandler(kendoEvent)">
and my web api controller:
[System.Web.Http.HttpGet]
public IEnumerable<ProductsDTO> Get(int orderId)
{
NameValueCollection nvc = HttpUtility.ParseQueryString(Request.RequestUri.Query);
//the name value captures the paging info that kendo automatically appends to the query string when it requests data
//it has info such as teh current page, page size etc....
int take = int.Parse(nvc["take"]);
int skip = int.Parse(nvc["skip"]);
return productsSvc.GetProductsOfOrder(orderId,skip,take);
}
My service returns an IQueryable
, but it could also return a concrete list as returning an IQueryable
did nothing in helping Kendo figure out how many total items there were. The main issue for me was that the grid was not realising the total items count correctly, for example the first page would be displayed (first 5 items) however the remaining items weren't noticed and as a result the grids paging buttons were disabled so I kinda hacked around that but manually setting the total number of items, that was these lines of code:
schema:{
total: function(response) {
return 13; // call some function, or some scope variable that know the total items count
},.........
One thing bothering me is having to set the total items count manually. Worth mentioning that when setting up the datasource you can pass in a function to the read property of the transport object, that function will have as a parameter an object containing the current paging/filtering info, so you could use that to build a query string manually rather than relying on the default kendo server request:
transport: {
read: function (options) {
console.log(options);//see whats inside
//we can use the pageNo and pageSize property to create a query string manually
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With