只能拖放剑道UI网格未锁定侧的行



我有一个使用冻结/锁定列并具有拖放功能的网格。问题是我只能在解锁列的一侧拖放一行,这不是我想要的。我希望能够从锁定的一侧抓取一行并拖放。IE,如果我从 ID 列中抓取一行,我应该能够拖放它。我希望这是有道理的

$(document).ready(() => {
  $.when(LoadGrid()).then(EnableDragAndDropForGrid());
});
let ds = [{
    id: 1,
    name: "Jane",
    lastname: "Doe",
    age: 25,
    gender: "female",
    city: "London"
  },
  {
    id: 2,
    name: "John",
    lastname: "Doe",
    age: 26,
    gender: "male",
    city: "London"
  },
  {
    id: 3,
    name: "James",
    lastname: "Jones",
    age: 30,
    gender: "male",
    city: "New York"
  },
  {
    id: 4,
    name: "Mary",
    lastname: "Johnson",
    age: 23,
    gender: "female",
    city: "Paris"
  },
  {
    id: 5,
    name: "Robert",
    lastname: "Lee",
    age: 44,
    gender: "male",
    city: "Berlin"
  }
];
function LoadGrid() {
  $("#grid").kendoGrid({
    schema: {
      model: {
        fields: {
          id: {
            type: "number"
          },
          name: {
            type: "string"
          },
          lastname: {
            type: "string"
          },
          age: {
            type: "number"
          },
          gender: {
            type: "string"
          },
          city: {
            type: "string"
          }
        }
      }
    },
    columns: [{
        title: "id",
        field: "id",
        width: 100,
        locked: true
      },
      {
        title: "First",
        field: "name",
        locked: true,
        width: 150
      },
      {
        title: "Last",
        field: "lastname",
        locked: true,
        width: 150
      },
      {
        title: "Age",
        field: "age",
        width: 100
      },
      {
        title: "Gender",
        field: "gender",
        width: 100
      },
      {
        title: "City",
        field: "city",
        width: 100
      }
    ],
    dataSource: {
      data: ds
    },
    sortable: true
  });
}
function EnableDragAndDropForGrid() {
  let grid = $('#grid').data('kendoGrid');
  grid.table.kendoSortable({
    filter: ">tbody >tr",
    hint: function(element) {
      let table = $('<table style="width: 600px;" class="k-grid k-widget"></table>'),
        hint;
      table.append(element.clone());
      table.css("opacity", 0.7);
      return table;
    },
    cursor: "move",
    placeholder: function(element) {
      return $('<tr colspan="4" class="placeholder"></tr>');
    },
    change: function(e) {
      let 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);
    }
  });
}
.k-grid tbody tr {
  cursor: move;
}
.placeholder {
  outline-style: dashed;
  outline-width: 1px;
  outline-color: red;
}
#grid {
  width: 600px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.1.220/js/kendo.all.min.js"></script>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.common.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.rtl.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.silver.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.mobile.all.min.css" />
<div id="grid"></div>

此问题的解决方案是

该行为的原因是具有锁定列的剑道 UI 网格创建了两个表,并且当前可排序小部件在保存非锁定内容的表上初始化。

要初始化在锁定表上的拖放,我们需要使用 lockedTable 元素。

如果您希望用户看到整行,可以通过查找具有相同 data-uid 的行从另一个表中获取相应的单元格

function EnableDragAndDropForGrid() {
  let grid = $('#grid').data('kendoGrid');
  console.log(grid)
  grid.lockedTable.kendoSortable({
    filter: ">tbody >tr",
    hint: function(element) {
      var unlockedPortion = grid.table.find("tr[data-uid=" + element.data("uid") + "]").children();
      
      let table = $('<table style="width: 600px;" class="k-grid k-widget"></table>'),
        hint;
      table.append(element.clone().append(unlockedPortion));
      table.css("opacity", 0.7);
      return table;
    },
    cursor: "move",
    placeholder: function(element) {
      return $('<tr colspan="4" class="placeholder"></tr>');
    },
    change: function(e) {
      let 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);
    }
  });
}

因此,我通过创建一个函数来解决此问题,该函数可以在创建具有锁定列的可拖动网格后调用。不幸的是,网格的 rowReorder 事件从未被调用。

喜欢这个:

let myGrid = $("#myGrid").kendoGrid({
   reorderable: {
      rows: true,
   },
   rowReorder: function(ev) {
     // doesn't seem to work with locked columns.
   },
   // rest of options
}).data("kendoGrid");
//Optionally pass a callback function as the second parameter. 
//It will get the same parameters as the rowReorder function should have gotten.
enableKendoGridLockedDND("#myGrid", reorderHappened);
function reorderHappened(e) {
    console.log(e);
}

这是函数:

// You can pass a function as the second parameter which will be called on change.
// The on change function will receive information from the change event and
// pass it back as a parameter to the function you pass.
// Access it like myFunction(e). 
function enableKendoGridLockedDND(gridElement, onChangeFunction) {
    if (!gridElement) {
        gridElement = ".k-grid";
    }
    let grid = $(gridElement).data("kendoGrid");
    if (!grid.lockedTable) {
        console.info("The function enableKendoGridLockedDND was called on a table without any locked columns");
        return false;
    }
    let gridWidth = $(gridElement).width();
    let lockedWidth = $(gridElement).find(".k-grid-header-locked").width() || 0;
    let unlockedWidth = $(gridElement).find(".k-grid-header-wrap table").width() || 0;
    let tableWidth = lockedWidth + unlockedWidth + 2;
    let placeholderPosition = null;
    grid.lockedTable.kendoSortable({
        axis: "y",
        filter: ">tbody >tr",
        hint: function(element) {
            let unlockedPortion = grid.table.find("tr[data-uid=" + element.data("uid") + "]").children();
            let hint = $(`<div style="overflow: hidden; width: ${gridWidth}px;"><table style="background: whitesmoke; width: ${tableWidth}px;" class="k-grid k-widget"></table></div>`);
            let colgroups = $(gridElement).find(".k-grid-header colgroup");
            let colgroupWidths = [];
            $.each(colgroups, function (index, group) {
                $.each($(group).children(), function (index2, child) {
                    colgroupWidths.push($(child).css("width"));
                });
            });
            hint.find("table").append(element.clone().append(unlockedPortion.clone()));
            $.each(hint.find("td"), function (index, col) {
                $(col).css("width", colgroupWidths[index]);
            });
            hint.css("opacity", 0.7);
            return hint;
        },
        cursor: "move",
        placeholder: function (element) {
            var unlockedRow = grid.table.find("tr[data-uid=" + element.data("uid") + "]");
            $(unlockedRow).before($(unlockedRow).clone().attr("data-uid", "").addClass("k-hover unlocked-placeholder"));
            $(unlockedRow).hide();
            let placeholder = element.clone();
            $(placeholder).attr("data-uid", "");
            return placeholder;
        },
        move: function (e) {
            //Set positions
            let lastPosition = placeholderPosition;
            placeholderPosition = this.indexOf(this.placeholder);
            let itemPosition = this.indexOf(e.item);
            let targetPosition = this.indexOf(e.target);
            //Get Elements
            let unlockedDraggingRow = $(gridElement).find(".k-grid-content tr.unlocked-placeholder");
            let targetElement = $(gridElement).find(".k-grid-content tr[data-uid=" + e.target.data("uid") + "]");
            //Find direction of move
            let movingUp = false; 
            if (lastPosition === null) {
                if (itemPosition > targetPosition) {
                    movingUp = true;
                }
            } else {
                if (lastPosition > placeholderPosition) {
                    movingUp = true;
                }
            }
            //Move the unlocked row
            if (movingUp) {
                targetElement.before(unlockedDraggingRow);
            } else {
                targetElement.after(unlockedDraggingRow);
            }
        },
        change: function (e) {
            let skip = grid.dataSource.skip() || 0;
            let newIndex = e.newIndex + skip;
            let dataItem = grid.dataSource.getByUid(e.item.data("uid"));
            grid.dataSource.remove(dataItem);
            grid.dataSource.insert(newIndex, dataItem);
            // Custom function to call
            if (typeof onChangeFunction === "function") {
                e.skip = skip;
                e.newWithSkip = newIndex;
                e.oldWithSkip = e.oldIndex + skip;
                onChangeFunction(e);
            }
        },
        start: function () {
            placeholderPosition = null;
        }
    });
}

我还在这里发布了这个答案的一个版本:[Telerik Kendo UI Jquery Forum][https://www.telerik.com/forums/grid-with-locked-column-and-drag-and-drop]

最新更新