Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/422.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如果条件满足,则在剑道网格中使单元格只读_Javascript_Kendo Ui_Kendo Grid_Kendo Asp.net Mvc - Fatal编程技术网

Javascript 如果条件满足,则在剑道网格中使单元格只读

Javascript 如果条件满足,则在剑道网格中使单元格只读,javascript,kendo-ui,kendo-grid,kendo-asp.net-mvc,Javascript,Kendo Ui,Kendo Grid,Kendo Asp.net Mvc,假设我有这样一个数据: [ {ID: 1, SomeForeignKeyID: 4, IsFkEnabled: true}, {ID: 2, SomeForeignKeyID: 9, IsFkEnabled: false} ] $("#grid").kendoGrid({ dataSource: dataSource, height: "300px", columns: columns, editable: true, edit: fun

假设我有这样一个数据:

[
    {ID: 1, SomeForeignKeyID: 4, IsFkEnabled: true},
    {ID: 2, SomeForeignKeyID: 9, IsFkEnabled: false}
]
$("#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
}
@(Html.Kendo().Grid()
    .Name("Grid")
    .Events(events => events.Edit("onEdit"))
)
剑道网格正在使用以下数据:

columns.Bound(m => m.ID);
columns.ForeignKey(p => p.SomeForeignKeyID, ViewBag.ForeignKeys as IEnumerable<object>, "Value", "Name");
columns.Bound(m=>m.ID);
columns.ForeignKey(p=>p.SomeForeignKeyID,ViewBag.ForeignKeys作为IEnumerable,“Value”,“Name”);

问题是:如何使ForeignKey列可编辑,但仅在行中,其中IsFkEnabled==true?编辑模式为InCell。

请尝试使用以下代码段

查看

<script type="text/javascript">  

function errorHandler(e) {  
    if (e.errors) {  
        var message = "Errors:\n";  
        $.each(e.errors, function (key, value) {  
            if ('errors' in value) {  
                $.each(value.errors, function () {  
                    message += this + "\n";  
                });  
            }  
        });  
        alert(message);  
    }  
}  

function onGridEdit(arg) {  
    if (arg.container.find("input[name=IsFkEnabled]").length > 0) {
        arg.container.find("input[name=IsFkEnabled]").click(function () {
            if ($(this).is(":checked") == false) {  

            }  
            else {  
                arg.model.IsFkEnabled = true;
                $("#Grid").data("kendoGrid").closeCell(arg.container);  
                $("#Grid").data("kendoGrid").editCell(arg.container.next());  
            }  
        });  
    }  
    if (arg.container.find("input[name=FID]").length > 0) {  
        if (arg.model.IsFkEnabled == false) {
            $("#Grid").data("kendoGrid").closeCell(arg.container)  
        }  
    }  
}  
</script>  

<div>
@(Html.Kendo().Grid<MvcApplication1.Models.TestModels>()
    .Name("Grid")
    .Columns(columns =>
    {
        columns.Bound(p => p.ID);
        columns.Bound(p => p.Name);
        columns.Bound(p => p.IsFkEnabled);
        columns.ForeignKey(p => p.FID,   (System.Collections.IEnumerable)ViewData["TestList"], "Value", "Text");

    })
    .ToolBar(toolBar => toolBar.Save())
    .Editable(editable => editable.Mode(GridEditMode.InCell))
    .Pageable()
    .Sortable()
    .Scrollable()
    .Filterable()
    .Events(e => e.Edit("onGridEdit"))
    .DataSource(dataSource => dataSource
        .Ajax()
        .Batch(true)
        .ServerOperation(false)
        .Events(events => events.Error("errorHandler"))
        .Model(model =>
        {
            model.Id(p => p.ID);
            model.Field(p => p.ID).Editable(false);
        })
    .Read(read => read.Action("ForeignKeyColumn_Read", "Home"))
    .Update(update => update.Action("ForeignKeyColumn_Update", "Home"))
    )
)
</div>
控制器

public class HomeController : Controller
{
    public ActionResult Index()
    {

        List<SelectListItem> items = new List<SelectListItem>();

        for (int i = 1; i < 6; i++)
        {
            SelectListItem item = new SelectListItem();
            item.Text = "text" + i.ToString();
            item.Value = i.ToString();
            items.Add(item);
        }

        ViewData["TestList"] = items;

        return View();
    }

    public ActionResult ForeignKeyColumn_Read([DataSourceRequest] DataSourceRequest request)
    {
        List<TestModels> models = new List<TestModels>();

        for (int i = 1; i < 6; i++)
        {
            TestModels model = new TestModels();
            model.ID = i;
            model.Name = "Name" + i;

            if (i % 2 == 0)
            {
                model.IsFkEnabled = true;

            }

            model.FID = i;


            models.Add(model);
        }

        return Json(models.ToDataSourceResult(request));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult ForeignKeyColumn_Update([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<TestModels> tests)
    {
        if (tests != null && ModelState.IsValid)
        {
            // Save/Update logic comes here  
        }

        return Json(ModelState.ToDataSourceResult());
    }
}
公共类HomeController:控制器
{
公共行动结果索引()
{
列表项=新列表();
对于(int i=1;i<6;i++)
{
SelectListItem=新建SelectListItem();
item.Text=“Text”+i.ToString();
item.Value=i.ToString();
项目。添加(项目);
}
ViewData[“TestList”]=项;
返回视图();
}
public ActionResult ForeignKeyColumn_Read([DataSourceRequest]DataSourceRequest请求)
{
列表模型=新列表();
对于(int i=1;i<6;i++)
{
TestModels model=新的TestModels();
model.ID=i;
model.Name=“Name”+i;
如果(i%2==0)
{
model.IsFkEnabled=true;
}
model.FID=i;
模型。添加(模型);
}
返回Json(models.ToDataSourceResult(request));
}
[接受动词(HttpVerbs.Post)]
public ActionResult ForeignKeyColumn_更新([DataSourceRequest]DataSourceRequest请求,[Bind(Prefix=“models”)]IEnumerable测试)
{
if(tests!=null&&ModelState.IsValid)
{
//这里有保存/更新逻辑
}
返回Json(ModelState.ToDataSourceResult());
}
}

如果要下载演示,请单击。

备注:

  • 此解决方案仅适用于单元格内编辑(内联或弹出式编辑) (需要不同的方法)
  • 第一种方法可能导致不必要的视觉效果(网格) (b)在某些情况下;如果你有这种经历,我 推荐方法#2
  • 如果您想使用MVC包装器,方法2可能不起作用(尽管可以扩展Kendo.MVC.UI.Fluent.GridEventBuilder);在这种情况下,需要在JS中绑定编辑处理程序
方法#1

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

[
    {ID: 1, SomeForeignKeyID: 4, IsFkEnabled: true},
    {ID: 2, SomeForeignKeyID: 9, IsFkEnabled: false}
]
$("#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
}
@(Html.Kendo().Grid()
    .Name("Grid")
    .Events(events => events.Edit("onEdit"))
)
()

要通过MVC fluent语法使用此功能,只需在名称上方提供匿名
edit
函数(例如
onEdit
):

并参照如下:

[
    {ID: 1, SomeForeignKeyID: 4, IsFkEnabled: true},
    {ID: 2, SomeForeignKeyID: 9, IsFkEnabled: false}
]
$("#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
}
@(Html.Kendo().Grid()
    .Name("Grid")
    .Events(events => events.Edit("onEdit"))
)
这样做的缺点是在触发编辑事件之前首先创建编辑器,这有时会产生不希望的视觉效果

方法#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);
然后使用类似于#1的方法:

这种方法的不同之处在于,编辑器不会首先被创建(和聚焦)。
beforedit
方法使用的是来自#1的相同的
isEditable
方法。 见a

如果您想在MVC包装器中使用这种方法,但不想/无法扩展GridEventBuilder,您仍然可以用JavaScript绑定事件处理程序(位于网格MVC初始值设定项下方):


这些方法都不适合我。一个非常简单的实现如下所示

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

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

最简单的方法是使用dataBound事件有条件地将一个特殊CSS类应用于网格在编辑时忽略的单元格:

  • 数据绑定:函数(e){
    var-colIndex=1;
    var rows=this.table.find(“tr:not(.k-grouping-row)”;
    对于(变量i=0;i

另一种方法是对列定义使用您自己的“编辑器”功能,该功能根据您的条件提供输入元素或普通div。

Kendo UI开箱即用不支持这一点,但您可以实现它,但干净/简单的实现取决于您使用的版本类型。它是内联的、弹出的还是插入的?Telerik,请开箱即用地实施方法2!我想知道是否有人有一个如何实现fo内联编辑的例子?@Azzi这里有一个选项:我在连接事件时遇到了问题(我正在使用MVC绑定创建网格)。最后,我在editCell实现中实现了我的整个事件处理程序。对于我的情况应该可以,因为我在页面上只有on-grid。对,对于MVC fluent Builder,如果您想使用beforedit,您可能需要扩展Kendo.MVC.UI.fluent.GridEventBuilder;我应该提到的是,如果您使用的是2017 R2之前的版本,其中添加了一个官方的BeforeEdit事件,并且您使用的是MVC包装(“剑道MVC”),那么这种破解方法是一种很好的解决方法。如果您使用它,我建议您在代码中添加一条注释,说明您为什么要hi劫持k-group-cell类,以便将来阅读您的代码的人能够理解。