Conditionally Allow Movement using react-beautiful-dnd Draggable and Droppable Props

Alex Reardon
InstructorAlex Reardon

Share this video with your friends

Send Tweet
Published 4 years ago
Updated a year ago

Now that we are able to drag tasks between our task lists, we might not always want a user to move a task to any location. This lesson will explore how we can conditionally allow what can be dragged, and where it can be dragged to.

react-beautiful-dnd provides a robust API for configuring what can be dragged or dropped where. isDragDisabled prop on a <Draggable />, isDropDisabled prop on a <Droppable />, and the <Droppable /> type prop give you fine-grain control to allow whatever business logic you need to implement, control what is draggable and droppable.

Instructor: [00:00] With react-beautiful-dnd, you have the ability to control what is able to be dragged and where it is able to be dropped. Controlling what is able to be dragged is done using the Draggable isDragDisabled prop.

[00:14] When isDragDisabled is set to true, it will prevent a Draggable from being dragged. What I'm doing here is conditionally disabling the drag when the task ID is Task 1. We can see that we are no longer able to drag the first task, but we are still able to drag other tasks.

[00:46] I'm going to pull this out into a variable. I've pulled it out into a variable so that I can also apply it to our style component. I'm now using a nested ternary statement to conditionally set the background color to light grey if a Draggable is disabled.

[01:16] That way, we can more easily see what things in our system are disabled. isDragDisabled will prevent a Draggable from being dragged, but it will still be reorderable within the list.

[01:31] How you populate the isDragDisabled prop is up to you. It could be based on some fairly complicated business logic. We'll now go to the column component. There are two mechanisms available to control where a Draggable can be dropped.

[01:48] The simplest mechanism is the Droppable type prop. You can provide an optional type to a Droppable. A Draggable can only be dropped into a Droppable that shares the same type as the Droppable that it started in.

[02:07] Here I am conditionally assigning the type of the Droppable based on the ID of the column. The third column will have a type of Done, whereas the first two columns will have a type of Active.

[02:22] This configuration will allow me to move tasks between the To-Do and In Progress columns. I will not be able to move that task into the Done column. A second mechanism for controlling what can be dropped on a Droppable is the Droppable isDisabled prop.

[02:42] If isDropDisabled is set to true, then no Draggable will be able to drop onto it, even if it is of the same type. You can dynamically change this prop as much as you like, even during a drag.

[03:06] I have set up our column so that it now has an isDropDisabled prop that is passed straight through to the Droppable. Using this prop, we can enforce that tasks can only move to the right of where they started.

[03:23] I'm creating an onDragStart function to capture the index of the column that we start dragging from. I am then recording this index in our component state. While I'm here, I'll make sure that I clear this index when a drag finishes.

[04:01] I'm now going to bind our onDragStart function to the DragDropContext. I'm getting the index of the column from our map function. I'm now creating a variable called isDropDisabled.

[04:20] IsDropDisabled will be set to true when the index of our map function is less than the index of the column that we started a drag in. This will prevent dragging backwards between the columns.

[04:36] I'm now going to pass this on to the column. I can move a task from To-Do to In Progress, but I'm no longer able to move a task from In Progress to To-Do. I can only move a task from In Progress to Done.