Cancel Changes per Row by Using the Incell Editing Mode of the Grid
Environment
Product | Progress® Kendo UI® Grid for jQuery |
Operating System | Windows 10 64bit |
Browser | Google Chrome |
Browser Version | 58.0.3029.110 |
Product Version | 2020.3.1021 |
Description
I use a Grid with a remote Datasource with the batch:true
setup. The Grid is in the incell editing mode. The toolbar of the Grid has the create
, save,
and cancel
commands. The problem is that the cancel
command discards all made changes.
In other words, I need my Grid to have both of the following commands:
1. The cancel
command of the row which discards only the changes of the corresponding row, and
1. The cancel
command of the toolbar which discards all changes that are made.
How can I provide a cancel
command per row and at the same time keep the above configurations?
Suggested Workarounds
The Kendo UI Grid does not provide a built-in solution for achieving this behavior. However, you can still work around this issue by applying custom logic.
- Add a custom button.
- On the button click, get the item by
Uid
. - Call
cancelChanges
only for that item.
Important
This approach will prevent the item from being updated in the database. However, the old values will be visually reverted after
cancelChanges
.
For more details, refer to the following articles:
- https://docs.telerik.com/kendo-ui/api/javascript/data/datasource\/methods/getbyuid
- https://docs.telerik.com/kendo-ui/api/javascript/data/datasource\/methods/cancelchanges
- https://docs.telerik.com/kendo-ui/api/javascript/ui/grid\/configuration/columns.command
To resolve the resulting scroll-related issue which occurs after the refresh, restore the scroll position by using a custom approach.
<div id="example">
<div id="grid"></div>
<script>
$(document).ready(function () {
var scrollOffset = {
left: 0,
top: 0
};
var crudServiceBaseUrl = "https://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 } },
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,
dataBound:function(e){
var container = e.sender.wrapper.children(".k-grid-content"); // or ".k-virtual-scrollable-wrap"
container.scrollLeft(scrollOffset.left);
container.scrollTop(scrollOffset.top); // use only if virtual scrolling is disabled
},
height: 550,
toolbar: ["create", "save", "cancel"],
columns: [
"ProductName",
{ field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: 120 },
{ field: "UnitsInStock", title: "Units In Stock", width: 120 },
{ field: "Discontinued", width: 120 },
{ command: [{
name: "Cancel",
click: function(e) {
// prevent page scroll position change
e.preventDefault();
//console.log(e.toElement.offsetParent.parentElement)
var row = e.target.closest('tr')
var uid = $(row).data(uid)
dataSource = $("#grid").data("kendoGrid").dataSource
var item = dataSource.getByUid(uid.uid);
dataSource.cancelChanges(item);
var container = this.wrapper.children(".k-grid-content"); // or ".k-virtual-scrollable-wrap"
scrollOffset.left = container.scrollLeft();
scrollOffset.top = container.scrollTop();
this.refresh()
}
}]
}],
editable: true
});
});
</script>
</div>