Reputation: 215
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:
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>
Upvotes: 2
Views: 4036
Reputation: 215
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.
const onDragEnd = result => {
const { destination, source, draggableId, combine } = result;
if (!combine && !destination) {
return; // not dropped in a known destination
}
if (!combine && destination.draggableId === source.droppableId && destination.index === source.index) {
return; // dropped in same location
}
const start = state.columns[source.droppableId]; //get selected column
const finish = combine ? state.columns[combine.droppableId] : state.columns[destination.droppableId]; //get new selected column
if (combine) {
//just removing the dragging item
const combineTaskIds = Array.from(start.taskIds); //create new array with current columns taskids
combineTaskIds.splice(source.index, 1); // from this index we want to remove 1 item
const newColumn = {
...start,
taskIds: combineTaskIds,
}; // create new column with new tasks
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); // from this index we want to remove 1 item
newTaskIds.splice(destination.index, 0, draggableId); // from this index we want to add the draggable item
const newColumn = {
...start,
taskIds: newTaskIds,
}; // create new column with new tasks
setState(prevState => ({ ...prevState, columns: { ...prevState.columns, [newColumn.id]: newColumn } }));
}
if (start !== finish) { //move to different column
const startTaskIds = Array.from(start.taskIds);
startTaskIds.splice(source.index, 1); //remove item from index
const newStart = {
...start,
taskIds: startTaskIds,
};
const finishTaskIds = Array.from(finish.taskIds);
finishTaskIds.splice(destination.index, 0, draggableId); // add draggable to index
const newFinish = {
...finish,
taskIds: finishTaskIds,
};
setState(prevState => ({ ...prevState, columns: { ...prevState.columns, [newStart.id]: newStart, [newFinish.id]: newFinish } }));
}
}
Any additions or corrections to my answer are always welcome to learn.
Upvotes: 4