0

I'm working on a project where I need to enable drag-and-drop functionality for rows within a MUI X Data Grid using React Beautiful DnD. I've set up the DataGrid and integrated React Beautiful DnD for draggable functionality, but I'm having trouble getting it to work correctly for rows.

    import React from "react";
    import { DataGrid } from "@mui/x-data-grid";
    import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
    
    const columns = [
      { field: "id", headerName: "ID", width: 90 },
      { field: "name", headerName: "Name", width: 150 },
      { field: "age", headerName: "Age", width: 90 },
    ];
    
    const rows = [
      { id: "1", name: "John Doe", age: 30 },
      { id: "2", name: "Jane Smith", age: 25 },
    ];
    
    const CustomRowWrapper = ({ data, index }) => {
       const rowStyle = {
       border: "1px solid #ddd",
       padding: "8px",
       margin: "4px 0",
       backgroundColor:"red",
       border:'5px solid black'
      };

    return (
      <Draggable draggableId={`row-${data.id}`} index={index}>
        {(provided, snapshot) => (
        <div
          ref={provided.innerRef}
          {...provided.draggableProps}
          {...provided.dragHandleProps}
          style={{
            ...provided.draggableProps.style,
            ...rowStyle,
            backgroundColor: snapshot.isDragging ? "#f0f0f0" : "inherit",
          }}
        >
          <Grid.Row {...provided.draggableProps} {...provided.dragHandleProps}>
            <Grid.Cell>{data.id}</Grid.Cell>
            <Grid.Cell>{data.name}</Grid.Cell>
            <Grid.Cell>{data.age}</Grid.Cell>
          </Grid.Row>
        </div>
       )}
     </Draggable>
    };
    
    const CustomDataGrid = () => {
      const onDragEnd = (result) => {
        console.log(result);
      };
    
      return (
        <DragDropContext onDragEnd={onDragEnd}>
          <Droppable droppableId="data-grid">
            {(provided) => (
              <div ref={provided.innerRef} {...provided.droppableProps}>
                <DataGrid
                  rows={rows}
                  columns={columns}
                  components={{
                    Row: CustomRowWrapper,
                  }}
                />
                {provided.placeholder}
              </div>
            )}
          </Droppable>
        </DragDropContext>
      );
    };
    
    export default CustomDataGrid;

I expect the rows in the DataGrid to be draggable and rearrangeable using React Beautiful DnD, but when I try to drag a row, it doesn't visually move or trigger the onDragEnd function properly. What am I missing in my implementation? How can I correctly integrate React Beautiful DnD for row drag-and-drop functionality within Material-UI's DataGrid?

1 Answer 1

0

I'm not sure if you use the current latest version of @mui/x-data-grid but, the latest version as of now is v7, you can do it like this:

import React, { useState } from 'react';
import { DataGrid, GridRow, GridCell } from '@mui/x-data-grid';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';

const columns = [
  { field: 'id', headerName: 'ID', width: 90 },
  { field: 'name', headerName: 'Name', width: 150 },
  { field: 'age', headerName: 'Age', width: 90 },
];

const rows = [
  { id: '1', name: 'John Doe', age: 30 },
  { id: '2', name: 'Jane Smith', age: 25 },
  { id: '3', name: 'User 3', age: 23 },
  { id: '4', name: 'User 4', age: 24 },
  { id: '5', name: 'User 5', age: 25 },
];

const CustomRowWrapper = ({ row, index, ...rest }) => {
  const rowStyle = {
    padding: '8px',
    margin: '4px 0',
    backgroundColor: 'red',
    border: '5px solid black',
  };

  return (
    <Draggable
      key={`row-${row.id}`}
      draggableId={`row-${row.id}`}
      index={index}
    >
      {(provided, snapshot) => (
        <GridRow
          index={index}
          row={row}
          {...rest}
          ref={provided.innerRef}
          {...provided.draggableProps}
          {...provided.dragHandleProps}
          sx={{
            ...provided.draggableProps.style,
            ...rowStyle,
            backgroundColor: snapshot.isDragging ? '#f0f0f0' : 'inherit',
          }}
        >
          <GridCell>{row.id}</GridCell>
          <GridCell>{row.name}</GridCell>
          <GridCell>{row.age}</GridCell>
        </GridRow>
      )}
    </Draggable>
  );
};

const CustomDataGrid = () => {
  const [reorderedRows, setReorderedRows] = useState(rows);

  const onDragEnd = (result) => {
    if (!result.destination) {
      return;
    }

    const newReorderedItems = Array.from(reorderedRows);
    const [removed] = newReorderedItems.splice(result.source.index, 1);
    newReorderedItems.splice(result.destination.index, 0, removed);
    setReorderedRows(newReorderedItems);
  };

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <Droppable droppableId="data-grid">
        {(provided) => (
          <div ref={provided.innerRef} {...provided.droppableProps}>
            <DataGrid
              rows={reorderedRows}
              columns={columns}
              slots={{
                row: CustomRowWrapper,
              }}
            />
            {provided.placeholder}
          </div>
        )}
      </Droppable>
    </DragDropContext>
  );
};

export default CustomDataGrid;

You can take a look at this StackBlitz for a live working example.

Note that, I've also removed StrictMode from main.jsx which is suggested in this answer.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.