Drag and Drop Sortable List With Javascript (Simple Example)

Welcome to a quick tutorial on how to create a drag-and-drop sortable list with HTML and Javascript. Once upon a time in the Dark Ages of the Internet, implementing drag-and-drop is a massive task that involves a lot of coding with 3rd party libraries. But ever since HTML5, it has been made a native feature and we no longer have to fight with digital dragons.

In the simplest design, drag-and-drop in HTML and Javascript only requires:

  1. Create draggable items by attaching the draggable property – <div draggable>Drag This</div>
  2. Define the dropzone – <div id="drop">Drop Here</div>
  3. Attach a drop listener in Javascript – document.getElementById("drop").ondrop = () => { DO SOMETHING };

That covers the basics, but how can we create a sortable list with this? Read on for an example!

 

 

TABLE OF CONTENTS

 

DRAG-AND-DROP SORTABLE LIST

All right, let us now get into the details of how the drag-and-drop list works.

 

SORTABLE LIST DEMO

  • First
  • Second
  • Third
  • Forth
  • Fifth

 

STEP 1) THE HTML

1-sort-list.html
<!-- (A) LOAD CSS + JS -->
<link rel="stylesheet" href="2-sort-list.css">
<script src="3-sort-list.js"></script>
 
<!-- (B) THE LIST -->
<ul id="sortlist">
  <li>First</li>
  <li>Second</li>
  <li>Third</li>
  <li>Forth</li>
  <li>Fifth</li>
</ul>
 
<!-- (C) CREATE SORTABLE LIST -->
<script>
slist(document.getElementById("sortlist"));
</script>

For you guys who just want to use this as a “plugin” without reading the rest of the tutorial:

  1. Load the CSS and Javascript. Doh.
  2. Define the <ul> or <ol> as usual. Take note that this simple example will only work with a flat one-level list.
  3. Use the slist(TARGET) function on window load to initiate the sortable list.

 

 

STEP 2) THE CSS

2-sort-list.css
/* (A) LIST STYLES */
.slist {
  list-style: none;
  padding: 0;
  margin: 0;
}
.slist li {
  margin: 10px;
  padding: 15px;
  border: 1px solid #dfdfdf;
  background: #f5f5f5;
}

/* (B) DRAG-AND-DROP HINT */
.slist li.hint {
  border: 1px solid #ffc49a;
  background: #feffb4;
}
.slist li.active {
  border: 1px solid #ffa5a5;
  background: #ffe7e7;
}

These are just some simple cosmetic styles for the sortable list.

  1. The Javascript will attach a .slist class to the container. In this section, we remove the default bullet points and make the list look a little better.
  2. The .hint class is used to highlight the possible dropzones, and .active when the draggable is hovering over the dropzone.

 

 

STEP 3) THE JAVASCRIPT

3-sort-list.js
function slist (target) {
  // (A) SET CSS + GET ALL LIST ITEMS
  target.classList.add("slist");
  let items = target.getElementsByTagName("li"), current = null;

  // (B) MAKE ITEMS DRAGGABLE + SORTABLE
  for (let i of items) {
    // (B1) ATTACH DRAGGABLE
    i.draggable = true;
    
    // (B2) DRAG START - YELLOW HIGHLIGHT DROPZONES
    i.ondragstart = e => {
      current = i;
      for (let it of items) {
        if (it != current) { it.classList.add("hint"); }
      }
    };
    
    // (B3) DRAG ENTER - RED HIGHLIGHT DROPZONE
    i.ondragenter = e => {
      if (i != current) { i.classList.add("active"); }
    };

    // (B4) DRAG LEAVE - REMOVE RED HIGHLIGHT
    i.ondragleave = () => i.classList.remove("active");

    // (B5) DRAG END - REMOVE ALL HIGHLIGHTS
    i.ondragend = () => { for (let it of items) {
        it.classList.remove("hint");
        it.classList.remove("active");
    }};
 
    // (B6) DRAG OVER - PREVENT THE DEFAULT "DROP", SO WE CAN DO OUR OWN
    i.ondragover = e => e.preventDefault();
 
    // (B7) ON DROP - DO SOMETHING
    i.ondrop = e => {
      e.preventDefault();
      if (i != current) {
        let currentpos = 0, droppedpos = 0;
        for (let it=0; it<items.length; it++) {
          if (current == items[it]) { currentpos = it; }
          if (i == items[it]) { droppedpos = it; }
        }
        if (currentpos < droppedpos) {
          i.parentNode.insertBefore(current, i.nextSibling);
        } else {
          i.parentNode.insertBefore(current, i);
        }
      }
    };
  }
}

Right, the Javascript looks like quite a handful at first, but keep calm and study closely.

  1. Attach a .slist CSS class to the list, and get all the <li> list items.
  2. Loop through all the <li>, attach a load of drag-and-drop listeners.
    • (B1) Set <li draggable>.
    • (B2) On drag start, attach .hint to highlight all the list items.
    • (B3) When the dragged element hovers a list item, add .active to show a different highlight color.
    • (B4) When the dragged element leaves a list item, remove .active.
    • (B5) When the drag stops, remove all .hint and .active CSS classes.
    • (B6) Necessary. Prevents the default browser action, so we can define our own.
    • (B7) Some Math. Does the actual sorting on dropped.

 

 

DOWNLOAD & NOTES

Here is the download link to the example code, so you don’t have to copy-paste everything.

 

SORRY FOR THE ADS...

But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.

Buy Me A Coffee Code Boxx eBooks

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

EXTRA BITS & LINKS

That’s it for the example code, and here are some extras and links that you may find useful.

 

COMPATIBILITY CHECKS – NOTES ON MOBILE SUPPORT

Guess what? Mobile devices and browsers still don’t properly support drag-and-drop at the time of writing. If you have to do drag-and-drop on mobile devices, the best bet is to use a “polyfill” such as DragDropTouch and MobileDragDrop.

 

THE SUMMARY – DRAG-DROP EVENTS

Event Description
dragstart Fired when the drag starts.
dragend Fired when the drag stops.
drag As the element is being dragged around.
dragenter When the mouse enters the boundaries of an element.
dragover As the element is being dragged over another element.
dragleave When the mouse exits the boundaries of an element.
drop Fired when the element is being dropped.

 

LINK & REFERENCES

 

TUTORIAL VIDEO

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you to better understand how vanilla Javascript drag and drop works. If you have anything to add to this guide, please feel free to comment below. Good luck and happy coding!

12 thoughts on “Drag and Drop Sortable List With Javascript (Simple Example)”

  1. For anyone to save the position with reload the browser, use this:

    /////////////// To Save and Show data ////////////////////////
    let your-variable = document.getElementById(“your-id”);
    function saveData(){
    localStorage.setItem(“data”, your-variable.innerHTML);
    }
    function showTask(){
    your-variable.innerHTML = localStorage.getItem(“data”);
    }
    showTask();

    /////////////// In drap and drop – take care of “saveData();” /////////////////
    ///// B5 /////
    // (B5) DRAG END – REMOVE ALL HIGHLIGHTS
    i.ondragend = () => { for (let it of items) {
    it.classList.remove(“hint”);
    it.classList.remove(“active”);
    saveData();
    }};

    ///// B7 /////
    // (B7) ON DROP – DO SOMETHING
    i.ondrop = e => {
    e.preventDefault();
    if (i != current) {
    let currentpos = 0, droppedpos = 0;
    for (let it=0; it<items.length; it++) {
    if (current == items[it]) { currentpos = it; }
    if (i == items[it]) { droppedpos = it; }
    }
    if (currentpos < droppedpos) {
    i.parentNode.insertBefore(current, i.nextSibling);
    saveData();
    } else {
    i.parentNode.insertBefore(current, i);
    saveData();
    }
    }

Leave a Comment

Your email address will not be published. Required fields are marked *