I'm trying to use Kendo-UI to manage a grid on a page, however I'm having a hard time with the following specific set-up:
The data is fetched from a remote source, however, I would like to do paging on the client side, not on the server side.
The whole problem can easily be summarized with the following jsfiddle: http://fiddle.jshell.net/dimodi/4eNu4/
When serverPaging: true, everything works as expected, but when serverPaging: false, no entries are show after the first page.
The problem is that you have defined a dataBound event function that does not return any data.
Define your function as:
function resizeGrid(d) {
var gridElement = $("#grid");
var dataArea = gridElement.find(".k-grid-content");
var newHeight = gridElement.parent().innerHeight() - 2;
var diff = gridElement.innerHeight() - dataArea.innerHeight();
gridElement.height(newHeight);
dataArea.height(newHeight - diff);
return d;
}
I've added an argument d that I return at the end of your processing.
Updated fiddle: http://fiddle.jshell.net/4eNu4/253/
All you really have to do is remove the serverPaging: true config option. Then just set a pageSize: 10 in the schema and then add pageable: true to the config of the grid to allow for client side paging.
Updated your fiddle http://jsfiddle.net/4eNu4/247/ hope this is what you are looking for.
Related
I have a Grid, when users click a button, it gets some parameters and refresh datasource:
var grdUP = $("#weblogGrid").data("kendoGrid");
grdUP.dataSource.transport.options.read.url = url; // new url
//Read data source to update
grdUP.dataSource.read();
it works fine. the new data shows in the grid. And the grid has another button, which will export the data to excel. I'm using below code (also tried the built-in button):
var grid = $("#weblogGrid").data("kendoGrid");
grid.saveAsExcel();
it actually exports the data to excel file.
However, it always exports the initial data in the grid, not the data user refreshed.
For example, when the grid first shows up, it has 10 rows data. After refresh, it has 5 rows data. Now, if export, it still exports 10 rows data although the data in grid is different.
Is this a Bug? or, maybe I did something wrong in refresh grid?
Thanks
===============================
edit to clarify something
Thanks. currently, I got new data using:
var url = '/WeblogReport/GetWebLogList?fromDate=' + fromDate + '&toDate=' + toDate;
var grdUP = $("#myGrid").data("kendoGrid");
//Set url property of the grid data source
grdUP.dataSource.transport.options.read.url = url;
//Read data source to update
grdUP.dataSource.read();
So I changed to:
// get value of date
....
$.ajax({
type: "GET",
dataType: "json",
url: "/WeblogReport/GetWebLogList",
data: { FromDate: fromDate, ToDate: toDate },
success: function (data) {
alert(data);
var grid = $("#myGrid").data("kendoGrid");
grid.dataSource.data(data);
grid.refresh();
}
});
Somehow, it does not show the new data. Any suggestions?
Thank you very much.
add more clarification
Here is in the Json call.
success: function (data) {
var newdata = [{ "UserName": "username", "ClientIP": "1.1.1.1"}];
$("#myGrid").data("kendoGrid").dataSource.data(newdata);
$("#myGrid").data("kendoGrid").refresh();
//$("#myGrid").data("kendoGrid").saveAsExcel();
}
Set both of the following fields to make Excel export work:
grid.dataSource.transport.options.read.url = url;
grid.options.dataSource.transport.read.url = url;
check this:
http://jsfiddle.net/Sowjanya51/o8cw3vj8/
$('#grid1').data('kendoGrid').dataSource.data(newdata);
$('#grid1').data('kendoGrid').refresh();
You need to update the dataSource and reload the grid,otherwise the grid dataSource will still have reference to old data even though UI displays the new data.
Just set the "allPages" option on your grid to "True". like so :
excel: {
fileName: "Export.xlsx",
filterable: true,
allPages: true
},
Your original solution should be fine if you refresh the grid after you read from the data source.
var grdUP = $("#weblogGrid").data("kendoGrid");
grdUP.dataSource.transport.options.read.url = url; // new url
//Read data source to update
grdUP.dataSource.read();
//add this line to refresh the active data set in the grid
grdUP.refresh();
I had run into the same issue and this solved it for me. The only difference between your approach and mine is that you're changing the data source's read URL, whereas I was changing the data parameters for the read method. Shouldn't make any difference, but I'll mention that just in case.
The JsonRest store I created is shown below
var questionBaseURL = "/" + contextName + "/service/questions/" + projectId + "/";
var questionStore = new dojo.store.JsonRest({
target: questionBaseURL,
handleAs: 'json',
idProperty: 'questionId'
});
questionStore = new dojo.store.Observable(questionStore);
var memoryStore = new dojo.store.Memory();
var questionCacheStore = new dojo.store.Cache(questionStore, memoryStore);
Which I use to render into the Grid created as below
var CustomGrid = declare([OnDemandGrid, Keyboard, Selection]);
var questionGrid = new CustomGrid({
store: questionCacheStore,
columns: [
editor({
label: "Questions",
field: "question",
editor: "text",
editOn: "dblclick",
sortable: true,
autoSave:true
})
],
selectionMode: "single",
cellNavigation: false
}, "questions");
questionGrid.startup();
questionGrid.renderArray(questionArray);
The data is properly populated in the grid. Now, since am using "editor", I am able edit the populated data in the grid. I am not sure how exactly to detect if the data has been edited (dirty data ) and which method to call to carry the updated data back to the server. I couldn't find any easy documentation. So any help is appreciated. Thanks in advance
You can use the grid's save method to push all items with dirty data back to the server. There is also a revert method which can be called to discard any dirty data. These are listed in the OnDemandList and OnDemandGrid documentation.
These methods are defined in dgrid/_StoreMixin which is inherited by OnDemandList (and OnDemandGrid). The editor column plugin calls updateDirty (also defined by _StoreMixin) when changes are made, which updates a dirty hash. save will check this hash and call put on the store for each dirty item.
I made this topic once, but the information I had was a bit hard to follow and I did not get much help, so I am trying again after spending the day making a JSBIN sample.
I have a situation where I am using KendoUI to make a view model, and also to make some items within it, and when you click on sub-items that are drawn, it opens up a KendoWindow to let you edit them more specifically.
However, there is a problem with the dataSource concept, I think. When I try to bind to a dataSource on my page it works fine; But when I try to bind a kendo control to a remote datasource within a rendered window, it refuses to fetch.
If I bind only to local data, hard coded data, it works; So I know the dropdownlist is working. But I really need to be able to bind to remote data.
I have prepared a JSBIN to show this behavior (or lack thereof)
JSBIN EXAMPLE
Any help would be greatly appreciated. To see the behavior, click on the button to Create Socket Rail, then use the NumericTextBox to increase the size to any number higher than 0, then click on one of the drawn boxes.
You need to create the kendoDropDownList in the kendoWindow.activate event (or at least bind the DataSource there). Adapted from your code, this will work:
kendoWindowWidget = function (options) {
// extend the settings options so that we can take
// explicit configuration from the widget caller.
var settings = $.extend({
resizable: false,
modal: true,
viewable: true,
visible: false,
width: "450px",
height: "450px",
activate: function () {
var myDataSource = new kendo.data.DataSource({
transport: {
read: {
dataType: "json",
url: "http://jsbin.com/UYEbOXi/3/js"
}
}
});
widgets.windows.sockets.type = $('#socket-type').kendoDropDownList({
dataTextField: "Name",
dataValueField: "Id",
dataSource: myDataSource
}).data("kendoDropDownList");
}
}, options);
var $window = $("<div id='kendow-editor-window'/>")
.kendoWindow(settings)
.data("kendoWindow");
$window.databind = function (e) {
kendo.bind($window.element, e);
$window.open().center();
};
// return the created combo box
return $window;
};
Adapted JSBin (I removed a bunch of things to make it easier to manage):
http://jsbin.com/uMuFewI/3/edit
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;
}
}
});
I am trying to change the columns collection of my Kendo grid in the below way.
var grid = $("#grid").data("kendoGrid");
$http.get('/api/GetGridColumns')
.success(function (data) {
grid.columns = data;
})
.error(function (data) {
console.log(data);
});
This is changing the column collection but not reflecting immediately in my grid. But when I try to perform some actions in the grid (like grouping), then my new column set is appearing.
Please let me know how can I achieve this.
Regards,
Dilip Kumar
You can do it by setting the KendoUI datasource, destroy the grid, and rebuild it
$("#load").click(function () {
var grid = $("#grid").data("kendoGrid");
var dataSource = grid.dataSource;
$.ajax({
url: "/Home/Load",
success: function (state) {
state = JSON.parse(state);
var options = grid.options;
options.columns = state.columns;
options.dataSource.page = state.page;
options.dataSource.pageSize = state.pageSize;
options.dataSource.sort = state.sort;
options.dataSource.filter = state.filter;
options.dataSource.group = state.group;
grid.destroy();
$("#grid")
.empty()
.kendoGrid(options);
}
});
});
here you can just do this :
var options = grid.options;
options.columns = state.columns;
where you can retrieve the columns in a session or in a db
This jsfiddle - Kendo UI grid dynamic columns can help you - using kendo.observable.
var columns = data;
var configuration = {
editable: true,
sortable: true,
scrollable: false,
columns: columns //set the columns here
};
var grid = $("#grid").kendoGrid(configuration).data("kendoGrid");
kendo.bind($('#example'), viewModel); //viewModel will be data as in jsfiddle
For the ones who are using Kendo and Angular together, here is a solution that worked for me:
The idea is to use the k-rebind directive. From the docs:
Widget Update upon Option Changes
You can update a widget from controller. Use the special k-rebind attribute to create a widget which automatically updates when some scope variable changes. This option will destroy the original widget and will recreate it using the changed options.
Apart from setting the array of columns in the GridOptions as we normally do, we have to hold a reference to it:
vm.gridOptions = { ... };
vm.gridColumns = [{...}, ... ,{...}];
vm.gridOptions.columns = vm.gridColumns;
and then pass that variable to the k-rebind directive:
<div kendo-grid="vm.grid" options="vm.gridOptions" k-rebind="vm.gridColumns">
</div>
And that's it when you are binding the grid to remote data (OData in my case). Now you can add or remove elements to/from the array of columns. The grid is going to query for the data again after it is recreated.
When binding the Grid to local data (local array of objects), we have to somehow postpone the binding of the data until the widget is recreated. What worked for me (maybe there is a cleaner solution to this) is to use the $timeout service:
vm.gridColumns.push({ ... });
vm.$timeout(function () {
vm.gridOptions.dataSource.data(vm.myArrayOfObjects);
}, 0);
This has been tested using AngularJS v1.5.0 and Kendo UI v2016.1.226.
I'm use this code for change columns dynamic:
kendo.data.binders.widget.columns = kendo.data.Binder.extend({
refresh: function () {
var value = this.bindings["columns"].get();
this.element.setOptions({ columns: value.toJSON });
this.element._columns(value.toJSON());
this.element._templates();
this.element.thead.empty();
this.element._thead();
this.element._renderContent(this.element.dataSource.view());
}
});
Weddin
Refresh your grid
.success(function (data) {
grid.columns = data;
grid.refresh();
})
Here is what i use
var columns = [];//add the columns here
var grid = $('#grid').data('kendoGrid');
grid.setOptions({ columns: columns });
grid._columns(columns);
grid._templates();
grid.thead.empty();
grid._thead();
grid._renderContent(grid.dataSource.view());
I think a solution for what you are asking is to call the equivalent remote DataSource.read() method inside of the function. This is what I used to change the number of columns dynamically for local js data.
$("#numOfValues").change(function () {
var columnsConfig = [];
columnsConfig.push({ field: "item", title: "Metric" });
// Dynamically assign number of value columns
for (var i = 1; i <= $(this).val(); i++) {
columnsConfig.push({ field: ("value" + i), title: ("201" + i) });
}
columnsConfig.push({ field: "target", title: "Target" });
columnsConfig.push({ command: "destroy", title: "" });
$("#grid").data("kendoGrid").setOptions({
columns: columnsConfig
});
columnDataSource.read(); // This is what reloads the data
});
Refresh the grid
$('#GridName').data('kendoGrid').dataSource.read();
$('#GridName').data('kendoGrid').refresh();
Instead of looping through all the elements. we can remove all the data in the grid by using a single statement
$("#Grid").data('kendoGrid').dataSource.data([]);
If your grid is simple and you don't need to configure special column-specific settings, then you can simply omit the columns argument, as suggested in the API reference.
Use autogenerated columns (i.e. do not set any column settings)
... and ....
If this [column] setting is not specified the grid will create a column for every field of the data item.
var newDataSource = new kendo.data.DataSource({data: dataSource}); $("#grid").data("kendoGrid").setDataSource(newDataSource);
$("#grid").data("kendoGrid").dataSource.read();
After fighting this for a day and seeing hints in this thread that Kendo had simplified this problem, I discovered you can just use setOptions with a single property.
.success(function (data) {
grid.setOptions({
columns: data,
});
})
Grid Set Options