I have a selectable, navigatable and editable grid. After I enter a value in a cell, I have to change the value in the cell under the updated cell. To show the updated values of both cells, I have to refresh the grid. When I do that, the edited cell loses focus. I found a way to refocus the last edited cell during the save event:
save: function (e) {
var focusedCellIndex = this.current()[0].cellIndex; //gets the cell index of the currently focused cell
//...some dataItem saving (dataItem.set()) logic...
this.refresh(); //refreshing the grid instance
setTimeout(function () { //refocusing the cell
return function () {
var focusedCell = $("#grid tr[data-uid='" + dataItem.uid + "'] td:nth-child(" + (focusedCellIndex + 1) + ")");
$('#grid').data('kendoGrid').editCell(focusedCell);
}
}(), 200);
}
The problem is that this works for the first time, but if I try to re-edit the same cell again, the cell loses focus. When I try to debug, it seems that this.current()[0].cellIndex
returns 0 in the second attempt, and because of that cell focusing isn't working anymore.
Does anyone have any idea why this.current()
works for the 1st time, and not for the 2nd time? Are there any other approaches for refocusing the cell?
It's difficult to say exactly what is happening without seeing it in a demo, so if you can, I'd suggest creating one for illustration. I'm guessing that the call to refresh
is removing the current cell selection and focusing the first cell because the grid is navigatable (I don't quite understand the rationale behind that behavior, but it's hard to say whether it's a bug since we don't get to read Telerik's code comments).
One approach that might work would be to modify the current
method to also store the current cell index:
kendo.ui.Grid.fn.refresh = (function(refresh) {
return function(e) {
this._refreshing = true;
refresh.call(this, e);
this._refreshing = false;
}
})(kendo.ui.Grid.fn.refresh);
kendo.ui.Grid.fn.current = (function(current) {
return function(element) {
// assuming element is td element, i.e. cell selection
if (!this._refreshing && element) {
this._lastFocusedCellIndex = $(element).index(); // note this might break with grouping cells etc, see grid.cellIndex() method
this._lastFocusedUid = $(element).closest("tr").data("uid");
}
return current.call(this, element);
}
})(kendo.ui.Grid.fn.current);
kendo.ui.Grid.fn.refocusLastEditedCell = function () {
if (this._lastFocusedUid ) {
var row = $(this.tbody).find("tr[data-uid='" + this._lastFocusedUid + "']");
var cell = $(row).children().eq(this._lastFocusedCellIndex);
this.editCell(cell);
}
};
That way, you should always be able to use grid.refocusLastEditedCell()
when you need to.
Another idea:
save: function (e) {
var focusedCell = this.current();
var focusedCellIndex = focusedCell.index(); //gets the cell index of the currently focused cell
//...some dataItem saving (dataItem.set()) logic...
this.refresh(); //refreshing the grid instance
// reset current cell..
this.current(focusedCell);
setTimeout(function () { //refocusing the cell
return function () {
var focusedCell = $("#grid tr[data-uid='" + dataItem.uid + "'] td:nth-child(" + (focusedCellIndex + 1) + ")");
$('#grid').data('kendoGrid').editCell(focusedCell);
}
}(), 200);
}
I don't have enough reputation to comment on the answer, but I'd like to thank you Lars Hoppner for your answer. It helped me tremendously with the annoying refresh navigation problems of Kendo Grids.
I also would like to add that for grids with horizontal scroll bars, your solution will still cause the scroll to shift as far left as possible while keeping the last edited cell in view. To prevent this bad behavior, I did the following:
grid.closeCell();
grid.refresh();
grid.refocusLastEditedCell();
Closing the cell before refreshing kept the scroll bars in place, now everything works great. Hopefully this helps anyone else viewing your answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With