刷新后重新聚焦Kendo网格单元格

4

我有一个可选择、可导航、可编辑的网格。在我输入单元格中的值之后,我必须更改更新单元格下方的单元格中的值。为了显示两个单元格的更新值,我必须刷新网格。当我这样做时,编辑的单元格失去焦点。我找到了一种在保存事件期间重新聚焦上次编辑的单元格的方法:

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);
}

问题在于第一次有效,但如果我尝试再次编辑同一个单元格,该单元格就会失去焦点。当我尝试调试时,似乎 this.current()[0].cellIndex 在第二次尝试中返回0,因此单元格聚焦不再起作用。你是否有任何想法为什么this.current()只有第一次有效而第二次无效?还有其他重新聚焦单元格的方法吗?
2个回答

7

没有看到演示很难确定具体情况,如果可以的话,建议创建一个演示来进行说明。我猜测调用refresh会取消当前的单元格选择并将焦点放在第一个单元格上,因为该网格可以被导航(我不太明白这种行为的理由,但由于我们无法阅读Telerik的代码注释,很难说它是否是一个错误)。

可能有效的一种方法是修改current方法,也将当前单元格索引存储下来:

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);
    }
};

这样,当您需要时,您应该始终能够使用 grid.refocusLastEditedCell()

另一个想法:

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);
}

谢谢,我认为我们的第一种方法很有成效。_lastFocusedCellIndex现在一直在工作。但是,例如,如果我编辑第3行的第10个单元格,它将被重新聚焦;如果我再次编辑它,焦点将转移到第1行的第10个单元格。所以,我只需要获取最后一个聚焦单元格所在行的行索引(或uid)。我尝试使用您版本的kendo.ui.Grid.fn.current扩展this._lastFocusedCell = $(element);,然后获取单元格的dataItem,但第二次返回网格的第一个dataItem。 - tstancin
1
你不应该使用 DOM 元素的引用,因为当网格刷新时它们会被替换;我更新了我的答案。 - Lars Höppner
非常感谢,它正在工作,甚至在IE中也是如此 :) 我会给你做出的每个评论或答案+1,但我还没有足够的声望 :) - tstancin
我没有在网格中使用过验证器,所以我不知道;如果编辑无效,我期望它在第一时间阻止保存事件,因此在这种情况下,甚至不应该刷新。这可能太复杂了,在评论中难以解决。 - Lars Höppner
1
不确定我理解你在做什么;如果你调用editCell(cell)并希望记住该单元格,你也可以显式地调用current(cell)。 - Lars Höppner
显示剩余5条评论

4

我没有足够的声望来对答案进行评论,但我想感谢Lars Hoppner提供的答案。您的答案帮助我解决了Kendo Grid刷新导航问题。

我还想补充一点,对于有水平滚动条的网格,您的解决方案仍然会导致滚动条向最左边移动,同时保持最后编辑的单元格可见。为了避免这种不良行为,我采取了以下措施:

grid.closeCell();
grid.refresh();
grid.refocusLastEditedCell();

关闭单元格然后刷新可以保持滚动条的位置,现在一切运行良好。希望这可以帮助其他查看你回答的人。

1
您还可以保存和恢复具有滚动条的DOM元素(使用常规滚动的.k-scrollbar-horizontal/vertical或使用虚拟滚动时的.k-virtual-scrollable-wrap)的$.scrollTop和$.scrollLeft值。 - Lars Höppner
我还没有尝试过那个方法,听起来应该是可行的。但我的唯一担忧是用户可能会看到网格在快速来回滚动时出现"闪烁"。不过我还没有确认过这一点。 - ruhler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接