I'm trying to make a drag-drop functionality on a webpage but unsuccessful so far. I want to make the A, B, C cards in the pink box stay where they are after we drag a copy of them to the black box (like a menu box, link for a demo of this behavior). I don't know what element or code that makes the box stay where they are like a menu bar despite many attempts of finding, so any help would be appreciated! Thank you!
So far, since I'm a beginner in React, my problem is that the online examples I refer to are written in a single file using 'class App', but what I'm trying to do is to have separate components, and I don't know how to convert the code properly.
My app includes index.js, App.js, and the components:\
- Card.js
import React from "react";
function Card(props) {
const dragStart = (e) => {
const target = e.target;
e.dataTransfer.dropEffect = "move";
e.dataTransfer.setData("card_id", target.id);
setTimeout(() => {
target.style.display = "none";
}, 0);
};
const dragOver = (e) => {
e.stopPropagation();
// e.dataTransfer.dropEffect = "copy";
};
return (
<div
id={props.id}
className={props.className}
draggable={props.draggable}
onDragStart={dragStart}
onDragOver={dragOver}
>
{props.children}
</div>
);
}
export default Card;
- Board.js (the black box)
import React from "react";
function Board(props) {
const drop = (e) => {
e.preventDefault();
const card_id = e.dataTransfer.getData("card_id");
const card = document.getElementById(card_id);
card.style.display = "block";
e.target.appendChild(card);
};
const dragOver = (e) => {
e.preventDefault();
};
return (
<div
id={props.id}
className={props.className}
onDrop={drop}
onDragOver={dragOver}
>
{props.children}
</div>
);
}
export default Board;
- Menu.js (the pink box)
import React from "react";
import Card from "./Card";
function Menu(props) {
const dragOver = (e) => {
e.preventDefault();
};
return (
<div id={props.id} className={props.className} onDragOver={dragOver}>
{props.children}
</div>
);
}
export default Menu;
- My App.js is currently like this:
import React, { useState } from "react";
import Board from "./components/Board";
import Card from "./components/Card";
import Menu from "./components/Menu";
function App() {
const [card_list, setList] = useState([
{ id: "card-1", value: "A" },
{ id: "card-2", value: "B" },
{ id: "card-3", value: "C" },
]);
return (
<div className="flexbox">
<Menu id="menu-1" className="menu">
{card_list.map((item) => {
return (
<Card
key={item.id}
value={item.value}
id={item.id}
className="card"
draggable="true"
>
<p> {item.value}</p>
</Card>
);
})}
</Menu>
<Board id="board-2" className="board">
<Card id="card-other" className="card">
<p> Card two </p>
</Card>
</Board>
</div>
);
}
export default App;
And index.js is nothing but:
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);