This is a migrated thread and some comments may be shown as answers.

How to cancel changes of one field in one item in the DataSource?

6 Answers 430 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
Salim
Top achievements
Rank 1
Salim asked on 07 Oct 2016, 08:09 AM

Is there a way to cancel the changes of one field in one item in the DataSource?

Let us say that the user is modifying in the grid one item and he wants to cancel the changes of this item (one specific field) and not all his changes in the grid, can this be done?

6 Answers, 1 is accepted

Sort by
0
Alex Hajigeorgieva
Telerik team
answered on 10 Oct 2016, 03:13 PM
Hi Salim,

The required functionality is not available out of the box, however, you may be able to implement it with some custom coding and utilising the save event of the Kendo UI Grid as well as a custom column editor. Below are the steps I took to make this implementation possible:

- create the required input field with a cancel button by adding the columns editor setting:

http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#configuration-columns.editor

- add a boolean value whether the button was clicked via mousedown
- attach an event handler function to the save event of the Kendo UI Grid and call the preventDefault() method if the cancel button mousedown event call evaluates to true
- remember to change the boolean value within the handler function

For your convenience, a runnable demo is available at:

http://dojo.telerik.com/OjOqA

Regards,
Alex
Telerik by Progress
 
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
0
Austen
Top achievements
Rank 1
answered on 28 Dec 2018, 12:08 AM

Not to revive a dead thread but I would be copying the same title, I can create a new post if that is preferred - the dojo example linked here can cancel the changes of the currently entered text, but can't cancel a cell that has already been changed and has the dirty flag. This is easily seen in that example if you change the value and press enter then open up the editor again and click cancel.

Is the functionality I described possible? It seems that cancelling changes on a single cell basis should be common enough to be supported.

0
Alex Hajigeorgieva
Telerik team
answered on 28 Dec 2018, 02:30 PM
Hello, Austen,

The desired functionality is still not available out of the box but there are other ways to achieve the desired behaviour.

For example, we can call on the grid cancelRow() method which cancels the changes of the currently edited row. (the entire model)

Since the requirement seems to be to cancel only a certain field, we could clone the current model, cancel the row and then set the old values back to it, except the one which should remain cancelled:

https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/methods/cancelrow

var grid = $("#grid").data("kendoGrid");
var model = Object.assign({},options.model);
grid.cancelRow();
var oldModel = options.model.toJSON();
for(var prop in oldModel){
  if(prop !== "ProductName"){
    options.model.set(prop, model[prop]);
  }            
}
grid.refresh();

Here is the runnable example:

https://dojo.telerik.com/eRAzuCoK
*if you need to support IE, you would need to use an alternative for Object.assign().

Alternatively, the pristine data items are kept in an internal array that may be used. It is contained in the _pristineData data source property.

Finally, if this functionality is important to you and you feel that the Kendo UI DataSource should offer it out of the box, please log a Feature request in our portal:

https://feedback.telerik.com/kendo-jquery-ui

The popular items get selected for future implementation.

Kind Regards,
Alex Hajigeorgieva
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Austen
Top achievements
Rank 1
answered on 28 Dec 2018, 09:24 PM

Hello Alex,

Thank you for the quick reply! That was exactly what I needed. For my case we did not want to have an edit button cluttering the grid so I used a context menu and had to grab the values differently due to that. My grid is also dynamic so grabbing the field names required looking at the column index. I've pasted my code below in case someone else has the same needs.

 

@(Html.Kendo().ContextMenu()
        .Name("UndoMenu")
        .Target("#EntityGrid")
        .Filter("tr[role='row']")
        .Orientation(ContextMenuOrientation.Vertical)
        .Events(e => e.Select("onUndoMenuSelect"))
        .Items(items =>
        {           
            items.Add().Text("Undo Change");
            items.Add().Text("Undo Row Changes");
 
        })
    )

 

function onUndoMenuSelect(e)
    {
        var grid = $("#EntityGrid").data("kendoGrid");
        var rowData = [];
        var model = grid.dataItem(e.target);
        for (var i = 1; i < grid.columns.length; i++)
        {
            rowData.push({ field: grid.columns[i].field, value: model[grid.columns[i].field] });
        }
        grid.editCell(grid.current()); // Force grid to edit the selected cell since grid.cancelRow only works when a cell is in edit mode
        var cancelledFieldName = grid.columns[grid.current().context.cellIndex].field; // Use the currently selected cell's col index to find the field name
        grid.cancelRow();
 
        if (e.item.textContent == "Undo Change") { // User requested to undo one cell - change other cells to their dirty value
            for (i = 0; i < rowData.length; i++) {
                if (rowData[i].field !== cancelledFieldName) model.set(rowData[i].field, rowData[i].value);
            }
        }
        $("#contextmenu").hide();
        grid.refresh();
    }
0
Alex Hajigeorgieva
Telerik team
answered on 31 Dec 2018, 09:05 AM
Hello, Austen,

Thank you for clarifying the UI, it is something that has been missing from the scenario.

Based on this new knowledge and the provided code, I have a couple of recommendations:

1) Since the grid is not in edit mode, you may use the grid data source cancelChanges method instead of having to put the cell in edit mode:

https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/cancelchanges

2) Use the public API to determine the cell index as it should work in all scenarios (reorderable, hidden columns, etc.)

https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/methods/cellindex

For this to work with the current implementation the filter of the context menu should be modified to use the cell, let me know if this causes any issues. Here is the logic on the select event of the context menu:

var grid = $("#grid").data("kendoGrid");
var cellIndex = grid.cellIndex(e.target);
var dataItem = grid.dataItem(e.target.closest("tr"));
var dataItemClone = Object.assign({}, dataItem);
 
grid.dataSource.cancelChanges(dataItem);
 
var props = dataItem.toJSON();
for(var prop in props){
  if(grid.columns[cellIndex].field !=prop){
    dataItem.set(prop, dataItemClone[prop]);                 
  }              
}
grid.refresh();

https://dojo.telerik.com/@bubblemaster/uDEPUCiF

Kind Regards,
Alex Hajigeorgieva
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Austen
Top achievements
Rank 1
answered on 31 Dec 2018, 04:48 PM

Hello Alex,

Thank you for your response, this is a much cleaner approach - I'm definitely still learning the ins and outs of kendo. I've implemented this change and it's working great!

Best,

Austen

Tags
Data Source
Asked by
Salim
Top achievements
Rank 1
Answers by
Alex Hajigeorgieva
Telerik team
Austen
Top achievements
Rank 1
Share this question
or