NextJS/Drag & Drop /

How to add Drag and Drop in next.js?

Published on

How to add Drag and Drop in next.js?
Drag and Drop is a pointing device gesture in which the user selects a virtual object by "grabbing" it and dragging it to a different location. In this blog, we will learn how to add a Drag and Drop feature in the next js application using React DND.

Introduction :

Next js :

Next.js is a React framework. Next.js is constitutionally an excellent tool to achieve great SEO performance. building super fast static websites that behave dynamically. Next.js when building UI and UX there is flexibility. and the important great community support. To know more about relative links click here.

Drag and Drop :

Drag and drop is a functionality by which users can select an object or a section of text and can move it to the desired location and "drop" it there. Drag and drop is a part of most graphical user interfaces.

Flow Diagram:



d&d flow diagram

Prerequisites :

  • next.js

Steps:

Step 1: Installing Library’s

  • If you already have the React.js project, please copy the project. In this blog, we are using a sample React.js project code with Tailwind CSS.

  • After creating a React project install "react-dnd". using the following command.

1npm i react-dnd
  • And then install "react-dnd-html5-backend". using the following command.

1npm i react-dnd-html5-backend

Step 2: Creating Component

  • Create a component folder inside the React Project.

Drop → component

  • Inside the component folder, create a filename with a .js extension with your preferred name (e.g. DragFile.js ). As shown in the following screenshot.



folder structue

Step 3: Creating DragCard.js file

Drop → pages

  • Inside the pages folder, creates a filename with a .js extension with your preferred name (e.g. DragCard.js ) in the above path. As shown in the following screenshot.



folder structue 2

Drop → pages→DragCard.js

  • Update the DragCard.js in the above path.

  • For this example, we are using the useDrag from react-dnd, so we have imported the same here. using the following snippet.

1import { useDrag } from "react-dnd";
  • In the DragCard function use useDrag hooks. Inside the useDrag hooks set a type and also type is required. It is used by the "accept" specification of drop targets.

  • The collect function utilizes a monitor instance.

1export const DragCard = ({ name }) => { 2 const [{ isDragging }, dragRef] = useDrag({ 3 type: "language", 4 item: { name }, 5 collect: (monitor) => ({ 6 isDragging: monitor.isDragging(), 7 }), 8 }); 9 10 return ( 11 <div> 12 <div ref={dragRef}> 13 {name} 14 {isDragging && "📂"} 15 </div> 16 </div> 17 ); 18};

Sample code for the /pages/DragCard.js file can be found in the following Github URL.

Step 4: Update the DragFile.js file

Drop → component →DragFile

  • Update the DragFile.js in the above path,

  • For this example, we are using the DragCard file, so we have imported the same here. using the following snippet.

1import { DragCard } from "../pages/DragCard";
  • In this Example we using mock data for Mapping. using the following snippet.

1const Data = [ 2 { name: "HTML" }, 3 { name: "CSS" }, 4 { name: "Javascript" }, 5 { name: "Python" }, 6];
  • Inside the DragFile function map a mock data. and set a value in the DragCard component tag. using the following snippet.

1export function DragFile() { 2 return ( 3 <div className="my-8 mx-8 rounded-xl border w-fit"> 4 <div className="my-4"> 5 <div> 6 <p className="mx-16 font-bold">Draged Items</p> 7 </div> 8 {Data.map((e) => ( 9 <div 10 key={e.name} 11 className="border w-fit my-2 p-2 mx-16 rounded bg-indigo-400 text-white font-bold cursor-pointer" 12 > 13 <DragCard draggable name={e.name} /> 14 </div> 15 ))} 16 </div> 17 </div> 18 ); 19} 20export default DragFile;

As shown in the following screenshot.


drag file

Sample code for the /pages/components/DragFile.js file can be found in the following Github URL.

Step 5: Update the index.js file

Drop → pages →index.js

  • Update the DragFile.js in the above path,

  • For this example, we are using the useDrop form react-dnd ,useState form react hooks , and DragFile from component, so we have imported the same here. using the following snippet.

1import DragFile from "../components/DragFile"; 2import { useDrop } from "react-dnd"; 3import { useState } from "react";
  • Set the useState from react hooks. using the following snippet.

1const [basket, setBasket] = useState([]);
  • In the Home function use useDrop hooks.

  • Inside the useDrop hooks. we use accept, drop, and collect key value. using the following snippet.

  • accept is Required. A string, a symbol, or an array of either. This drop target will only react to the items produced by the drag sources of the specified type or types.

  • drop(item, monitor) is Optional. Called when a compatible item is dropped on the target.

  • collect is also Optional. The collecting function. It should return a plain object of the props to return for injection into your component. It receives two parameters, monitor and props.

1export default function Home() { 2 const [basket, setBasket] = useState([]); 3 4 const [{ isOver }, dropRef] = useDrop({ 5 accept: "language", 6 drop: (item) => 7 setBasket((basket) => 8 !basket.includes(item) ? [...basket, item] : basket 9 ), 10 collect: (monitor) => ({ 11 isOver: monitor.isOver(), 12 }), 13 }); 14 15 return ( 16 17 <div className="flex"> 18 <div> 19 <DragFile /> 20 </div> 21 <div className="my-8 mx-8 rounded-xl border w-fit" ref={dropRef}> 22 <div className="my-4"> 23 <div> 24 <p className="mx-16 font-bold">Droped Items</p> 25 </div> 26 {basket.map((e) => ( 27 <p className="border w-fit my-2 p-2 mx-16 rounded bg-indigo-400 text-white font-bold cursor-pointer"> 28 {e.name} 29 </p> 30 ))} 31 </div> 32 </div> 33 </div> 34 ); 35}

As shown in the following screenshot.


index file


Sample code for the /pages/index.js file can be found in the following Github URL.

Step 5. Add the DndProvider in _app.js to enable the data sharing among all the components.

Drop → pages →_app.js

  • Update the _app.js in the above path,

  • For this example we are using the DndProvider , HTML5Backend. so we have imported the same here. using the following snippet.

1import { DndProvider } from 'react-dnd' 2import { HTML5Backend } from 'react-dnd-html5-backend'
  • The imported DndProvider is wrapped around the main component.

  • It is important to note that the Dragged values are accessible inside the child component enclosed by the DndProvider.

  • Any component outside the DndProvider will not be able to access the Draged values.

1function MyApp({ Component, pageProps }) { 2 return ( 3 <> 4 <DndProvider backend={HTML5Backend}> 5 <Component {...pageProps} /> 6 </DndProvider> 7 </> 8 ) 9}

As shown in the following screenshot.

Sample code for the /pages/app.js file can be found in the following Github URL.

Step 6: Run your Application

Run the Next Application with the following command.

1npm run dev

After compiling your application open your browser and check the following URL:

1http://localhost:3000/

A Sample Github repo, with all the required configurations, is given below.

Result:

The Example UI is shown in the following screenshot.



result 1

  • First, click and drag HTML text in Dragged Items. As shown in the following screenshot.



result 2

  • The Dragged HTML text Drop into Dropped items lists. As shown in the following screenshot.



result 3

  • And release Dragged text (HTML) in Dropped items lists. As shown in the following screenshot.



result 4
  • Finally the Draged item placed in the Drop box.

Comments