Add custom command to Kendo UI dynamic datasource / grid - kendo-ui

I'm using Kendo UI javascript framework in an ASP.NET MVC application.
I have to load dynamic data, provided by my server, in my Kendo UI Grid, so I don't want to use datasource schema and columns definition, in no case.
An example of my data is : PersonID, Data1, Data2, Date3 ...
To load dynamic data in Kendo UI Grid I use the following code: (JsFidlle Example)
var grid = $("#grid").kendoGrid({
scrollable: false,
sortable: true
}).data("kendoGrid");
var ds = grid.dataSource;
grid.columns = [];
ds.data([{one: 1, two: 1, three: 3, four: 4}]);
Starting from this example, I'm curious to know if, with this management, I can put in each row a command / custom command like "Delete". (Example)
Eventually, how can I handle the command's behavior ? (would be nice to see a confirm window after the click over the command)
Thanks for the attention !

Get your data first, then create an array for the grid columns based on the data and add a column for the buttons.
Create the grid and attach handler to every button.
http://jsfiddle.net/cp67fpw1/2/
Creating the grid:
var columns = [],
data = [{
one: 1,
two: 1,
three: 3,
four: 4,
five: 5
}],
grid;
for (var cx in data[0]) {
if (data[0].hasOwnProperty(cx)) {
columns.push({
field: cx
})
}
}
columns.push({
field: '',
template: '<a class="k-button" command="doit">do it</a><a class="k-button" command="doitagain">do it again</a>'
});
grid = $("#grid").kendoGrid({
columns: columns,
dataSource: new kendo.data.DataSource({
data: data
}),
scrollable: false,
sortable: true
}).data("kendoGrid");
Adding the button handler:
$('#grid').on('click', '[command="doit"]', doit);
function doit(e) {
var dataItem = grid.dataSource.getByUid($(this).closest('tr').data('uid'));
}

I resolved out with this solution : https://jsfiddle.net/Endrik/smLfh67e/1/
It's very similar to Frederic solution but with few changes.
1) I start from a datasource object, cause I will get my data from remote
If you change the type of data loading in the DataSource object, the example should work equally.
var myDataSource = new kendo.data.DataSource({
data: [{
one: "1",
two: "2",
three: "3",
four: "4"
}, {
one: "5",
two: "6",
three: "7",
four: "8"
}]
});
myDataSource.fetch();
2) In order to have dynamic columns, I have to convert the data present in my datasource object into an array of values. (Like Frederic's startup collection of objects)
var myDataSourceRowsNumber = myDataSource.total();
var rows = [];
var columns = null;
var columnsCount = 0;
for (var i = 0; i < myDataSourceRowsNumber; i++) {
var entryArray = [];
var dataItem = myDataSource.at(i);
columns = [];
for (var field in dataItem) {
if (dataItem.hasOwnProperty(field) &&
field != 'parent' &&
field != 'uid' &&
field != '_events') {
columns.push({
field: field,
value: dataItem[field.toString()]
});
}
}
columnsCount = columns.length;
for (var j = 0; j < columnsCount; j++) {
entryArray.push(dataItem[columns[j].field]);
}
rows.push(kendo.observable({
entries: entryArray
}));
}
var viewModel = kendo.observable({
gridRows: rows
});
3) At the end, I create a new Kendo UI grid with my definition of columns.
var finalColumns = [];
for (var k = 0; k <= columnsCount; k++) {
var entryIndex = "entries[" + k + "]";
if (k != columnsCount) {
finalColumns.push({
field: entryIndex,
title: columns[k].field
});
} else {
finalColumns.push({
command: [{
name: "CustomDelete",
text: "Delete",
className: "custom-delete-btn ",
imageClass: "k-icon k-i-close",
click: ManageDeleteButtonClick
}],
title: "Actions"
});
}
}
var configuration = {
editable: true,
sortable: true,
scrollable: false,
columns: finalColumns
};
function ManageDeleteButtonClick(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.target).closest("tr"));
if (confirm('Are you sure you want to delete this record ?')) {
// AJAX CALL
var dataSource = $("#grid").data("kendoGrid").dataSource;
dataSource.remove(dataItem);
}
}
var myGrid = $("#grid").kendoGrid(configuration).data("kendoGrid");
kendo.bind($('#example'), viewModel);

Related

Text of select column in jqgrid is not exporting to excel

The demo Link - "https://jsfiddle.net/OlegKi/ovq05x0c/6/" uses the code
.jqGrid("navButtonAdd", {
caption: "",
title: "Export to Excel(.XLSX)",
onClickButton: function () {
var filename = "jqGrid.xlsx",
data = $(this).jqGrid("getGridParam", "lastSelectedData"), i, item,
dataAsArray = [["Client", "Date", "Amount", "Tax", "Total",
"Closed", "Shipped via"]];
for (i = 0; i < data.length; i++) {
item = data[i];
dataAsArray.push([
item.name,
new Date(item.invdate),
item.amount, item.tax, item.total,
item.closed, item.ship_via]);
}
var ws_name = "SheetJS";
var wb = XLSX.utils.book_new(),
ws = XLSX.utils.aoa_to_sheet(dataAsArray);
XLSX.utils.book_append_sheet(wb, ws, ws_name);
XLSX.writeFile(wb, filename);
}
});
in this demo- click on export button export value of jqgrid select formatter column instead of text of formatter select column(Shipped via). And my requirement is text should export in excel. Can anyone help to solve this issue.
One can fix the code by calling formatter function and removing <span class='ui-jqgrid-cell-wrapper'>...</span> wrapper in case of usage autoResizable: true property. The modified code could looks like
.jqGrid("navButtonAdd", {
caption: "",
title: "Export to Excel(.XLSX)",
onClickButton: function () {
var filename = "jqGrid.xlsx",
self = this,
data = $(this).jqGrid("getGridParam", "lastSelectedData"), i, item,
iColByName = $(this).jqGrid("getGridParam", "iColByName"),
dataAsArray = [["Client", "Date", "Amount", "Tax", "Total", "Closed", "Shipped via"]];
function getFormattedValue (item, cmName) {
var value = self.formatter(item.id, item[cmName], iColByName[cmName], item, "add", item),
ex = /^<span class='ui-jqgrid-cell-wrapper'>([^<]+?)<\/span>$/i.exec(value);
return Array.isArray(ex) && ex.length === 2 ? ex[1] :value;
}
for (i = 0; i < data.length; i++) {
item = data[i];
dataAsArray.push([
item.name,
getFormattedValue(item, "invdate"),
getFormattedValue(item, "amount"),
getFormattedValue(item, "tax"),
getFormattedValue(item, "total"),
item.closed,
getFormattedValue(item, "ship_via")]);
}
var ws_name = "SheetJS";
var wb = XLSX.utils.book_new(),
ws = XLSX.utils.aoa_to_sheet(dataAsArray);
XLSX.utils.book_append_sheet(wb, ws, ws_name);
XLSX.writeFile(wb, filename);
}
});
see https://jsfiddle.net/OlegKi/mpyuxto9/14/

Filtering a single column with OR operator

Would like to do filtering in kendo grid within the same column for getting a union of values coming from a multiselect field:
$('#btnSearchRoles').click(function (e) {
e.preventDefault();
//process searched roles
var multiselect = $("#RoleSubroleId").data("kendoMultiSelect");
// get data items for the selected options.
var dataItem = multiselect.dataItems();
var filterCode = "[";
for (var i = 0; i < dataItem.length; i++) {
filterCode += "{ field: 'RolesAsString', operator: 'contains', value: '" + dataItem[i].Name + "'},"
}
filterCode += "]";
//start filtering
var dataSource = $("#grid").data('kendoGrid').dataSource;
dataSource.filter({
logic: "or",
filters: filterCode
});
});
Even though filterCode gets correctly populated the filters do not reach the DataSourceRequest request parameter.
I used push method for JS arrays to replace string composition of the filter:
$('#btnSearchRoles').click(function (e) {
e.preventDefault();
//process searched roles
var multiselect = $("#RoleSubroleId").data("kendoMultiSelect");
// get data items for the selected options.
var dataItem = multiselect.dataItems();
var setFilter = { logic: "or", filters: [] };
for (var i = 0; i < dataItem.length; i++) {
setFilter.filters.push({ field: "RolesAsString", operator: "contains", value: dataItem[i].Name });
}
//start filtering
var dataSource = $("#grid").data('kendoGrid').dataSource;
dataSource.filter(setFilter);
});

Database driven Kendo Grid column

Is it possible to enumerate the grid columns eg (title and width) coming from a database table?
You will need to make an ajax call for that. Derive the column names from the table and then you can make modifications.
For e.g.
$.ajax({
url:actionUrl, //Url of the Method for fetching names of the columns and its count
success: function(result){
for (var i = 0; i < result.columnsCount; i++) { //running the loop based on number of columns needed
columns.push({
field: result.columnName, //set the columnNames from the Db as field
title: result.Header //specifying the columns title
});
}
}
});
You can try the following:
$(document).ready(function() {
var model = kendo.observable({
gridRows: []
});
var columns = [];
for (var i = 0; i < 4; i++) {
var entryIndex = "entries[" + i + "]";
columns.push({
field: i,
title: "Column " + i
});
}
var configuration = {
resizable: true,
columns: columns
};
var timeEditGrid = $("#grid").kendoGrid(configuration).data("kendoGrid");
kendo.bind($('#example'), model);
});
http://jsfiddle.net/4sM7g/

Kendo UI grid databinding using mvvm pattern

I am new to Kendo UI, i want to bind kendo ui grid using MVVM pattern, and my datasource is sharepoint list. so i am calling sharepoint list data through CSOM javascript code. I tried different solution but nothing seems to working. I have collection of data from sharepoint list.
var divisionListData = [];
//var divisionsViewModel;
var viewModel = kendo.observable({
isVisible: true,
onSave: function (e) {
alert('hi');
kendoConsole.log("event :: save(" + kendo.stringify(e.values, null, 4) + ")");
},
divisions: new kendo.data.DataSource({
// schema: {
data: divisionListData,
schema: {
data: "rows",
model: {
fields:
{
ID: { type: "string" },
DivisionName: { type: "string" },
DivisionCode: { type: "string" },
OpenDate: { type: "datetime" },
CloseDate: { type: "datetime" },
Description: { type: "string" },
}
}
},
batch: true,
transport: {
read: function (e) {
return divisionListData;
}
})
})
function ReadList() {
//this.set("isDisabled", false);
var clientContext = new SP.ClientContext.get_current();
// denote that we will be performing operations on the current web
var web = clientContext.get_web();
// denote that we will be querying the "Business Divisions" custom SharePoint list
var divisionsList = web.get_lists().getByTitle("Divisions");
// create a CAML query (blank means just return all items)
var camlQuery = new SP.CamlQuery();
// denote that the operation we want to perform is getItems() on the list
var divisionsListItems = divisionsList.getItems(camlQuery);
var fields = 'Include(ID,DivisionCode, DivisionName, OpenDate, CloseDate, Description)';
clientContext.load(divisionsListItems, fields);
clientContext.executeQueryAsync(function () {
// get the list item enumerator
var listItemEnumerator = divisionsListItems.getEnumerator();
// loop through the items in our custom
// "Divisions" SharePoint list
var listItem;
while (listItemEnumerator.moveNext()) {
var division = new Division();
// get the list item we are on
listItem = listItemEnumerator.get_current();
// get the divisions
division.ID = listItem.get_item("ID");
// var lookup_DivisionCode = listItem.get_item("DivisionCode").get_lookupValue();
//lookup_DivisionCode.get_l
var divisionLookupField = new SP.FieldLookupValue();
divisionLookupField = listItem.get_item("DivisionCode");
//var test = divisionLookupField.$2d_1;
if (divisionLookupField != null)
division.DivisionCode = divisionLookupField.$2d_1;
division.DivisionName = listItem.get_item("DivisionName");
division.Description = listItem.get_item("Description");
division.OpenDate = listItem.get_item("OpenDate");
division.CloseDate = listItem.get_item("CloseDate");
divisionListData.push(division);
kendo.bind($("body"), viewModel);
}
})
}
You are pretty close, instead of returning the array inside the read: function(e), you need to call
e.success(yourArrayOfData);

Kendo Ui Grid - dataItem.set() method not working properly

I have a grid with 4 columns name, age, collection, profit. But when I try to set a number column it's not reflecting on grid.
schema:
{
model:{
fields:{
name:{type:"string"},
age:{type:"number"},
collection: { type:"number", defaultValue:0.00},
profit: { type:"number", defaultValue:0.00}
}
}
}
This code works perfectly:
var grid = $("#grid").data("kendoGrid");
var data = grid.dataSource.at(0);
data.set("name", "John Doe");
But I want to update numeric column:
var grid = $("#grid").data("kendoGrid");
var data = grid.dataSource.at(0);
var collectionVal = 50000;
data.set("collection", collectionVal);
And it's not updating because the column is of type "number".
UPDATE:
pageable:
{
refresh : true,
pageSizes: true
},
edit: function(e)
{
$('input[name="age"]').blur(function()
{
mygrid = $("#grid").data("kendoGrid");
selectedRow = mygrid.select();
dataItem = mygrid.dataItem(selectedRow);
dataItem.collection = dataItem.age * dataItem.profit;
dataItem.set("collection", dataItem.collection);
});
}
Instead of updating collection in a blur handler defined in the edit, define a save event handler in your grid as follow:
pageable : {
refresh : true,
pageSizes: true
},
save : function (e) {
var profit = e.values.profit || e.model.profit;
var age = e.values.age || e.model.age;
this.dataSource.getByUid(e.model.uid).set("collection", age * profit);
}

Resources