I am using react beautiful dnd and have created 3 columns with list-items. I want to add the feature to combine items. I have read the documentation, but still can't seem to figure out why it's not working.
The problem seems to be in onDragEnd, where it can find result.combine (combine) like in the documentation, but it doesn't seem to be true when it gets to the if statement. Am I overlooking something? Can someone please explain to me what is happening, why it's not working?
Thank you in advance!
resources I've used:
- https://react-beautiful-dnd.netlify.app/?path=/story/board--with-combining
- https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/combining.md
- https://egghead.io/lessons/react-move-items-between-columns-with-react-beautiful-dnd-using-ondragend (nothing on combining though!)
my data:
const initialData = {
tasks: {
'task-1': { id: 'task-1', content: 'task-1' },
'task-2': { id: 'task-2', content: 'task-2' },
'task-3': { id: 'task-3', content: 'task-3' },
},
columns: {
'column-1': {
id: 'column-1',
title: 'column-1',
taskIds: ['task-1', 'task-2'],
},
'column-2': {
id: 'column-2',
title: 'column-2',
taskIds: [],
},
'column-3': {
id: 'column-3',
title: 'column-3',
taskIds: ['task-3'],
},
},
columnOrder: ['column-1', 'column-2', 'column-3'],
};
export default initialData;
index file with onDragEnd
const onDragEnd = result => {
const { destination, source, draggableId, combine } = result;
//console.log(`drag: ${combine.draggableId} drop: ${combine.droppableId}`);
if (!destination) {
return; // not dropped in a known destination
}
if (destination.draggableId === source.droppableId && destination.index === source.index) {
return; // dropped in same location
}
const start = state.columns[source.droppableId]; //get selected column
const finish = state.columns[destination.droppableId]; //get new selected column
if (combine) {
//console.log(`drag: ${combine.draggableId} drop: ${combine.droppableId}`);
const combineTaskIds = Array.from(start.taskIds);
combineTaskIds.splice(source.index, 1);
const newColumn = {
...start,
taskIds: combineTaskIds,
};
setState(prevState => ({ ...prevState, columns: { ...prevState.columns, [newColumn.id]: newColumn } }));
}
if (start === finish) { //move in same column
const newTaskIds = Array.from(start.taskIds);
newTaskIds.splice(source.index, 1);
newTaskIds.splice(destination.index, 0, draggableId);
const newColumn = {
...start,
taskIds: newTaskIds,
}; // create new column with new tasks
setState(prevState => ({ ...prevState, columns: { ...prevState.columns, [newColumn.id]: newColumn } }));
}
if (start !== finish) {
const startTaskIds = Array.from(start.taskIds);
startTaskIds.splice(source.index, 1);
const newStart = {
...start,
taskIds: startTaskIds,
};
const finishTaskIds = Array.from(finish.taskIds);
finishTaskIds.splice(destination.index, 0, draggableId);
const newFinish = {
...finish,
taskIds: finishTaskIds,
};
setState(prevState => ({ ...prevState, columns: { ...prevState.columns, [newStart.id]: newStart, [newFinish.id]: newFinish } }));
}
}
return <DragDropContext onDragEnd={onDragEnd} >
<Container>
{
state.columnOrder.map(columnId => {
const column = state.columns[columnId];
const tasks = column.taskIds.map(taskId => state.tasks[taskId]);
return <Column key={column.id} column={column} tasks={tasks} />;
})
}
</Container>
</DragDropContext >
Droppable Columns (with isCombineEnabled as true)
<Container>
<List dense>
<ListItemText primary={props.column.title} />
<Droppable droppableId={props.column.id} isCombineEnabled>
{(provided, snapshot) => (
<ListItem
{...provided.droppableProps}
innerRef={provided.innerRef}
isDraggingOver={snapshot.isDraggingOver}
button>
{props.tasks.map((task, index) => <Task key={task.id} task={task} index={index} />)}
{provided.placeholder}
</ListItem>
)}
</Droppable>
</List>
</Container>
Draggable Task Items
<Draggable draggableId={props.task.id} index={props.index}>
{(provided, snapshot) => (
<Container
{...provided.draggableProps}
{...provided.dragHandleProps}
innerRef={provided.innerRef}
isDragging={snapshot.isDragging}
>
{props.task.content}
</Container>
)}
</Draggable>
Finally I have solved the issue and wanted to share this in case someone might end up with the same problem.
The problem was indeed in onDragEnd before getting to the conditional for combine.
const finish
needs to change depending on the usage, for it will have either one or the other. Combine or Destination.Any additions or corrections to my answer are always welcome to learn.