如何将Kendo Hierarchical Grid与kendoSortable结合起来?

时间:2014-04-30 19:58:59

标签: jquery kendo-ui kendo-grid

我有一个kendo分层网格,我希望能够对“外部”网格进行排序。我得到了排序,但细节网格不会与其父级一起移动。

我的网格:

var grid = $("#grid").kendoGrid({
    dataSource: {
        data: [{
            Name: "Hilari",
            prodID: 1
        }, {
            Name: "Carlo",
            prodID: 2
        }, {
            Name: "Kelcie",
            prodID: 3
        }],
        schema: {
            model: {
                fields: {
                    Name: {
                        type: "string"
                    },
                    prodID: {
                        type: "number"
                    }
                }
            }
        }
    },
    columns: [{
        field: "Name"
    }],
    detailInit: detailInit
}).data("kendoGrid");

可排序:

grid.table.kendoSortable({
    filter: ">tbody >tr",
    hint: $.noop,
    cursor: "move",
    placeholder: function (element) {
        return element.clone().addClass("k-state-hover").css("opacity", 0.65);
    },
    container: "#grid tbody",
    change: function (e) {
        //     var skip = grid.dataSource.skip(),
        //     oldIndex = e.oldIndex + skip,
        //     newIndex = e.newIndex + skip,
        //     data = grid.dataSource.data(),
        //     dataItem = grid.dataSource.getByUid(e.item.data("uid"));

        //     grid.dataSource.remove(dataItem);
        //     grid.dataSource.insert(newIndex, dataItem);

    }
});

详情init:

function detailInit(e) {
    $("<div/>").appendTo(e.detailCell).kendoGrid({
        dataSource: {
            data: [{
                prodID: 1,
                Pet: "Dog"
            }, {
                prodID: 1,
                Pet: "Cat"
            }, {
                prodID: 1,
                Pet: "Fish"
            }, {
                prodID: 2,
                Pet: "Bird"
            }, {
                prodID: 2,
                Pet: "Ferret"
            }, {
                prodID: 3,
                Pet: "Snake"
            }, {
                prodID: 3,
                Pet: "Frog"
            }],
            filter: {
                field: "prodID",
                operator: "eq",
                value: e.data.prodID
            }
        },
        columns: [{
            field: "Pet"
        }]
    });
}

这是一个显示我的问题的JSBin: http://jsbin.com/fizup/1/edit

有什么想法吗?

谢谢, Hilari

2 个答案:

答案 0 :(得分:2)

你是对的。如果检查生成的HTML,您将看到子网格实际上是父网格中的另一行。

Sortable移动一行,但不检查下一行是否实际上是父网格或子网格的一部分。

你可能会做一些技巧,因为在开始移动之前折叠父级,然后正常排序并最终将其展开。

作为第一种方法,尝试在kendoSortable中定义以下事件处理程序:

start : function(e) {
    // collapse master row when starting to move
    grid.collapseRow(e.item);
},
change: function(e) {
    // expand it back
    grid.expandRow(e.item);
}

请在此处查看:http://jsbin.com/wakod/1/

然后,您可以通过检查start主要行是否实际展开来改进解决方案,并且change只有在start中您将其检测为展开时才展开。

start : function(e) {
    grid.isExpanded = $("a.k-minus", e.item).length > 0;
    grid.collapseRow(e.item);
},
change: function(e) {
    if (grid.isExpanded) {
        grid.expandRow(e.item);
    }
}

请在此处查看:http://jsbin.com/wakod/2/

答案 1 :(得分:2)

您需要稍微调整可排序的更改处理程序以修复以下问题:

  • dataSource.skip()可以返回undefined
  • 将拖动的行插入正确的位置后,您需要找到<tr>再次展开(e.item不再有效,因为插入后网格会刷新)

以下是你如何做到的:

change: function (e) {
    var skip = grid.dataSource.skip() || 0,
        oldIndex = e.oldIndex + skip,
        newIndex = e.newIndex + skip,
        uid = e.item.data("uid"),
        dataItem = grid.dataSource.getByUid(uid),
        rowToExpand;

    grid.dataSource.remove(dataItem);
    grid.dataSource.insert(newIndex, dataItem);

    if (grid.isExpanded) {
        rowToExpand = $(grid.tbody).find("tr[data-uid=" + uid + "]");
        grid.expandRow(rowToExpand);
    }
}

demo,基于OnaBai的解决方案)