I have a grid with a datasource loaded locally (not using transport). I was able to create a custom editor which adds checkboxes to a row when user clicks "edit" button. Can't use the default editor since I have to do a per-field check to see if user is authorized to change a field.
Clicking "edit" button does what I expect, it displays checkboxes where it should. However, upon changing data and clicking "update" button, the row deletes. Or when in "edit" mode and user clicks another "edit" button in a different row, the original row deletes or console error about null data.
Update event never seems to fire either so that I can manually handle updating data source.
dataSource = new kendo.data.DataSource({
data: result,
change: function(e){
console.log('a change happened');
console.log(e);
},
schema: {
model: {
id: "uid",
fields: {
lastName: {editable:false},
firstName: {editable:false},
email: {editable:false},
accountNum: {editable:false},
email: {editable:false},
status: {editable:true},
RQ:{editable:true, type:"boolean"},
RR:{editable:true, type:"boolean"},
ER:{editable:true, type:"boolean"},
}
}
},
batch: true,
pageSize: 50
});
$("#grid").kendoGrid({
dataSource: dataSource,
editable: "inline",
pageable: {
refresh: false,
pageSize: 50,
pageSizes: [
50,
100,
200
]
},
filterable: {
extra: false,
operators: {
string: {
contains: "Contains",
startswith: "Starts with"
},
}
},
reorderable: true,
resizable: true,
columns: columnsettings,
edit: function(e){
//$('#grid').data('kendoGrid').dataSource.read();
console.log('an edit happened');
console.log(e);
//e.preventDefault();
},
cancel: function(e){
//$('#grid').data('kendoGrid').dataSource.read();
//$('#grid').data('kendoGrid').dataSource.sync();
console.log('cancel happened');
console.log(e);
//e.preventDefault();
$('#grid').data('kendoGrid').dataSource.read();
},
update: function(e){
console.log('an update happened');
console.log(e);
},
change: function(e){
console.log('a change happened not datasource one');
console.log(e);
},
saveChanges: function(e){
console.log('a save is about to occurr');
console.log(e);
},
// get grid state to save to DB
dataBound: function(e){
var grid = this;
var dataSource = this.dataSource;
var state = kendo.stringify({
page: dataSource.page(),
pageSize: dataSource.pageSize(),
sort: dataSource.sort(),
group: dataSource.group(),
filter: dataSource.filter()
});
}
});
function customInlineEditor(container, options){
var currentField = options.field;
var inputField;
if(options.model[currentField] === true){
inputField = $('<input type="checkbox" data-value-field="'+currentField+'" name="'+currentField+'" checked>');
}else if(options.model[currentField] === false){
inputField = $('<input type="checkbox" name="'+currentField+'">');
}else{
//inputField = "Locked";
}
container.append(inputField);
}
I have a grid with a datasource loaded locally (not using transport). I was able to create a custom editor which adds checkboxes to a row when user clicks "edit" button. Can't use the default editor since I have to do a per-field check to see if user is authorized to change a field.
Clicking "edit" button does what I expect, it displays checkboxes where it should. However, upon changing data and clicking "update" button, the row deletes. Or when in "edit" mode and user clicks another "edit" button in a different row, the original row deletes or console error about null data.
Update event never seems to fire either so that I can manually handle updating data source.
dataSource = new kendo.data.DataSource({
data: result,
change: function(e){
console.log('a change happened');
console.log(e);
},
schema: {
model: {
id: "uid",
fields: {
lastName: {editable:false},
firstName: {editable:false},
email: {editable:false},
accountNum: {editable:false},
email: {editable:false},
status: {editable:true},
RQ:{editable:true, type:"boolean"},
RR:{editable:true, type:"boolean"},
ER:{editable:true, type:"boolean"},
}
}
},
batch: true,
pageSize: 50
});
$("#grid").kendoGrid({
dataSource: dataSource,
editable: "inline",
pageable: {
refresh: false,
pageSize: 50,
pageSizes: [
50,
100,
200
]
},
filterable: {
extra: false,
operators: {
string: {
contains: "Contains",
startswith: "Starts with"
},
}
},
reorderable: true,
resizable: true,
columns: columnsettings,
edit: function(e){
//$('#grid').data('kendoGrid').dataSource.read();
console.log('an edit happened');
console.log(e);
//e.preventDefault();
},
cancel: function(e){
//$('#grid').data('kendoGrid').dataSource.read();
//$('#grid').data('kendoGrid').dataSource.sync();
console.log('cancel happened');
console.log(e);
//e.preventDefault();
$('#grid').data('kendoGrid').dataSource.read();
},
update: function(e){
console.log('an update happened');
console.log(e);
},
change: function(e){
console.log('a change happened not datasource one');
console.log(e);
},
saveChanges: function(e){
console.log('a save is about to occurr');
console.log(e);
},
// get grid state to save to DB
dataBound: function(e){
var grid = this;
var dataSource = this.dataSource;
var state = kendo.stringify({
page: dataSource.page(),
pageSize: dataSource.pageSize(),
sort: dataSource.sort(),
group: dataSource.group(),
filter: dataSource.filter()
});
}
});
function customInlineEditor(container, options){
var currentField = options.field;
var inputField;
if(options.model[currentField] === true){
inputField = $('<input type="checkbox" data-value-field="'+currentField+'" name="'+currentField+'" checked>');
}else if(options.model[currentField] === false){
inputField = $('<input type="checkbox" name="'+currentField+'">');
}else{
//inputField = "Locked";
}
container.append(inputField);
}
Share
Improve this question
asked Oct 29, 2013 at 16:38
cartercarter
5,4625 gold badges33 silver badges40 bronze badges
2 Answers
Reset to default 3Kendo Grid without transports defined is designed to just 'display' the data, not to edit it. What you can do instead of using event handlers for events such as 'save', 'update', 'edit' is to declare the transport operations as functions.
var data = [
{ Id: 1, Name: "Decision 1", Position: 1 },
{ Id: 2, Name: "Decision 2", Position: 2 },
{ Id: 3, Name: "Decision 3", Position: 3 }
];
var dataSource = new kendo.data.DataSource({
//data: data,
transport: {
read: function(e) {
e.success(data);
},
update: function(e) {
e.success();
},
create: function(e) {
var item = e.data;
item.Id = data.length + 1;
e.success(item);
}
},
Here is an example that should be working fine.
Although this is late in the game, I thought it would benefit others to see an entire data source.
One problem with some of the Kendo-related documentation, is that some of the examples don't go far enough and reflect actual real-world implementation.
return new kendo.data.DataSource({
type: "odata",
transport: {
read:
function (options) {
var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read");
dataFactory.getList(odataParams)
.success(function (result) {
options.success(result);
})
.error(function (error) {
console.log("data error");
});
//$http({
// url: crudServiceBaseUrl,
// method: 'GET',
// params: odataParams
//})
//.success(function (result) {
// options.success(result);
//});
},
//{
// url: crudServiceBaseUrl,
// dataType: "json"
//},
// {function (options) {
// //var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read"); // "{"take":"10","skip":"0","page":"1","pageSize":"10"}"
// (new abstractFactory2().query({ odataUrl: crudServiceBaseUrl })).$getAll()
// .then(function (data) {
// return options.success(data);
// });
//var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read"); // "{"take":"10","skip":"0","page":"1","pageSize":"10"}"
//contentTypeFactory.getList()
// .success(function (data) {
// return options.success(data);
// })
// .error(function (error) {
// console.log(error);
// });
//},
update:
function (options) {
//var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "update");
var data = options.data;
dataFactory.update(data.ContentTypeId, data)
.success(function (result) {
// call standard error message function
customFunctions.showConfirmation();
options.success(result);
})
.error(function (error) {
customFunctions.showError("Update Failed"); // use default error message
console.log("data error");
});
//{ // PUT
//url: function (data) {
// console.log(data);
// dataType: "json"
// return crudServiceBaseUrl + "(" + data.ContentTypeId + ")";
//},
//error: function (e) {
// console.log("error: " + e);
//}
},
create:
function (options) {
var data = options.data;
data.ContentTypeId = "0"; // required for valid field data
dataFactory.insert(data)
.success(function (result) {
options.success(result);
})
.error(function (error) {
customFunctions.showError("Create Failed"); // use default error message
});
//{ // POST
//data: function (data) {
// // reformat the data to match the DTO
// data.ContentTypeId = "0";
// data.NumberOfContentTypes = "0";
// //data.msrepl_tran_version = "00000000-0000-0000-0000-000000000000";
// return data;
//},
//url: function (data) {
// console.log(data);
// return crudServiceBaseUrl;
//},
//error: function (e) {
// console.log("create error: " + e);
//},
//dataType: "json",
},
destroy:
function (options) {
var data = options.data;
dataFactory.remove(data.ContentTypeId)
.success(function (result) {
options.success(result);
})
.error(function (error) {
console.log("data error");
});
//{
//url: function (data) {
// dataType: "json";
// return crudServiceBaseUrl + "(" + data.ContentTypeId + ")";
//},
//success: function (e) {
// console.log("success");
//},
//error: function (e) {
// console.log(e);
//}
},
parameterMap: function (options, type) {
// this is optional - if we need to remove any parameters (due to partial OData support in WebAPI
if (operation !== "read" && options.models) {
return JSON.stringify({ models: options });
}
//var parameterMap = kendo.data.transports.odata.parameterMap(options);
//delete parameterMap.$inlinecount; // remove inlinecount parameter
//delete parameterMap.$format; // remove format parameter
//return parameterMap;
},
},
batch: false,
pageSize: 10,
serverPaging: true,
change: function (e) {
console.log("change: " + e.action);
// do something with e
},
schema: {
data: function (data) {
//console.log(data)
return data.value;
},
total: function (data) {
console.log("count: " + data["odata.count"]);
return data["odata.count"];
},
model: {
id: "ContentTypeId",
fields: {
ContentTypeId: { editable: false, nullable: true },
//UserId: {editable: false, nullable: false },
Description: { type: "string", validation: { required: true } },
//msrepl_tran_version: { type: "string", validation: { required: true } }
}
}
},
error: function (e) {
//var response = JSON.parse(e.responseText);
var response = e.status;
console.log(response);
}
}) // dataSource
This is full KendoUI OData datasource and initially used the default KendoUI way of doing things (mented out sections in the different transport sections - left in for reference). What's different about this is that it exposes the Kendo options and stores them in odataParams
, then passes them off to an AngularJS factory provider that handles the munication.
Take note of the parameterMap:
section, and set a break-point there to see what goes through there, for reference.
There is some additional debugging console.log()
's put in there.
Hope this is of benefit.