I have a web page where words need to be rearranged by drag and drop method. The app is built with React. My issue is that when the element is dropped in the drop zone/area, the id that was set by the target element is blank. This was the original error TypeError: Failed to execute ‘appendChild’ on ‘Node’: parameter 1 is not of type ‘Node’. I tried console logging the id text during drop and it shows up blank.
const handleDragStart = (e:DragEvent<HTMLHeadingElement>) => { e.dataTransfer.dropEffect = "move"; e.dataTransfer.setData("elementID", e.target.id); } const handleDragDrop = (e:DragEvent<HTMLDivElement>) => { const data = e.dataTransfer.getData("elementID"); console.log(data) //prints nothing e.target.appendChild(document.getElementById(data)); } const handleDragOver = (e:DragEvent<HTMLDivElement>) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; } return( <> <div className="display-flex"> {["before", "calm", "storm", "the"].map((elem, i)=>( <h4 key={elem} id={`draggable-${i}`} draggable="true" onDrag={handleDragStart} className="px-1 b-1 m-1">{elem}</h4> ))} </div> <div className="b-1 p-1 h-2" onDrop={handleDragDrop} onDragOver={handleDragOver}> <p>Drop Zone</p> </div> </> )
Advertisement
Answer
You should use the onDragStart
instead of the onDrag
on the draggable element:
You can read more here
import React from "react"; const Com = () => { const drag = (e) => { e.dataTransfer.setData("id", e.target.id); e.dataTransfer.dropEffect = "move"; }; const handleDragDrop = (e) => { e.preventDefault(); const data = e.dataTransfer.getData("id"); const el = document.getElementById(data); el && e.target.appendChild(document.getElementById(data)); }; const handleDragOver = (e) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; }; return ( <> <div className="display-flex"> {["123"].map((elem, i) => ( <h4 key={elem} id={`draggable-${elem}`} draggable="true" onDragStart={drag} className="px-1 b-1 m-1" > {elem} </h4> ))} </div> <div className="b-1 p-1 h-2" onDrop={handleDragDrop} onDragOver={handleDragOver} > <p>Drop Zone</p> </div> </> ); }; export default Com;
See it running here on CodeSandbox