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!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

Download & Demo Sortable List Useful Bits & Links
The End

 

DOWNLOAD & DEMO

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

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.

 

SORTABLE LIST DEMO

  • First
  • Second
  • Third
  • Forth
  • Fifth

 

 

DRAG-AND-DROP SORTABLE LIST

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

 

STEP 1) THE HTML

sort-list.html
<!-- (A) LOAD CSS + JS -->
<link rel="stylesheet" href="sort-list.css"/>
<script src="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) INIT ON PAGE LOAD -->
<script>
window.addEventListener("DOMContentLoaded", () => {
  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

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

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 = (ev) => {
      current = i;
      for (let it of items) {
        if (it != current) { it.classList.add("hint"); }
      }
    };
    
    // (B3) DRAG ENTER - RED HIGHLIGHT DROPZONE
    i.ondragenter = (ev) => {
      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 = (evt) => { evt.preventDefault(); };
 
    // (B7) ON DROP - DO SOMETHING
    i.ondrop = (evt) => {
      evt.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.

 

 

USEFUL 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? Some older mobile devices and browsers don’t support draggable… If you have to do drag-and-drop on mobile devices, the best bet is to use a “polyfill” such as Draggin.

 

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

 

YOUTUBE TUTORIAL

 

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!

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

  1. I wanted to have a red line showing where the item was dropped so I used `.active { border-top: 2px solid red; }` as style and simplified the drop code to just

    evt.preventDefault();
    if (this != current)
    this.parentNode.insertBefore(current, this);

    which made it always work as expected. Though this only really works well for small (height) elements as it is kind of unintuitive when the red line is a long distance away from the cursor.

    Also removed the getElementById (to be able to pass element references directly instead of only IDs)

    1. Are you sure it “always works as intended” after “simplifying” the drop calculations? There is a good reason why I did that. 😉

      Hint: Try swapping the first with the second. You might want to do more calculations to check if it is border-top or border-bottom.

  2. I’m in agreement with CN. It is ridiculously difficult to do something that supposedly doesn’t take much code to do at all. * REMOVED – UNINTELLIGIBLE DUMB TROLL NOISES *

    1. Agree with what? Guy only posted a question. There was no mention of “difficult”, nor negative suggestions. Go learn how to read basic English and stop embarrassing yourself first?

      P.S. Since you claim “it doesn’t take much code to do” – I am interested to see how a genius such as yourself make an already barebones example even shorter. While showcasing all the drag-and-drop events PLUS sort capability.

      https://code-boxx.com/faq/#nolike

  3. I’m doing a javascript course. Recently, I built a “to do” list, that saved the list of to dos in local storage.

    I added your script to the app and it worked, more or less out of the box!

    However, I can’t figure out how to add the positions to local storage – data in local storage, as you know, always gets stored as a string. What strings could be stored that relate to the position of the list items?

    I’ve googled this, but haven’t found any answers.

Leave a Comment

Your email address will not be published.