Kendo grid columns disable and make enable conditionally - kendo-ui

I want my Kendo grid's column read-only after bind. I have a dropdownlist in my page. Depending on the selected value of the dropdownlist I want to enable editing a cell in a row selected.
Does anyone have sample code?

It is possible to achieve the desired behavior like this:
use the edit event of the Grid, check the DropDownList value() and if editing should be prevented, execute the Grid's closeCell() method to exit edit mode. If the user is trying to add a new item to the Grid (e.model.isNew()), you will also need to remove() this new item with the respective dataSource method.
use the change event of the DropDownList to hide the CRUD-related buttons in the Grid with custom CSS styles.
Another possible option is to recreate and rebind the Grid with the correct editing settings via setOptions every time the dropDownList value changes.
The example below uses the first approach described above. You can modify it, so that not only the Delete buttons are toggled, but also Add New Record.
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/grid/editing/">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title>Kendo UI</title>
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.3.1118/styles/kendo.common.min.css" />
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.3.1118/styles/kendo.default.min.css" />
<script src="//kendo.cdn.telerik.com/2016.3.1118/js/jquery.min.js"></script>
<script src="//kendo.cdn.telerik.com/2016.3.1118/js/kendo.all.min.js"></script>
<style>
.hideDeleteButtons .k-grid-delete {
visibility: hidden;
}
</style>
</head>
<body>
<div id="example">
<p><label for="dropdownlist">Grid editing is:</label>
<select id="dropdownlist"><option value="1">enabled</option><option value="0">disabled</option></select></p>
<div id="grid"></div>
<script>
$(document).ready(function () {
$("#dropdownlist").kendoDropDownList({
change: function(e) {
$("#grid").toggleClass("hideDeleteButtons", e.sender.value() !== "1");
}
});
var crudServiceBaseUrl = "//demos.telerik.com/kendo-ui/service",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "/Products",
dataType: "jsonp"
},
update: {
url: crudServiceBaseUrl + "/Products/Update",
dataType: "jsonp"
},
destroy: {
url: crudServiceBaseUrl + "/Products/Destroy",
dataType: "jsonp"
},
create: {
url: crudServiceBaseUrl + "/Products/Create",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
batch: true,
pageSize: 10,
schema: {
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
ProductName: { validation: { required: true } },
UnitPrice: { type: "number", validation: { required: true, min: 1} },
Discontinued: { type: "boolean" },
UnitsInStock: { type: "number", validation: { min: 0, required: true } }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
navigatable: true,
pageable: true,
height: 300,
toolbar: ["create", "save", "cancel"],
columns: [
{ field: "ProductName", title: "Product Name" },
{ command: "destroy", title: " ", width: 200 }],
editable: true,
edit: function(e) {
var dropdownlist = $("#dropdownlist").data("kendoDropDownList");
if (dropdownlist.value() !== "1") {
e.sender.closeCell();
if (e.model.isNew()) {
e.sender.dataSource.remove(e.model);
}
}
}
});
});
</script>
</div>
</body>
</html>

Related

Formatters give incorrect result after sort or search

I have following code using free-jqgrid. It loads correctly for the first time (Status is “Active” and Partner? is “Yes”). But when I do a sort or search, the values become incorrect(Status is “Retired” and Partner? is “No”).
Why the formatters are giving incorrect values? How to fix this?
SCRIPT
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/themes/start/jquery-ui.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.13.6/js/jquery.jqgrid.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.13.6/css/ui.jqgrid.min.css" rel="stylesheet" />
<script type="text/javascript">
function getCurrentPractice ()
{
return "Test";
}
function getGridCaption() {
return "<div style='font-size:15px; font-weight:bold; display:inline; padding-left:10px;'><span class='glyphicon glyphicon-check' style='margin-right:3px;font-size:14px;'></span>" + getCurrentPractice() + " " + "</div>" +
"<div style='float:right; padding-right:20px; padding-bottom:10px; display:inline;>" +
"<div style='float:right;width:550px; padding-bottom:20px;'>" +
"<input type='text' class='form-control' id='filter' placeholder='Search' style='width:250px; height:30px; float:right; ' />" +
" </div>" +
"</div>";
}
$(function () {
var currentPractice = "P";
var grid = $("#list2");
grid.jqGrid({
url: '/Home/GetProviders',
datatype: "json",
postData:
{
practiceName: function () { return currentPractice }
},
colNames: [
'Practice',
'ProviderID',
'Partner?',
'Status'
],
colModel: [
{ name: 'Practice', hidden: false },
{ name: 'ProviderID', hidden: false },
{
name: 'PartnerStatusText',
width: 70,
formatter: function (cellvalue, options, rowObject) {
var isPartner = rowObject.IsPartner;
return isPartner == true ? 'Yes' : 'No';
}
},
{
name: 'ActiveStatusText',
width: 70,
formatter: function (cellvalue, options, rowObject) {
var isActive = rowObject.IsActive;
return isActive == true ? 'Active' : 'Retired';
}
}
],
ignoreCase: true,
loadonce: true,
rowNum: 25,
rowList: [15, 25, 35, 50],
pager: '#pager2',
viewrecords: true,
sortable: true,
caption: getGridCaption(),
beforeSelectRow: function (rowid, e) {
//Avoid selection of row
return false;
},
loadComplete: function () {
}
});
grid.jqGrid('navGrid', '#pager2', { edit: false, add: false, del: false });
//Filter Toolbar
$("#advancedSearch").click(function () {
grid.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false, defaultSearch: "cn" });
});
//Top Search
$("#filter").on('keyup', function () {
var searchFiler = $("#filter").val(), f;
if (searchFiler.length === 0) {
grid[0].p.search = false;
$.extend(grid[0].p.postData, { filters: "" });
}
f = { groupOp: "OR", rules: [] };
f.rules.push({ field: "Practice", op: "cn", data: searchFiler });
grid[0].p.search = true;
$.extend(grid[0].p.postData, { filters: JSON.stringify(f) });
grid.trigger("reloadGrid", [{ page: 1, current: true }]);
});
});
</script>
</head>
HTML
<div style="float:left; border:1px solid red;">
<div id="divGrid" style="width: 680px; min-height: 50px; float: left; border: 1px solid silver;">
<table id="list2"></table>
<div id="pager2"></div>
</div>
</div>
Server Code
[AllowAnonymous]
public JsonResult GetProviders(string practiceName)
{
//System.Threading.Thread.Sleep(3000);
List<Provider> providers = new List<Provider>();
Provider p = new Provider();
p.Practice = "Test1";
p.ProviderID = 1;
p.IsActive = true;
p.IsPartner = true;
providers.Add(p);
Provider p2 = new Provider();
p2.Practice = "Test2";
p2.ProviderID = 2;
p2.IsActive = true;
p2.IsPartner = true;
providers.Add(p2);
return Json(providers, JsonRequestBehavior.AllowGet);
}
UPDATE
Thanks to Oleg, working demo can be found here - Fiddle . It uses "/echo/json/" service of JSFiddle to get data from server.
It uses sorttype and additionalProperties. This can be rewritten without additionalProperties - I need to do it when I get a chance to revisit this.
The problem seems be very easy. The data returned from the server contains properties Practice, ProviderID, IsActive and IsPartner. The properties are available in rowObject during initial loading. You use additionally loadonce: true option. Thus free jqGrid will try to save some data locally, but which one? jqGrid saves by default the properties which corresponds the names of columns: Practice, ProviderID, PartnerStatusText and ActiveStatusText, but jqGrid have no information that other properties IsActive and IsPartner need be saved too.
You can solve the problem in two alternative ways:
you rename the column names PartnerStatusText and ActiveStatusText to IsActive and IsPartner.
you add the option additionalProperties: ["IsActive", "IsPartner"] to inform jqGrid to read and save locally additional properties.
Moreover, I'd recommend you to use options.rowData instead of rowObject inside of custom formatter. You can skip the 3-d parameter and to use formatter: function (cellvalue, options) {...}.
The final remark: the current code of the custom formatter is very easy. You need to replace some input values (true and false) to another text. One can use formatter: "select" for the case:
colModel: [
{ name: "Practice" },
{ name: "ProviderID" },
{
name: "IsPartner",
width: 70,
formatter: "select",
formatoptions: { value: "false:No;true:Yes" }
},
{
name: "IsActive",
width: 70,
formatter: "select",
formatoptions: { value: "false:Retired;true:Active" }
}
],
See https://jsfiddle.net/c9fge9yk/1/

How to disable the cell if the date is empty or null or undefined?

I'm new to jqgrid and jquery, can someone please help me in disabling the cell when the date is null or empty or undefined?
Actually the json for some (rows,col) date data is there and for some it is not there.
I want to disable the cell in the row for which Date data is not available.
grid cell editing POC
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" type="text/css" href="/jqGrid/jquery-ui-1.11.4.custom/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="/jqGrid/Guriddo_jqGrid_JS_5.0.1/css/ui.jqgrid.css">
<script type="text/ecmascript" src="/jqGrid/Guriddo_jqGrid_JS_5.0.1/js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="/jqGrid/jquery-ui-1.11.4.custom/jquery-ui.min.js"></script>
<script type="text/javascript" src="/jqGrid/Guriddo_jqGrid_JS_5.0.1/js/i18n/grid.locale-en.js"></script>
<script type="text/javascript">
$.jgrid.useJSON = true;
</script>
<script type="text/javascript" src="/jqGrid/Guriddo_jqGrid_JS_5.0.1/src/jquery.jqGrid.js"></script>
<script type="text/javascript">
$(function () {
"use strict";
var grid = $("#tree");
var initDateWithButton = function (elem) {
var ids = grid.jqGrid('getDataIDs');
for (var i=0;i<ids.length;i++) {
var id=ids[i];
if (grid.jqGrid('getCell',id,'assignedDate') == null) {
grid.jqGrid('setCell',id,'assignedDate','','not-editable-cell');
}
if (grid.jqGrid('getCell',id,'assignedDate') == "") {
grid.jqGrid('setCell',id,'assignedDate','','not-editable-cell');
}
if (grid.jqGrid('getCell',id,'assignedDate') == undefined) {
grid.jqGrid('setCell',id,'assignedDate','','not-editable-cell');
}
}
if (/^\d+%$/.test(elem.style.width)) {
// remove % from the searching toolbar
elem.style.width = '';
}
// to be able to use 'showOn' option of datepicker in advance searching dialog
// or in the editing we have to use setTimeout
setTimeout(function () {
$(elem).datepicker({
dateFormat: 'dd-M-yy',
showOn: 'button',
changeYear: true,
changeMonth: true,
showWeek: false,
showButtonPanel: true,
buttonImage: 'http://rcban0015:10039/GridPOC/pages/calenderIcon.gif',
onClose: function (dateText, inst) {
inst.input.focus();
}
});
$(elem).next('button.ui-datepicker-trigger').button({
text: false,
position: "relative",
top: "4px"
});
}, 100);
},
dateTemplate = {align: 'center', sorttype: 'date', editable: true,
formatter: 'date', formatoptions: { newformat: 'd-M-Y' }, datefmt: 'd-M-Y',
editoptions: { dataInit: initDateWithButton, size: 11 },
searchoptions: {
sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'],
dataInit: initDateWithButton,
size: 11, // for the advanced searching dialog
attr: {size: 11} // for the searching toolbar
}},
lastSel;
jQuery('#tree').jqGrid({
url: '<%= webAppAccess.getBackchannelActionURL("actionListjqGridPagination",false) %>',
"colModel":[
{
"name":"course_id",
"index":"course_id",
"sorttype":"int",
"key":true,
"hidden":true,
"width":50
},{
"name":"courseName",
"index":"courseName",
"sorttype":"string",
"label":"courseName",
"width":200
},{
"name":"facility",
"index":"facility",
"label":"facility",
"width":200,
"align":"left"
},{
"name":"assignedDate",
"index":"assignedDate",
"label":"assignedDate",
"width":110,
"template": dateTemplate
},{
"name":"dueDate",
"index":"dueDate",
"label":"dueDate",
"width":110,
"template": dateTemplate
},
{
"name":"AssignmentStatus",
"index":"AssignmentStatus",
"label":"AssignmentStatus",
"width":50
},{
"name":"Action",
"index":"Action",
"label":"Action",
"width":50
},
{
"name":"lft",
"hidden":true
},{
"name":"rgt",
"hidden":true
},{
"name":"level",
"hidden":true
},{
"name":"uiicon",
"hidden":true
}
],
"jsonReader": { "repeatitems": false, "root": "employees.rows" },
"toolbar": [true, "top"],
"width":"1200",
"hoverrows":false,
"viewrecords":false,
"gridview":true,
"height":"auto",
"sortname":"lft",
"loadonce":true,
"rowNum": 2,
"rowList":[2,10,15],
"scrollrows":true,
// enable tree grid
"treeGrid":true,
// which column is expandable
"ExpandColumn":"courseName",
// datatype
"treedatatype":"json",
// the model used
"treeGridModel":"nested",
// configuration of the data comming from server
"treeReader":{
"left_field":"lft",
"right_field":"rgt",
"level_field":"level",
"leaf_field":"isLeaf",
"expanded_field":"expanded",
"loaded":"loaded",
// set the ui icon field froom data
"icon_field":"uiicon"
},
"sortorder":"asc",
"datatype":"json",
"pager":"#pager",
"cellEdit": true, // TRUE = turns on celledit for the grid.
"cellsubmit" : 'clientArray',
"editurl": 'clientArray'
});
$('#t_' +"tree")
.append($("<div><label for=\"globalSearchText\">Global search in grid for: </label><input id=\"globalSearchText\" type=\"text\"></input> <button id=\"globalSearch\" type=\"button\">Search</button></div>"));
$("#globalSearchText").keypress(function (e) {
var key = e.charCode || e.keyCode || 0;
if (key === $.ui.keyCode.ENTER) { // 13
$("#globalSearch").click();
}
});
$("#globalSearch").button({
icons: { primary: "ui-icon-search" },
text: false
}).click(function () {
var postData = jQuery('#tree').jqGrid("getGridParam", "postData"),
colModel = jQuery('#tree').jqGrid("getGridParam", "colModel"),
rules = [],
searchText = $("#globalSearchText").val(),
l = colModel.length,
i,
cm;
for (i = 0; i < l; i++) {
cm = colModel[i];
if (cm.search !== false && (cm.stype === undefined || cm.stype === "text")) {
rules.push({
field: cm.name,
op: "cn",
data: searchText
});
}
}
postData.filters = JSON.stringify({
groupOp: "OR",
rules: rules
});
jQuery('#tree').jqGrid("setGridParam", { search: true });
jQuery('#tree').trigger("reloadGrid", [{page: 1, current: true}]);
return false;
});
});
</script>
</head>
<body>
<table id="tree"><tr><td></td></tr></table>
<div id="pager"></div>
</body>
</html>
There are exist alternative fork of jqGrid: free jqGrid, which I develop since more as one year. It has the functionality, where one can define editable property of colModel as function, which can return true or false based on the cell or the row content. See the wiki article for more details.
Check if this How to disable editing for soe cells in row editing of JQGrid
helps, it seen it is a similar thing, You just need to add into your logic.

kendo customised TreeList manual adding childnode unexpected result

List item
I have a page which loads a kendo TreeList by pressing a button. The data is for the moment statically defined in a variable where it stays as a basis for the Kendo TreeList datasource.
I have a datasource definition which I mostly copied from Telerik Website.
I have a treelist with a couple of requirements in terms of CRUD.
level1 - nothing
level2 - add new childnodes only
level3 - edit and delete
Edit should be doubleclick on a level3 item
CRUD command buttons need to be icon-only (no text in the buttons)
I could not achieve this with the buildin CRUD controls unfortunately so I used a Template column where the buttons are placed based on their "Type" field.
Now this has worked but after some changes which I can't undo somehow the add function does not work anymore. It works but new childnode is only visible after a edit ordelete of another node. (as if the change event is not triggered during add). The Add button in the treeList calls a function addProduct where at the end I try to pushCreate directly to the datasource. However the Transport.create is never invoked. It only gets invoked after another Crud action triggers it
Can anybody see what's wrong and couldn't this all be achieve with much easier approach?
Here's the page:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Kendo UI Grid - CRUD operations with local data</title>
<style>
html {
font-size: 12px;
font-family: Arial, Helvetica, sans-serif;
}
</style>
<link href="styles/kendo.common.min.css" rel="stylesheet" />
<link href="styles/kendo.default.min.css" rel="stylesheet" />
<script src="Scripts/jquery-2.1.3.min.js"></script>
<!--<script src="Scripts/kendo.all.min.js"></script>-->
<script src="Scripts/kendo.all.js"></script>
</head>
<body>
<style>
.hidden {
display: none;
}
.k-grid tbody .k-button, .k-ie8 .k-grid tbody button.k-button {
min-width: 0px;
padding-left: 10px;
padding-right: 0px;
padding-bottom: 0px;
padding-top: 0px;
margin: 0px;
}
</style>
<div id="buttons">
<br />
<p>
<button name="clear" id="clear" onclick="myclear()">Clear grid</button>
<button name="load" id="load" onclick="loadLocal()">Load from local DB</button>
</p>
<br />
version 1.01<br />
<br />
</div>
<div id="treelist"></div>
<script id="btn-template" type="text/x-kendo-template">
# if (Code == "Product") { #
<a id="btnupdate" class="k-button k-button-icontext k-grid-update column hidden" title="Update product" onclick="update(this)" href="\#"><span class="k-icon k-update"></span></a>
<a id="btndelete" class="k-button k-button-icontext k-grid-delete column" title="Delete product" data-command="destroy" href="\#"><span class="k-icon k-delete"></span></a>
# } else if (Code == "Requirement") { #
<a class="k-button k-button-icontext k-grid-add column" title="Add a product to this requirement" onclick="addProduct(this)" href="\#"><span class="k-icon k-add"></span></a>
# } #
</script>
<script>
var EPDdata // For holding the data of the TreeList
function loadLocal() {
EPDdata = [
{ Id: 1, Description: "Item1", Code: "Category", parentId: null },
{ Id: 2, Description: "Item2", Code: "Requirement", parentId: 1 },
{ Id: 3, Description: "Item3", Code: "Product", parentId: 2 },
{ Id: 4, Description: "Item4", Code: "Requirement", parentId: 1 },
{ Id: 5, Description: "Item5", Code: "Product", parentId: 4 },
{ Id: 6, Description: "Item6", Code: "Product", parentId: 4 },
{ Id: 7, Description: "Item7", Code: "Requirement", parentId: 1 },
{ Id: 8, Description: "Item8", Code: "Requirement", parentId: 1 },
{ Id: 9, Description: "Item9", Code: "Product", parentId: 8 },
{ Id: 10, Description: "Item10", Code: "Product", parentId: 8 }
]
LoadTree();
};
function LoadTree() {
var EPDdataNextID = EPDdata.length + 1;
var LocaldataSource = new kendo.data.TreeListDataSource({
transport: {
read: function (e) {
// on success
e.success(EPDdata);
},
create: function (e) {
// assign an ID to the new item
e.data.Id = EPDdataNextID++;
// save data item to the original datasource
EPDdata.push(e.data);
// on success
e.success(e.data);
},
update: function (e) {
// locate item in original datasource and update it
EPDdata[getIndexById(e.data.Id)] = e.data;
// on success
e.success();
},
destroy: function (e) {
// locate item in original datasource and remove it
EPDdata.splice(getIndexById(e.data.Id), 1);
// on success
e.success();
}
},
error: function (e) {
// handle data operation error
alert("Status: " + e.status + "; Error message: " + e.errorThrown);
},
pageSize: 10,
expanded: true,
batch: false,
schema: {
model: {
id: "Id",
expanded: true,
fields: {
Id: { type: "number", editable: false, nullable: true },
Description: { type: "string", validation: { required: true } },
Code: { type: "string" },
parentId: { type: "number", editable: true, nullable: true }
}
}
}
});
$("#treelist").empty(); // only 1 treelist on the page please
$("#treelist").kendoTreeList({
dataSource: LocaldataSource,
pageable: false,
edit: onEdit,
columns: [
{ field: "Description", title: "Description", width: "400px" },
{ field: "Code", width: "120px" },
{ field: "Id", title: "ID", width: "30px" },
{ field: "parentId", title: "PID", width: "30px" },
{ width: "35px", template: $("#btn-template").html() },
{ command: ["create", "edit", "destroy"] }
],
editable: "inline"
});
var treeList = $("#treelist").on("dblclick", function (e) {
var treeList = $("#treelist").data("kendoTreeList");
var rowindex = e.target.parentNode.rowIndex; // get rowindex
var tr = $(e.target).closest("tr"); // get the current table row (tr)
var dataItem = $("#treelist").data("kendoTreeList").dataItem(tr);
if (dataItem.Code == "Product") {
$("#treelist").find(".edit").addClass("hidden");
$("#treelist").find(".edit").removeClass("edit");
$("#treelist").find(".delete").removeClass("hidden");
$("#treelist").find(".delete").removeClass("delete");
treeList.saveRow(); // first save all other rows
treeList.editRow(tr[0]);
};
}); // double click function
}; // Function CreatetreeList
function onEdit(arg) {
var tr = $(arg.container);//.closest("tr"); // get the current table row (tr)
tr.find("#btndelete").addClass("hidden"); //remove btndelete from commandcolumn
tr.find("#btndelete").addClass("delete"); //put class to select the btn later on
tr.find("#btnupdate").removeClass("hidden"); //make btnupdate visible in commandcolumn
tr.find("#btnupdate").addClass("edit"); //put class to select the btn later on
};
function update(e) { // update the edited row
var tr = $(e).closest("tr"); // get the current table row (tr)
var treeList = $("#treelist").data("kendoTreeList");
treeList.saveRow();
tr.find("#btndelete").removeClass("hidden");
tr.find("#btndelete").removeClass("delete");
tr.find("#btnupdate").addClass("hidden");
tr.find("#btnupdate").removeClass("edit");
};
function addProduct(e) {
var treeList = $("#treelist").data("kendoTreeList");
var dataSource = treeList.dataSource;
var data = dataSource.data;
var tr = $(e).closest("tr"); // get the current table row (tr)
var dataItem = treeList.dataItem(tr);
dataSource.pushCreate({ Id: 15, Description: "New", Code: "Product", parentId: dataItem.Id });
alert("Done");
};
function getIndexById(id) {
var idx,
l = EPDdata.length;
for (var j; j < l; j++) {
if (EPDdata[j].Id == id) {
return j;
}
}
return null;
}
</script>
</body>
</html>
I found the answer !!!
The datasource pagesize is set to 10 and the TreeList was set to paging: false. In all my tests I started with sample data of 10 nodes. All the time I was adding an 11th and 12th record which wasn't showing up until I deleted another node...
Do these things only happen to me?

Getting only modified or new Kendo UI Grid rows to send to the server

Although I have tried several times, I could not solve trying many method.
Shortly this is the thing what I want to do : only get modified or new rows as an object or JSON string.
You should use set for changing the content of a record. Then, getting the records modified is just iterating through datasource.data() array and checking which items have dirty set to true.
var data = grid.dataSource.data();
var dirty = $.grep(data, function(item) {
return item.dirty
});
// Dirty array contains those elements modified
console.log("dirty", dirty);
The following snippet shows both that changing the data programmatically or via Grid built-in incell edition is compatible with this approach.
$(document).ready(function() {
var crudServiceBaseUrl = "http://demos.telerik.com/kendo-ui/service",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "/Products",
dataType: "jsonp"
},
update: {
url: crudServiceBaseUrl + "/Products/Update",
dataType: "jsonp"
},
destroy: {
url: crudServiceBaseUrl + "/Products/Destroy",
dataType: "jsonp"
},
create: {
url: crudServiceBaseUrl + "/Products/Create",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
batch: true,
pageSize: 20,
schema: {
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
ProductName: { validation: { required: true } },
Discontinued: { type: "boolean" }
}
}
}
});
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
navigatable: true,
pageable: true,
height: 300,
columns: [
"ProductName",
{ field: "Discontinued", width: 120 }
],
editable: "incell",
selectable: true
}).data("kendoGrid");
$("#change").on("click", function() {
var sel = grid.select();
if (sel.length) {
var item = grid.dataItem(sel);
item.set("Discontinued", true);
}
});
$("#show").on("click", function() {
var data = grid.dataSource.data();
var dirty = $.grep(data, function(item) {
return item.dirty
});
$("#logger").html(JSON.stringify(dirty, null, 2));
});
});
#logger {
min-height: 60px;
border: 1px solid black;
overflow-x: scroll
}
#grid {
width: 500px;
}
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.common.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.default.min.css" />
<script src="http://cdn.kendostatic.com/2014.3.1119/js/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1119/js/kendo.all.min.js"></script>
<div id="example">
<div>
This button changes the Discontinued field to "true" for the selected row:
<button id="change" class="k-button">Change selected</button>
</div>
<div>
Click for displaying modified rows:
<button id="show" class="k-button">Show dirty</button>
<pre id="logger"></pre>
</div>
<div id="grid"></div>
</div>

Unable to bind kendo datagrid datasource to Azure Mobile Services?

I am trying to bind kendo UI datagrid to my azure backend mobile services table (SASA) following this tutorial.
http://ignaciofuentes.com/archive/2014/01/20/zumo-kendo/
but unfortunately for some reasons it is not working. I have tried updating the mobile services javascript sdk from 1.0.0 to 1.1.5 still with no luck.
Here is my code.. can anyone point out what am I doing wrong.. the service is returning proper JSON..
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/grid/everlive">
<style>html { font-size: 12px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.1.528/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.1.528/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.1.528/styles/kendo.dataviz.min.css">
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.1.528/styles/kendo.dataviz.default.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.1.528/js/kendo.all.min.js"></script>
<div id="example">
<div id="grid"></div>
<script>
$(document).ready(function() {
var client = new WindowsAzure.MobileServiceClient("MY SERVICE URL", "MY API KEY");
var table = client.getTable("sasa");
var dataSource = new kendo.data.DataSource({
transport: {
read: function (options) {
table.includeTotalCount() //necessary for grid to paginate
.read()
.done(options.success);
},
update: function (options) {
table.update(options.data)
.done(options.success);
},
create: function (options) {
var item = options.data;
delete item.id; //ZUMO doesnt allow you to set your own ID. It gets auto generated.
table.insert(item)
.done(options.success);
},
destroy: function (options) {
table.del(options.data)
.done(options.success);
}
},
pageSize: 10,
schema: {
total: "totalCount",
model: {
id: "id",
fields: {
id: { type: "number" },
name: { type: "string" },
developer: { type: "string" },
}
}
}});
$("#grid").kendoGrid({
pageable: true,
dataSource: dataSource,
columns: [
"name",
"developer", {
command: [{
name: "edit",
text: "Edit"
}, {
name: "destroy",
text: "Delete"
}]
}],
toolbar: [{
name: "create"
}],
editable: "inline"
});
});
</script>
</div>
</body>
</html>
On a test I did a while back using a kendo datasource and a windows azure mobile service, my dataSource CRUD methods were a bit different.
create: function(options) {
delete options.data.id;
client.getTable("Customer").insert(options.data).done(function(data) {
options.success(data);
});
},
read: function(options) {
client.getTable("Customer").read().done(function(data) {
options.success(data);
});
},
update: function(options) {
client.getTable("Customer").update(options.data).done(function(data) {
options.success(data);
});
},
destroy: function(options) {
client.getTable("Customer").del(options.data).done(function(data) {
options.success(data);
});
}
And it worked properly. Perhaps try changing the .done(options.success); to
.done(function(data) {
options.success(data);
});
And see if it works ?
--edit I rebuilt my MobileService I used to test with and dug up the code, it still works properly. Here is the sample at jsbin http://jsbin.com/jirexo/2/edit

Resources