Drag & Drop with HTML
Tags: html, javascript
Published: 2020-08-20 15:53:05

It can be hard to reinvent the wheel, and I many weeks ago had fallen into the trap of creating a [task management app](https://github.com/aohibbard/taskmaster) using vanilla JS. I wanted to add some spice to the application, so decided to implemented a feature that allowed the user to drag and drop different tasks, reordering their list. Although there are many ways to implement this (e.g. Draggable), HTML5 has its own tools, which are perfectly sufficient.

To begin working with the Drag and Drop API, you need to determine which DOM elements are going to be draggable. This is as simple as adding <draggable=“true”> to your DOM element. My application displays tasks in a grid of cards, so these <divs> were the draggable elements. 

`<div class="task" id="task-${this.id}" task-data-id="${this.id}" draggable='true' ondragstart='onDragStart(event)'>`

Once you have enabled <draggable> on your DOM elements,  you should be able to drag the HTML element around your window, and it will have a transparent effect, but you won’t be to drop or do anything with it. This is where the JavaScript comes into play. In my JavaScript file, I’ve written an even handler to execute when an <div> is dragged. This looks like:

    `function onDragStart(event){
        event.dataTransfer.setData('text/plain', event.target.id)}`

The dataTransfer object is a crucial part of the drag and drop API that allows the data at the targeted element to be set and transferred to wherever you want to drop. When implementing this, I encourage you to use your console and dig into the [dataTransfer](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object to see everything that it contains. Different types of text and data can be set in the setData function, (e.g. ‘text/plain’, ‘text/html’). 

The next step is to determine your drop zone, or the area where you want you want to enable draggable content to be dropped. For me, this was the parent element or container for all the taks <divs>.
In the HTML, you have to assign functions that assign behaviors for the ondragover and ondrop events. This involve editing the HTML and JavaScript file. In my code, this looked like

            `<div
                class="team-tasks-${this.id}"
                id="task-field" data-id="${this.id}"
                draggable="true"
                ondragover='onDragOver(event);'
                ondrop='dropHandler(event)'
                >
            </div>`


   `function onDragOver(event) {
        event.preventDefault();
        event.dataTransfer.dropEffect = "move"
    }

    function dropHandler(event) {
        event.stopPropagation();

        const id = event.dataTransfer.getData('text/plain');
    
        const draggableElement = document.getElementById(id);
        //target container div
        const dropzone = event.target.parentElement;
        dropzone.appendChild(draggableElement);
    
      event.dataTransfer.clearData();
    } `

And that covered it. You can read more about [Drag and Drop](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) or check it out in my [application](https://aohibbard.github.io/taskmaster/frontend/) (you can use the existing team 'Goop' to play around with seed data) or [code](https://github.com/aohibbard/taskmaster).