如果满足条件,则在Kendo Grid中使单元格只读

And*_*zej 26 javascript kendo-ui kendo-grid kendo-asp.net-mvc

假设我有这样的数据:

[
    {ID: 1, SomeForeignKeyID: 4, IsFkEnabled: true},
    {ID: 2, SomeForeignKeyID: 9, IsFkEnabled: false}
]
Run Code Online (Sandbox Code Playgroud)

Kendo Grid正在使用这些数据:

columns.Bound(m => m.ID);
columns.ForeignKey(p => p.SomeForeignKeyID, ViewBag.ForeignKeys as IEnumerable<object>, "Value", "Name");
Run Code Online (Sandbox Code Playgroud)

这是问题所在:如何使ForeignKey列可编辑,但只能在行中,IsFkEnabled == true?编辑模式是InCell.

Lar*_*ner 43

笔记:

  • 此解决方案仅适用于单元格内编辑(内联或弹出编辑需要不同的方法)
  • 第一种方法在某些情况下会导致不必要的视觉效果(网格跳跃); 如果您遇到这种情况,我建议采用方法#2
  • 如果你想使用MVC包装器,方法#2可能不起作用(虽然可以扩展Kendo.Mvc.UI.Fluent.GridEventBuilder); 在这种情况下,您需要在JS中绑定编辑处理程序

方法#1

使用网格的编辑事件,然后执行以下操作:

$("#grid").kendoGrid({
    dataSource: dataSource,
    height: "300px",
    columns: columns,
    editable: true,
    edit: function (e) {
        var fieldName = e.container.find("input").attr("name");
        // alternative (if you don't have the name attribute in your editable):
        // var columnIndex = this.cellIndex(e.container);
        // var fieldName = this.thead.find("th").eq(columnIndex).data("field");

        if (!isEditable(fieldName, e.model)) {
            this.closeCell(); // prevent editing
        }
    }
});

/**
 * @returns {boolean} True if the column with the given field name is editable 
 */
function isEditable(fieldName, model)  {
    if (fieldName === "SomeForeignKeyID") {
        // condition for the field "SomeForeignKeyID" 
        // (default to true if defining property doesn't exist)
        return model.hasOwnProperty("IsFkEnabled") && model.IsFkEnabled;
    }
    // additional checks, e.g. to only allow editing unsaved rows:
    // if (!model.isNew()) { return false; }       

    return true; // default to editable
}
Run Code Online (Sandbox Code Playgroud)

这里的演示(2014年第一季度更新)

要通过MVC流畅语法使用它,只需将匿名edit函数放在名称上方(例如onEdit):

function onEdit(e) {
    var fieldName = e.container.find("input").attr("name");
    // alternative (if you don't have the name attribute in your editable):
    // var columnIndex = this.cellIndex(e.container);
    // var fieldName = this.thead.find("th").eq(columnIndex).data("field");

    if (!isEditable(fieldName, e.model)) {
        this.closeCell(); // prevent editing
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样引用它:

@(Html.Kendo().Grid()
    .Name("Grid")
    .Events(events => events.Edit("onEdit"))
)
Run Code Online (Sandbox Code Playgroud)

这样做的缺点是编辑器在触发编辑事件之前首先被创建,这有时会产生不良的视觉效果.

方法#2

通过editCell使用触发beforeEdit事件的变体覆盖其方法来扩展网格; 为了使用网格选项,您还需要覆盖init方法:

var oEditCell = kendo.ui.Grid.fn.editCell;
var oInit = kendo.ui.Grid.fn.init;
kendo.ui.Grid = kendo.ui.Grid.extend({
    init: function () {
        oInit.apply(this, arguments);
        if (typeof this.options.beforeEdit === "function") {
            this.bind("beforeEdit", this.options.beforeEdit.bind(this));
        }
    },
    editCell: function (cell) {
        var that = this,
            cell = $(cell),
            column = that.columns[that.cellIndex(cell)],
            model = that._modelForContainer(cell),
            event = {
                container: cell,
                model: model,
                field: column.field
            };

        if (model && this.trigger("beforeEdit", event)) {
            // don't edit if prevented in beforeEdit
            if (event.isDefaultPrevented()) return;
        }

        oEditCell.call(this, cell);
    }
});
kendo.ui.plugin(kendo.ui.Grid);
Run Code Online (Sandbox Code Playgroud)

然后使用它类似于#1:

$("#grid").kendoGrid({
    dataSource: dataSource,
    height: "300px",
    columns: columns,
    editable: true,
    beforeEdit: function(e) {
        var columnIndex = this.cellIndex(e.container);
        var fieldName = this.thead.find("th").eq(columnIndex).data("field");

        if (!isEditable(fieldName, e.model)) {
            e.preventDefault();
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

这种方法的不同之处在于编辑器不会首先被创建(和聚焦).该beforeEdit方法使用isEditable#1中的相同方法.请在此处查看此方法演示.

如果你想将此方法与MVC包装器一起使用但不希望/不能扩展GridEventBuilder,你仍然可以在JavaScript中绑定你的事件处理程序(位于网格MVC初始化器下面):

$(function() {
    var grid = $("#grid").data("kendoGrid");
    grid.bind("beforeEdit", onEdit.bind(grid));
});
Run Code Online (Sandbox Code Playgroud)

  • Telerik,请开箱即用! (6认同)

pat*_*zzi 5

这些方法都不适合我。一个非常简单的命令看起来像这样

edit: function (e) {
        e.container.find("input[name='Name']").each(function () { $(this).attr("disabled", "disabled") });       
    }
Run Code Online (Sandbox Code Playgroud)

其中edit是kendo网格声明的一部分,而Name是字段的实际名称。