Search code examples
jquerykendo-uikendo-grid

Can only drag and drop rows that are on the unlocked side of kendo ui grid


I have a grid that uses frozen/locked columns and has drag and drop functionality. The problem is that I can only drag and drop a row on the side where columns are unlocked and this is not what I want. I would like to be able to grab a row from the locked side and drag and drop. IE, if I grab a row from the ID column, I should be able to drag and drop that. I hope that make sense

$(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>


Solution

  • The solution for this issue is

    The reason for the behaviour is that the Kendo UI Grid with locked columns creates two tables and currently the sortable widget is initialized over the table that holds the non-locked content.

    To initialize the drag and drop over the locked table, we need to use the lockedTable element.

    If you want the user to see the full row, you can get the corresponding cells from the other table by looking for the row with the same 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);
    
        }
      });
    }