09fruits
09fruits

Reputation: 253

react-beautiful-dnd: Prevent the rest of draggable items from reordering / moving up and replacing the item being dragged

In a single Droppable, I have mapped out an array of items, each as its own Draggable. My code is working properly and is doing what it's supposed to (i.e., I can move each Draggable individually). I'm just wondering if there's a way to stop the rest of my Draggables from "moving up" or replacing the empty spot the item-that's-being-dragged leaves behind.

Here's my code (DragDropContext is in another component, so it's not shown here):

<Droppable
    droppableId='itemDroppable'
    type='acceptsItems'
    isDropDisabled={true} >
    {(provided) =>
        <div ref={provided.innerRef}>

            {this.props.items.map((item, index) =>
                <Draggable
                    key={item.id}
                    draggableId={item.name}
                    index={index} >
                    {provided =>
                        <div
                            ref={provided.innerRef}
                            {...provided.draggableProps}
                            {...provided.dragHandleProps} >
                            {item.icon}
                        </div>
                    }
                </Draggable>
            )}
        
            {provided.placeholder}

        </div>
    }
</Droppable>

And here's a video of what's happening:

enter image description here

As you can see, the rest of the following icons move up and replace the empty spot left by the item that's being dragged out of the Droppable. Is there a way to stop this? Ideally, I'd like to have the empty spot stay empty and not have the rest of the proceeding icons move up and fill up.

Thank you in advance!

Upvotes: 2

Views: 11696

Answers (2)

Sachin Jadeja
Sachin Jadeja

Reputation: 11

This may not be the correct solution, but a workaround.

<Draggable
    key={item.id}
    draggableId={item.name}
    index={index}
    >
    {(provided, snapshot) => (
        <>
            <div
                ref={provided.innerRef}
                {...provided.draggableProps}
                {...provided.dragHandleProps}
            >
                {item.icon}
            </div>
            {
                snapshot.isDragging && (
                <div style={{ width: '20px', height: '20px' }} />
                )
            }
        </>
        )}
</Draggable>;

Upvotes: 0

MURHAF AL-MSRI
MURHAF AL-MSRI

Reputation: 148

I don't have a direct solution but I have an idea that may work around this problem.
when you are displaying the items using Array.map() function

  • first: suppose we add some additional information to the object to track if it's deleted. add a condition so It renders the element if the flag is true. Otherwise, a hidden element will be displayed. note: I not sure but I think you can use provide.placeholder
    for example:
{(provided) => (
        <div ref={provided.innerRef}>
            {this.props.items.map((item, index) => {
                if (item.id !== 0) {
                    return (
                        <Draggable
                            key={item.id}
                            draggableId={item.name}
                            index={index}
                        >
                            {(provided) => (
                                <div
                                    ref={provided.innerRef}
                                    {...provided.draggableProps}
                                    {...provided.dragHandleProps}
                                >
                                    {item.icon}
                                </div>
                            )}
                        </Draggable>
                    );
                } else
                    return (
                        <div style={{ width: '20px', height: '20px' }} /> //display hidden undraggable hidden element or try provided.placeholder
                    );
            })}

            {provided.placeholder}
        </div>
    )}
  • second: when you implement the deleting function inside onDragEnd() we can change the flag of that element.

Upvotes: 1

Related Questions