Search code examples
javascriptreactjsdrag-and-dropag-grid

ag-grid prevent rowDrop


I have an ag-grid with row dragging enabled. I need the user to be able to drag and drop all rows except for the first row. The first row must remain in place at index 0. The issue I am seeing is that, while my code below works just fine to disable dragging the row at index 0, users can still drop other rows into index 0. I want to prevent this.

Here is a simplified version of my component:

import React, { useState } from 'react'
import { AgGridReact } from 'ag-grid-react';

const AgGrid = () => {
  const [gridApi, setGridApi] = useState(null)
  const [rowData, setRowData] = useState([
    {Name: "name1", Type: "type1", Draggable: false},
    {Name: "name2", Type: "type2", Draggable: true},
    {Name: "name3", Type: "type", Draggable: true}
  ]}

  const columnDefs= [
    {
      field: 'Name',
      rowDrag: ({data}) => data.Draggable
    },{
      field: 'Type'
    }
  ]
  
  return (
    <div className="ag-theme-alpine">
      <AgGridReact
        rowData={rowData}
        columnDefs={columnDefs}
        onGridReady{(params) => setGridApi(params.api)}
        rowDragManaged={true}
      />
    </div>
  )
})

I hoped there would be a rowDrop prop or some mechanism by which to keep a row in place, but I can not seem to find it if something like that exists.

Note

I tried unmanaged dragging, but found myself writing a ton of logic just to keep that single row in place. If there was a simple onRowDragStarted and onRowDragEnded event, it would certainly be simpler to implement. I ran into a lot of issues because of the behavior described on their website, and quoted below:

"If the drag is finished outside of the grid, then the rowDragLeave is the last event fired and no rowDragEnd is fired".

Any help would be tremendously appreciated!


Solution

  • Use the rowDragMove event and don't let the row at index 0 move at all, and don't allow any row to move to index 0.

    While using unmanaged row dragging, set the rowDragMove event to:

      onRowDragMove = (event) => {
        if (event.node.id === 0)
        {
          return;
        }
        var movingNode = event.node;
        var overNode = event.overNode;
        var rowNeedsToMove = movingNode !== overNode;
        if (rowNeedsToMove) {
          var movingData = movingNode.data;
          var overData = overNode.data;
          var fromIndex = immutableStore.indexOf(movingData);
          var toIndex = immutableStore.indexOf(overData);
          var newStore = immutableStore.slice();
          moveInArray(newStore, fromIndex, toIndex);
          immutableStore = newStore;
          this.gridApi.setRowData(newStore);
          this.gridApi.clearFocusedCell();
        }
        function moveInArray(arr, fromIndex, toIndex) {
          if (toIndex === 0)
          {
            toIndex = 1;
          }
          var element = arr[fromIndex];
          arr.splice(fromIndex, 1);
          arr.splice(toIndex, 0, element);
        }
      };
    

    Demo.