Drag and Drop implementation using html/css and Javascript
Tags: webdev, javascript, tutorial, html
Published: 2023-09-03 21:12:57

**Drag & drop** is among the important technique a web developer must be comfortable working with. In this article we are going to cover important events involved in **drag & drop**.  For better understanding of this article, you need to be familiar with:
+ html
+ Javascript
+ DOM events. 

**Drag & drop** events can be categorised into two:

1. Events that happens on `dragged element`
2. Events that happens on ` target element`(**dropZone**).

For these events to work, set draggable attribute in dragged element to true.

```html
<p draggable="true" class="dragged-item">This is our draggable element</p> 
```
 >**NOTE:**  Images and links are draggable by default (No need to set draggable attribute to true)

## 1 Events that happen on dragged element
These are events that trigger when draggable elements moves from their original position to final position. The events are:

+ dragstart event
+ drag event
+ dragend event

Now let's discuss each event to see when and how to use these events.

### a) Dragstart event
The `dragstart` event triggers when user start to move `dragged` element.This event uses [`dataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object to set data. 

The [`dataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object sets data using `setData` method. The `setData` method takes in two parameter:
1. **format** of data to be set (`"text/plain"`, `"text/html"` etc)
2. **data** value (anything in string form)
 
```js
e.dataTransfer.setData(format, data);
```
>**NOTE:** The data set above, is later retrieved and used in `drop` event.

#### dragstart event implemention
1. Add `dragstart` event listener to dragged element

1. Get `id` of `dragged` element for later use (use `event.target.getAttribute("id")` to get id).

2. Set data(in `text/plain` format) to `id` of dragged element. The data is set using` setData` method in `dataTransfer` object.
```js
const draggedElement = document.querySelector(".dragged-item");
draggedElement.addEventListener("dragstart",function(e){
    e.dataTansfer.setData("text/plain",e.target.id);
})
```
### b) drag event

The `drag` event triggers when dragged element is moving. The `drag` event fires continuously since it triggers when moving dragged element. 

`Drag` event provides an opportunity to change appearance of `dragged` element so that users can visualize their action.

In `drag` event, change the appearance of `dragged` element using css.

#### drag event implementation
1. Add `drag` event listener to dragged element
1. Get `dragged` element(`e.target`)
2. Change the color  of dragged element

```js
draggedElement.addEventListener("drag",function(e){
    e.target.style.color = "grey";
})
```
**NOTE:**
> You can ommit `drag` event if you not changing appearance of dragged element

>It is possible to use `setData` method in `dataTransfer` object to set data in this `drag` event.

### c) dragend event

The `dragend` event triggers when drag operation is completed. Drag operation can either be successful or unsuccessful.

This `dragend` event allows you to reset appearance of dragged element to initial appearance of dragged element.

#### dragend event implementation
1. Add `dragend` event listener to dragged element
1. Get dragged element(`e.target`)
2. Change the color  of dragged element to its initial color
```js
draggedElement.addEventListener("drag",function(e){
    e.target.style.color = "grey";
})
```
>**NOTE:** You can ommit `dragend` event if you not  changing appearance of dragged element


## 2 Events that happen on drop target element
These are events that occur when `dragged` element moves over the drop target element(**dropZone**). The events modifies the **dropZone** element. The events are:

+ dragenter event
+ dragover event
+ drop event
+ dragleave event

let's discuss the above events and how they should be implemented.

### a) dragenter event

The`dragenter` event fires when dragged element enters the **dropZone**. This `dragenter` event provides a visual feedback that a **dropZone** element accepts dragged element(drop target).

#### dragenter event implemention

1. Create **dropZone** element in html
```html
<div class="drop-zone"></div>
```
2. Get **dropZone** element using selector
```js
const dropZone = document,querySelector(".drop-zone");
```
3. Add `dragenter` event listener to **dropZone** element
4. Using `e.target`, modify **dropZone** element(change bacground color).
```js
dropZone.addEventListener("dragenter",function(e){
e.preventDefault()
e.target.style.border = "dotted 4px black";
})
```
>**NOTE:** The default behavior of `dragenter` is to avoid dropping of dragged element. The `e.preventDefault()` prevents the default behaviour of `dragenter` event hence allowing dropping of dragged element in **dropZone**.

### b) dragover event
The `dragover` event fires when dragged element is over the **dropZone**. This `dragover` event fires every milliseconds. 

The main purpose of `dragover ` event is to prevent default. Preventing default, prevents dragged element from going back to its original position when handling `drop` event.

#### dragover event implemention
1. Get the **dropZone** element
2. Add `dragover` event listener to **dropZone** element
2. Prevent default of `dragover` event 

```js
dropZone.addEventListener("dragover",function(e){
e.preventDefault()
})
```

### c) drop event
The `drop` event fires when dragged element drops in **dropZone**. The `drop` event is where we get the data that was set in `dragstart` event and use the data. The data is obtained from `dataTransfer` object using `getData` method.

#### drop event implemention
1. Get **dropZone** element
2. Add `drop` event listener to **dropZone** element
3. Prevent default of `drop` event (opening link when dropped)
4. Get the data that was set in `dragstart` event and store it in a variable called **draggedElementId**
```js
   const draggedElementId = e.dataTransfer.getData("text/plain");
```
>**NOTE:** **draggedElementId** is a string (`id` of dragged element)
5. Get the dragged element using `document.getElementById` and store it in another variable called **draggedElement**
```js
const draggedElement = document.getElementById(draggedElementId);
```
6. Get the **dropZone** element(`e.target`) and  append the **draggedElement**
```js
    dropZone.addEventListener("drop",function(e){
        e.preventDefault()
        const draggedElementId = e.dataTransfer.getData("text/plain");
        const draggedElement = document.getElementById( draggedElementId);
        e.target.appendChild(draggedElement);
    })
```
The **draggedElement** moves inside **dropZone** as child element.

### d) dragleave event
The `dragleave` event fires when dragged element leaves the **dropZone** area. This `dragleave` event can be used to modify dropZone element to its original state( remove visual feedback in `dragenter` event).

#### dragleave event implementation
1. Get **dropZone** element
2. Add `dragleave` event listener to **dropZone** element
3. Reset **dropZone** element to its original state

```js
dropZone.addEventListener("dragleave",function(e){
        e.preventDefault()
        e.target.style.border = "solid 4px black";
    })
```
## Conclusion
In summary, mastering these **drag & drop** events is essential for creating interactive and user-friendly web applications. They allow you to build features like drag-and-drop interfaces, file uploads, and more.

By understanding and effectively implementing these events, you can create dynamic and user-friendly interfaces with **drag & drop** functionality, enhancing the user experience and interactivity of websites.