I am using Kendo UI data Grid for displaying a large local data set (60MB). I enabled Virtual scrolling. Since the server is sending a very large dataset the performance is very low. I would like to do paging at the server end and send only a smaller data set. For this, how can I pass the currentpage data when virtual scrolling is enabled ?
Solution to the above is : Define the controller action with below signature
public JsonResult (int skip, int take, int page, int pageSize, List sort)
Kendo Grid posts the skip, take, page, pageSize parameters based on the pageSize property of the Kendo Grid. Also Kendo grid expects total item count as part of the data returned from the action for paging to work correctly. Include TotalRowCount in the data returned and specify this in the schema property of teh DataSource. For eg.,
schema: { data: "Data", total: "TotalRowCount" }
Related
How do I check if a particular field or column of a subgrid is business recommend or not? I want to do this using a web resource. Also due to some requirements, I will have to use the execution context of the form where the subgrid is present and not of the subgrid itself.
It is a little tricky because at the time that the form loads, the subgrid does not have data. So you have to use the Form's load event to attach a load event to the subgrid.
This is described in this MS Docs Page. You can do this like
function attachGridEvent(executionContext)
{
var formContext = executionContext.getFormContext();
var gridContext = formContext.getControl("gridCategories");
// We have the grid, now add a "load" event handler
gridContext.addOnLoad(MyGridLoadedEvent);
}
Now you've got a 'load' event for your grid so you can iterate through its rows and examine its data
I haven't been able to get this to work for subgrids that don't contain data
I get the first row in the sub grid. Once I have that we can loop through each of the row's attributes. Each attribute has the following methods:
getName Returns the logical name of the attribute of a selected grid
row.
getRequiredLevel Returns a string value indicating whether a
value for the attribute is required or recommended.
setRequiredLevel Sets whether data is required or recommended for the
attribute of a selected grid row before the record can be saved.
getValue Retrieves the data value for an attribute.
setValue Sets the
data value for an attribute.
MS Docs Page
I'm using some modern browser features (map, =>) but this code should work for you
function MyGridLoadedEvent(evt)
{
var gridContext = evt.getEventSource();
var rows = gridContext.getGrid().getRows();
if (rows.getLength() > 0)
{
let rowAttributes = rows.getByIndex(0).getAttribute();
let mappedResults = rowAttributes.map(x => x.getName() + " : " + x.getRequiredLevel());
alert(mappedResults);
}
}
With the particular database server we are using it's just as expensive to run a COUNT() query as it is to run the actual query, so I'd prefer to not display the count at all.
Normally, outside of kendo grid, I would just display previous and next buttons but not show the total count. Is it possible to achieve something similar with Kendo Grid?
Set the numeric property of the pageable object in your kendo grid options. That should disable the numeric buttons for you:
$("#grid").kendoGrid({
pageable: {
numeric: false
}
});
See http://docs.kendoui.com/api/web/grid#configuration-pageable.numeric for more info
To set the data to a specific count, in your kendo datasource options, use the schema.total function to return some large value to give you enough paged data:
var dataSource = new kendo.data.DataSource({
schema: {
total: function(response) {
return 100000000;
}
}
});
Let's say I have hierarchical data that I display in a treeview. It's possible that a particular node might have 1000 children and I don't want to display them all, so I'm toying with the idea of paging the nodes in a tree. I would show 10 children and if there are more, the user needs to click on the next/previous buttons to see them. I've got sql paging working but I can't get the treeview to do what I want.
If I do this, my controller gets the proper node id and page id and it returns the correct page of results back. But then the treeview shows only the 1 page of children I just requested; the rest of the hierarchy (all the parents) is lost:
$("#btnNextPage")
.click(function () {
var selectedNode = treeview.select();
var selectedNodeID = treeview.dataItem(selectedNode).id;
ds.read({
LoopID: selectedNodeID,
page: ds.page() + 1
});
If I do this, I can keep the hierarchy and my controller gets called, but I can't figure out how to pass in the page that I'm requesting.
$("#btnNextPage")
.click(function () {
var selectedNode = treeview.select();
var testnode = treeview.dataItem(selectedNode);
testnode.loaded(false);
testnode.load();
});
I've been using ASP.NET webforms and this is my first foray into jquery and kendo. Any ideas?
When you change pages the Kendo DataSource replaces its records in memory with the new page retrieved from the server.
You would need to retain all the previously loaded pages in a separate observable array and bind your treeview to that instead.
With a pointer from the folks at Telerik, I got this working. The trick was to use the children property which is the datasource for the children of the selected node. So when the next page button is clicked I do this:
parentNodeDataItem.children.read({
LoopID: parentNodeID,
page: currentPage
});
This produced the behavior I wanted, which was for the children to be refreshed without losing the ancestor hierarchy.
I need to display a number of "dynamic" grids using jqGrid. By dynamic I mean that both definition and data of the grid are retrieved from a database. There are many grids on the page, so I am trying to minimize the number of server trips, and there is a lot of data, so server-side paging is a must.
My workflow is
On initialization of each grid, retrieve grid definition and first
page of data in one server call.
If a user sorts/pages, then retrieve a page of data from the server
Because I want to retrieve the grid definition and first page of data in one call, I cannot use datatype: 'json', url: '###' approach; instead I do:
grid.jqGrid({
mtype: 'post',
...
datatype: function (postdata) {
if (!init.data) {
var request = {
screenId: settings.screenId,
pageNumber: postdata.page,
pageSize: postdata.rows,
sortColumn: postdata.sidx,
sortDirection: postdata.sortd,
date: settings.date
};
site.callWs("/MyService", request, function (pageResponse) {
//WHAT TO CALL HERE TO SET A PAGE OF DATA?
});
} else {
//WHAT TO CALL HERE TO SET A PAGE OF DATA?
init.data = null;
}
}
});
My data object (pageResponse or init.data) looks like this
I am not sure what method to call on jqGrid once a page of data is returned. I considered addJSONData, but it seems so inefficient to convert JSON back to string, then use EVAL(). Also, considered addRowData or setting the data property, but I am confused how to instruct jqGrid that I am doing server-side paging -- if I set the data property to one page of records, what do I need to do to tell jqGrid that there is a total of 50 records and this is page 1 out of 10.
Thanks for your help.
It was a user error (mine :). I had some show/hide logic in loadComplete of jqGrid, but this event does not fire when addJSONData is called.
addJSONData works just fine when provided with a properly-structured JavaScript object.
I have a view where I create a new company.
The company has a number of trades, or which 1 is a primary trade.
So when I enter the trades for that company, I select a trade via autocomplete, and this trade is added to a grid of trades underneath the autocomplete textbox. The grid contains the tradeId as a hidden field, the trade, and a radio button to indicate whether the trade is a primary trade and a remove button.
This is part of a form that contains other company details such as address.
Now I am wondering if I can use knockout and (maybe) jsrender to populate the grid without posting to the server?
When I have filled in the grid AND the other company details, I then want to submit the data to the controller post method.
Normally I use the Html helpers to post values to the controller, but I don't see how I can do that using knockout.
Yes you can use Knockout for this. If you have not checked the tutorials out yet then try this Knockout List and Collections tutorial. This should point you in the right direction. What you'll need to do is create a Trade object with observable properties and in a separate knockout view model create an observableArray to store trade objects. For information on posting to the server there are other tutorials in the same location.
function Trade(item) {
var self = this;
self.tradeId = ko.observable(item.tradeId);
self.tradeName = ko.observable(item.tradeName);
self.isPrimary = ko.observable(item.isPrimary);
}
function TradesViewModel() {
var self = this;
// Editable data
self.trades = ko.observableArray([]);
self.removeTrade = function(trade) { self.trades.remove(trades) }
self.save = function() {
$.post("/controller/action", self.trades);
}
}
ko.applyBindings(new TradesViewModel());