'Dropdown Menu that updates when user clicks on dropdown item AND is draggable in react
So I am trying to create a dropdown button, in where the user can click on one of the dropdown items, and the button updates. Next the user can drag the that button with the updated value to the drop box.
My problem is I have only been able to find a way to reach my goal with a select option input, draggable dropdown button, and dropbox.
I want to accomplish my goal with only a draggable dropdown button and dropbox.
here is my code:
import React, { useState } from "react";
import "./dragDrop.css";
import { useDrag } from "react-dnd";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCirclePlus } from "@fortawesome/free-solid-svg-icons";
const Task = ({ id, task }) => {
const [newTaskItem, setNewTaskItem] = useState([]);
const addTask = (event) => {
if (event) {
const addedTaskItem = [...newTaskItem, taskitem];
setNewTaskItem(addedTaskItem);
}
};
const [{ isDragging }, dragRef] = useDrag({
type: "task",
item: { id, task },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
const TASKS = [
{
id: 1,
task: "My Goal",
},
{ id: 2, task: "School" },
{ id: 3, task: "Creative" },
{ id: 4, task: "Professional" },
{ id: 2, task: "Health" },
];
return (
<div className="btn-group">
<button
type="button"
className="btn btn-outline-info taskBtn dropdown-toggle"
ref={dragRef}
data-bs-toggle="dropdown"
aria-expanded="false"
>
{task}
{isDragging && ""}
</button>
<ul class="dropdown-menu">
<li
onChange={(e) => {
setItem(e.target.value);
}}
>
<a class="dropdown-item" href="#">
action
</a>
</li>
</ul>
<FontAwesomeIcon icon={faCirclePlus}></FontAwesomeIcon>
</div>
);
};
export default Task;
_________________________
import React from "react";
import "./dragDrop.css";
import { useDrag } from "react-dnd";
const SelectedTask = ({ id, task }) => {
const [{ isDragging }, dragRef] = useDrag({
type: "task",
item: { id, task },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
return (
<li className="list-group-item taskItemColor" ref={dragRef}>
{task}
{isDragging && ""}
</li>
);
};
export default SelectedTask;
_______________________________
import React, { useEffect, useState } from "react";
import "./dragDrop.css";
import { useDrop } from "react-dnd";
import Task from "./task.jsx";
import SelectedTask from "./selectedTask.jsx";
const TASKS = [
{
id: 1,
task: "My Goal",
},
{ id: 2, task: "School" },
{ id: 3, task: "Creative" },
{ id: 4, task: "Professional" },
{ id: 2, task: "Health" },
];
const DayBtn = () => {
const [dayButton, setDayButton] = useState([]);
const [item, setItem] = useState("My Goal");
const [taskArray, setTaskArray] = useState(TASKS);
useEffect(() => {
let filteredArray = TASKS.filter((task) => {
if (task.task == item) {
return task;
}
});
setTaskArray(filteredArray);
}, [item]);
const [{ isOver }, dropRef] = useDrop({
accept: "task",
drop: (item) => {
if (dayButton.length == 0) {
setDayButton([item]);
} else if (dayButton.length > 0) {
let list = dayButton.filter((taskItem) => {
if (taskItem.task != item.task) {
return taskItem;
}
});
list = [...list, item];
setDayButton(list);
}
},
collect: (monitor) => ({
isOver: monitor.isOver(),
}),
});
return (
<React.Fragment>
<div className="row">
<div className="col-6">
<select
onChange={(e) => {
setItem(e.target.value);
}}
>
{TASKS.map((item) => {
return <option value={item.task}> {item.task}</option>;
})}
</select>
<div className="dayBtnDiv">
{taskArray.map((task) => (
<Task draggable key={task.id} task={task.task} />
))}
</div>
</div>
<div className="col-6 dayBtnCol">
<div className="dayButton" ref={dropRef}>
<ul className="list-group list-group-flush">
{dayButton.map((task) => (
<SelectedTask key={task.id} task={task.task} />
))}
</ul>
{isOver && <div> Drop Here!</div>}
</div>
</div>
</div>
</React.Fragment>
);
};
export default DayBtn;
_____________________________
import React from "react";
import DayBtn from "./dayBtn.jsx";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
const TodoList = () => {
return (
<div className="container">
<div className="row">
<div className="col-12">
<DndProvider backend={HTML5Backend}>
<DayBtn />
</DndProvider>
</div>
</div>
<div className="row">
<div className="col-6"></div>
<div className="col-6 readyBtnCol">
<div className="readyButton">
<button type="button" class="btn btn-warning">
Ready!
</button>
</div>
</div>
</div>
</div>
);
};
export default TodoList;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
