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:
- The
cancel
command of the row which discards only the changes of the corresponding row, and - 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>