I have the following code and I am trying to get the count of returned records without having to issue a second fetch() command:
dsOffers = new kendo.data.DataSource({
transport: {
read: {
url: PRODUCTAPI,
data: getOfferData()
}
},
serverPaging: true,
pageSize: 50,
schema: {
data: "results",
total: "count",
model: { id: "id" }
}
})
.bind("error", namespace.dataSource_error);
dsOffers.total(); // returns 0
// if I use this, my API is hit twice
dsOffers.fetch(function() {
console.log(dsOffers.total()); // returns 3
});
The problem is that it takes time loading the data (it happens asynchronously -in background/parallel-). If you print it just after the initialization you actually don't have the data available.
This is the correct behaviour.
If you don't want to do the second fetch you should print it in the dataBound event.
Related
Following code builds my kendo DataSource:
var dataSource = new kendo.data.DataSource({
serverPaging: true,
schema: {
data: "ListMediaSummary",
total: "RowCount",
},
transport: {
read: {
url: gAppBaseURL + "UniversalSearch/SearchData?searchText=" + searchText + "&pageNumber=" + page,
type: "POST",
dataType: "json",
}
},
parameterMap: function (data, type) {
if (type == "read") {
return {
$top: data.take,
$skip: data.skip
}
}
},
page: 1,
pageSize: 25,
});
And from here I am passing the parameter "searchText" and "PageNumber" from the transport.read method to the Action method in my asp.net controller, after which the search results gets rendered into kendo listView.
The action method gets the "searchText" value but it dosent gets the pageNumber? Although in the post it does passes the Page number(checked in firebug) but what I want is to pass the page number to the transport.read method in my function. How could I achieve this?
To enable server paging, you should configure data source to enable serverPaging. Then the data source will leave the data item paging implementation to the remote service. By default the data source performs paging client-side.
<script>
var dataSource = new kendo.data.DataSource({
transport: {
/* transport configuration */
},
serverPaging: true,
schema: {
total: "total" // total is returned in the "total" field of the response
}
});
</script>
Don't forget to set schema.total if you set serverPaging to true.
The following options are sent to the server when server paging is enabled:
page - the page of data item to return (1 means the first page)
pageSize - the number of items to return
skip - how many data items to skip
take - the number of data items to return (the same as
pageSize)
Therefore you should change your controller action method to something like this:
public ActionResult GetData(int page, int pageSize, int skip, int take){
// do some magic operation
}
I'm trying to understand how Kendo UI grid works. This the example for the Kendo website.
Somewhere one can find this configuration lines:
pageSize: 20,
serverPaging: true,
serverFiltering: true,
serverSorting: true
And this is the line that fetch the data
transport: {
read: "http://demos.telerik.com/kendo- ui/service/Northwind.svc/Orders"
},
I wonder whether the above parameters are being sent to the server, i.e. a server side method should like this?
public list<type> MyServerSideMethod(inr pageSize, bool serverPaging,
bool serverFiltering, boll serverSorting)
{
}
In fact, I've applied the configuration, but the pager on my grid is still not working. That why I'm wondering whether the method in the server is expecting those values.
Thank for helping
Define your read as a function and manipulate the parameters send to server
transport: {
read: function (options) {
console.log(JSON.stringify(options)); // You can see what parameters send : check your console on paging
var commandOBJ=[{
Page: 1, // Once the first 20 item is loaded and you click for the next page you will have the page in "options" (should be like options.page)
PageSize:20
}];
$.ajax({
url:"http://demos.telerik.com/kendo- ui/service/Northwind.svc/Orders",
data: { }, // send your page info here
dataType: "json", // your data return type
cache: false,
success: function (result) {
options.success(result);
},
error: function (result) {
options.error(result);
}
});
}
}
Environment:
kendo version: 2013.1.319
dataSource:
productsDataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: "http://www.mydomain.com/odata.svc/products",
dataType: "json",
contentType: "application/json"
}
schema: {
type: "json",
data: function(data){
return data.value;
},
total: function(data){
return data['odata.count'];
},
model: product
},
pageSize: 50,
serverPaging: true,
serverFiltering: true,
serverSorting: true
});
Get data:
productsDataSource.filter([{ field: "Id", operator: "eq", value: 5 }]); //this will send an httprequest
productsDataSource.fetch(function (e) {
tempDataStorage = e.items;
//more logic to dealing with the data;
});
problems:
need to use the fetch method of the dataSource for data processing(widgets initialization, data binding...etc);
avoid sending two httprequests when setting filters before fetch;
the filter condition need to be changed at runtime.
productsDataSource._filter = { logic: 'and', filters: [
{ field: "Id", operator: "eq", value: 5 }]};
I've found this to work. Set the internal property to a full filter object. You can then call fetch afterwards. I've not yet found a way to change the page size without triggering a fetch however.
You can user filter in the DataSource configuration. This should issue only one request with the filtering conditions that you specify in the DataSource configuration.
Set the _filter field in the dataSource using productsDataSource._filter = [{ field: "Id", operator: "eq", value: 5 }]; and then manually initiate the request for remote data when you are ready using productsDataSource.read();
Even though it is an old question, it comes in google results. So even though I don't know if it is valid for kendo version: 2013.1.319, but there is currently a method
dataSource.query({
sort: { field: "ProductName", dir: "desc" },
page: 3,
pageSize: 20
});
This can set multiple options like sort, filter paging etc in a single call and returns a promise.
http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#methods-query
Bind event listener to datasource which initializes widget and then use filter method.
datasource.one('requestEnd', function(){
// initialize or/and bind widget
});
datasource.filter({ /*your filter*/ })
Since I've tryed to write on kendoui forum but the answer I've got was "buy a license" for report a bug, I'm asking if someone has faced the same problem using kendoGrid 2013.1.319. Since I'm using it in a "sundays test application" there's no hurry at all!
My original message was on kendo forum was:
Hi there,
I've been updated kendo grid with the latest version and all of a sudden my application is facing problems on data operations. The problem seems to be located client side, because I'm correctly receiving requests for GET, PUT, POST and DELETE verbs but the grid does not update its status.
I'm using ASP.NET MVC 4 OData implementation through an API service.
For example: if I delete 2 rows and press save, the DELETE calls are made, the client grid hides the rows but if I press save again, the delete is called on and on.
The same problem is on update / create, the cell remains with the red corner and, after saving, again the data are still submitted as it was the first time.
I've noticed that when I receiving the callback on dataSource:
requestEnd: function (e) {
if (e.type === "update" || e.type === "create") {
// Refresh data after changes
this.read();
}
}
e.type is always undefined when inserting or updating records.
This is my dataSource configuration:
dataSource: {
type: 'odata', // <-- Include OData style params on query string
transport: {
read: {
url: $("#contactsGrid").attr("data-api-crud"),
dataType: "json", // <-- The default is "jsonp".
type: "GET"
},
update: {
url: $("#contactsGrid").attr("data-api-crud"),
dataType: "json", // <-- The default is "jsonp".
type: "POST"
},
create: {
url: $("#contactsGrid").attr("data-api-crud"),
dataType: "json", // <-- The default is "jsonp".
type: "PUT"
},
destroy: {
url: function (data) {
return $("#contactsGrid").attr("data-api-crud") + "/" + data.Id;
},
dataType: "json", // <-- The default is "jsonp".
type: "DELETE"
},
parameterMap: kendo.data.transports.odata.parameterMap
},
schema: {
// The array of repeating data elements (items)
data: "Results",
// The total count of records in the whole dataset. used for paging.
total: "Count",
model: {
id: "Id",
fields: {
Dealer: { type: "string", editable: true },
Address: { type: "string", editable: true }
}
}
},
pageSize: 50,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
requestEnd: function (e) {
if (e.type === "update" || e.type === "create") {
// Refresh data after changes
this.read();
}
}
}
the Kendo UI team have just published a blogpost how to use the library with JayData to simplify the configuration of datasources. Hopefully it will help you.
I have a problem with the Kendo AutoComplete widget.
I am trying it to query the datasource after the user has entered the first two characters of their search.
On the server (web api) I restrict the search using those two chars and all is well, i.e. a subset is returned and correctly shown and further filtered if I carry on typing in the search.
However, I then retype a new search entry which is no longer firing back to the datasource so I am stuck with the data that was retrieved from the first query.
How do I go about this properly?
Thanks
Here is my test code:
public class AlbumsController : ApiController
{
HttpRequest _request = HttpContext.Current.Request;
// GET api/albums
public IEnumerable<Album> GetForAutoComplete()
{
string sw = _request["sw"] == null ? "" : _request["sw"].ToString();
var query = (from a in Albums.MyAlbums
where a.Title.ToLower().StartsWith(sw)
orderby a.Title
select a).ToArray();
return query;
}
and my javascript on the client is like this:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/api/Albums/GetForAutoComplete",
data: {
sw: function () {
return $("#albumSearch").data("kendoAutoComplete").value();
}
}
}
}
});
$("#albumSearch").kendoAutoComplete({
dataSource: dataSource,
dataTextField: "Title",
minLength: 2,
placeholder: "type in here.."
});
Set serverFiltering to true. The default is false, so it will only grab data once and assume that it now has all the data, and subsequent filtering is done on the client.
To have it re-send to the server every time, add this:
var dataSource = new kendo.data.DataSource({
serverFiltering: true, // <-- add this line.
transport: {
...
}
});
The code for selecting an European country while typing using kendo autocomplete from database as below:
$("#countries").kendoAutoComplete({
dataTextField: "yourfield",
filter: "startswith", // or you can use filter: "contains",
minLength: 3, //what ever you want. In my case its 0.
placeholder: "Select country...",
dataSource: {
type: "get",
serverFiltering: true, //or can also make it false
transport: {
read: {
url: "/yourController/yourAction",
datatype: "json"
}
}
}
});
It works fine for me.