sortable-draggable-js is a JavaScript library for reorderable drag-and-drop lists.

What is SortableJS

In sortable-draggable-js, any item can be sortable using new Sortable() method. new Sortable() takes two arguments, The first one is item which have to be sorted and second one takes options object where any customization can be applied.Below are the examples with every option so let get started with Demo's examples !

Example 1: Simple Sortable Box

It is the simple list, All elements are targeted one by one in a loop and became sortable. it takes single element for sorting unlike other libraries which takes Sortable parent only.
Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5
HTML

  
Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5
CSS

  body {
    background-color: #1f1f1f;
  }

  .sortable-container {
    width: 300px;
    max-height: 600px;
    border: solid #000000 1px;
    border-radius: 7px;
    margin: 18px 0;
    background-color: rgb(23 23 23);
    overflow: auto;
    padding: 15px;
  }

  .sort {
    display: flex;
    align-items: center;
    height: 46px;
    color: #747474;
    font-size: 13px;
    margin-top: 10px;
    border-radius: 5px;
    outline: solid #1f1f1f 1px;
    background-color: rgb(26 26 26);
  }
                      
Javascript

  document.querySelectorAll(".sort").forEach(function(item){
    const sortable = new Sortable(item);
  });
              

Example 2: Sorting in multiple boxes

SortableJS supports sorting in multiple containers, The Demo example uses containers options
Todo
Awake
Eat
InPrgress
Sleeping
Done
HTML

  
Todo
Awake
Eat
InPrgress
Sleeping
Done
CSS

  body {
    background-color: #1f1f1f;
  }
  
  .containers-example {
    display: flex;
    flex-wrap: wrap;
    gap: 25px;
  }

  .containers-example .container-wrapper {
    border: solid 1px #3d3d3d;
    border-radius: 7px;
    overflow: hidden;
    width: 100%;
    max-width: 300px;
  }

  .containers-example .container-wrapper .wrapper-head {
    background-color: #000000;
    width: 100%;
    text-align: center;
    padding: 10px;
  }

  .containers-example .container-wrapper .sort-container {
    min-height: 180px;
    border: none;
  }
                      
Javascript

  document.querySelectorAll(".sort").forEach(function(item){
    const sortable = new Sortable(item, {
      containers: "sort-container", // comma seperated appendable boxes classes,
    });
  });
              

Example 3: Sortable containers

The containers can also be sortable and appendable at same time.It is also targeted by new Sortable() method.
Should Do
I am container and also sortable
Awake
Eat
Should not Do
I am container and also sortable
Sleep
HTML

  
Should Do
I am container and also sortable
Awake
Eat
Should not Do
I am container and also sortable
Sleep
CSS

  body {
    background-color: #1f1f1f;
  }
  
  .containers-example {
    display: flex;
    flex-wrap: wrap;
    gap: 25px;
  }

  .containers-example .container-wrapper {
    border: solid 1px #3d3d3d;
    border-radius: 7px;
    overflow: hidden;
    width: 100%;
    max-width: 300px;
  }

  .containers-example .container-wrapper .wrapper-head {
    background-color: #000000;
    width: 100%;
    text-align: center;
    padding: 10px;
  }

  .containers-example .container-wrapper .sort-container {
    min-height: 180px;
    border: none;
  }
              
Javascript

  document.querySelectorAll(".sort").forEach(function(item){
    const sortable = new Sortable(item, {
      containers: "sort-container", // comma seperated appendable boxes classes,
    });
  });
              

Example 4: Prevented containers

The Specific item can decide for it have to be append or not.This uses Prevented Containers option.
Home
I can go to School 😀
I cannot go to School 😈
School
HTML

  
Should Do
I am container and also sortable
Awake
Eat
Should not Do
I am container and also sortable
Sleep
CSS

  body {
    background-color: #1f1f1f;
  }
  
  .containers-example {
    display: flex;
    flex-wrap: wrap;
    gap: 25px;
  }

  .containers-example .container-wrapper {
    border: solid 1px #3d3d3d;
    border-radius: 7px;
    overflow: hidden;
    width: 100%;
    max-width: 300px;
  }

  .containers-example .container-wrapper .wrapper-head {
    background-color: #000000;
    width: 100%;
    text-align: center;
    padding: 10px;
  }

  .containers-example .container-wrapper .sort-container {
    min-height: 180px;
    border: none;
  }
              
Javascript

  document.querySelectorAll(".sort").forEach(function(item){
    const sortable = new Sortable(item, {
      containers: "sort-container,school-container", // comma seperated appendable boxes classes,
      preventedContainers: !item.classList.contains("can-go")
        ? "school-container"
        : "",
    });
  });
              

Example 5: Fallback Elements

Fallback Element takes HTML element which will drop instead of sortable element.It will prevent from sorting and will drop a provided html fallback Element if fallbackClone option is false which is defaults to true then it will drop single Element means if you drop an Element and start drop on another container, The previous one will replace from it instead of dropping another one Check Options API below for more information.This uses fallBackElement and fallBackClone option.

With Clone (default)

Fallback
I will Drop Fallback
Drop here Fallback
Drop here Fallback

Without Clone

Fallback
I will Drop Fallback
Drop here Fallback
Drop here Fallback
HTML

    
Fallback
I will Drop Fallback
Drop here Fallback
Drop here Fallback
CSS

                
  body {
    background-color: #1f1f1f;
  }
  
  .containers-example {
    display: flex;
    flex-wrap: wrap;
    gap: 25px;
  }

  .containers-example .container-wrapper {
    border: solid 1px #3d3d3d;
    border-radius: 7px;
    overflow: hidden;
    width: 100%;
    max-width: 300px;
  }

  .containers-example .container-wrapper .wrapper-head {
    background-color: #000000;
    width: 100%;
    text-align: center;
    padding: 10px;
  }

  .fallback {
    border: rebeccapurple 1px solid;
  }

  .fallback-element {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 50px;
    font-size: 12px;
    color: white;
    border: rebeccapurple solid 1px;
    background: #2e003f;
  }
              
Javascript

  document.querySelectorAll(".fallback").forEach(function(item){
    const sortable = new Sortable(item, {
      containers: "sort-container", // comma seperated appendable boxes classes,
      fallBackElement: `
I am fallback
`, fallBackClone: !item.classList.contains("Without-clone"), }); });

Example 6: Zoomed parent Elements

In some cases, page has CSS zoom which works same as transform : scale(); property, and dragging libraries get disturbed from zoom, to prevent this disturbation,we proviided zoom and zoomedElement The contrast between both options are if you know the value of zoom of your page or page zoom is static and will not change then you can go for zoom option but if your page has dynamic or changeable zoom then you will need to pass zoomedElement option which is recommonded method because it will check it's css zoom property on every sort start which ranges between 0-1.
I will not work perfect after zoom
Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5
I will work perfect after zoom
Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5
HTML

  
I will not work perfect after zoom
Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5
I will work perfect after zoom
Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5
CSS

  body {
    background-color: #1f1f1f;
  }
  
  .containers-example {
    display: flex;
    flex-wrap: wrap;
    gap: 25px;
  }

  .containers-example .container-wrapper {
    border: solid 1px #3d3d3d;
    border-radius: 7px;
    overflow: hidden;
    width: 100%;
    max-width: 300px;
  }

  .containers-example .container-wrapper .wrapper-head {
    background-color: #000000;
    width: 100%;
    text-align: center;
    padding: 10px;
  }

  span.message {
    display: inline-block;
    font-size: 12px;
    color: #088d9c;
    padding-bottom: 10px;
  }
              
Javascript

  const containers = sections[4]?.querySelectorAll(".sortable-container");
  containers[0].querySelectorAll(".sort").forEach(function(item, i) {
    const sortable = new Sortable(item);
  });
  containers[1].querySelectorAll(".sort").forEach(function(item, i) {
    const sortable = new Sortable(item, {
      zoomedElement: item.closest(".containers-example"),
      // or zoom option like zoom : 0.5
    });
  });
              

Example 7: Disabled method

Any item can be disable after sortable. new Sortable() method returns another method for disable like item.disable(),To re-enable it can be re-enable by passing false into disbale method parameter like item.disable(false) and any class can applied through disabledClass option.
Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5
HTML

  
Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5
CSS

  body {
    background-color: #1f1f1f;
  }

  .sortable-container {
    width: 300px;
    max-height: 600px;
    border: solid #000000 1px;
    border-radius: 7px;
    margin: 18px 0;
    background-color: rgb(23 23 23);
    overflow: auto;
    padding: 15px;
  }

  .sort {
    display: flex;
    align-items: center;
    height: 46px;
    color: #747474;
    font-size: 13px;
    margin-top: 10px;
    border-radius: 5px;
    outline: solid #1f1f1f 1px;
    background-color: rgb(26 26 26);
  }

  .disabled {
    opacity: 0.3;
  }
                      
Javascript

  document.querySelectorAll(".sort").forEach(function(item) {
    const sortable = new Sortable(item, {
      disabledClass: "disabled",
    });
    if (i % 2 !== 0) { // for even
      const oldHTML = item.innerHTML;
      sortable.disable();
      item.innerHTML = "Click me to Re-Enable";

      function reEnable() {
        sortable.disable(false);
        item.removeEventListener("click", reEnable);
        item.innerHTML = oldHTML;
      };

      item.addEventListener("click", reEnable);
    }
  });
              

Example 8: Handle method

The example uses handle option. defaults to false, if this option recieves html string or DOM object it will be showed to handle and if it recieve true, the default handle will render any css Class for handle can be pass using handleClass option.

Default Handle

Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5

Custom Handles

Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5
HTML

    

Default Handle

Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5

Custom Handles

Hello I am a Element 1
Hello I am a Element 2
Hello I am a Element 3
Hello I am a Element 4
Hello I am a Element 5
CSS

  body {
    background-color: #1f1f1f;
  }

  .sortable-container {
    width: 300px;
    max-height: 600px;
    border: solid #000000 1px;
    border-radius: 7px;
    margin: 18px 0;
    background-color: rgb(23 23 23);
    overflow: auto;
    padding: 15px;
  }

  .sort {
    display: flex;
    align-items: center;
    height: 46px;
    color: #747474;
    font-size: 13px;
    margin-top: 10px;
    border-radius: 5px;
    outline: solid #1f1f1f 1px;
    background-color: rgb(26 26 26);
  }
                      
Javascript

  const containers = document.querySelectorAll(".sortable-container");

  containers[0].querySelectorAll(".sort").forEach((item, i) => {
    const sortable = new Sortable(item, {
      handle: true,
    });
  });
  containers[1].querySelectorAll(".sort").forEach((item, i) => {
    const sortable = new Sortable(item, {
      handle:
        i % 2 !== 0
          ? "👀"
          : ``,
    });
  });
              

Options Used

Options Description
containers It receives comma seperated classes like "my-container,another-container" for container.It makes the div appendable.While sorting the element any sortable can be append into container, to prevent sort to append,the preventedContainers option will required in sortable's option.
preventedContainers It also recieves comma seperated classes for the container, every sortable element can decide,It have to be drop in container or not.
zoom It receives number value of zoom, defaults to 1.CSS zoom property value ranges between 0-1 for small scale and greater then 1 for large scale.if your container has zoom then this option should use to prevent sorting issues.
zoomedElement It also receives number value of zoom, defaults to 1.It is a recommended method to utilize, if sorting parent has zoom,it will watch the element if zoom changes or not so there is no chance to disturb sorting.
fallBackElement It recieves html string element or DOM element,defaults to null.It will drop the fallback element instead of real sorting element.It works only for another container and sortable for same container.
fallBackClone it receives boolean true | false.defaults to true.By default it drops a clone of provided fallback element.if it's fallbackClone value is false,It will not drop a clone.It drop single element for every drop.
handle It recieves boolen Or html string or DOM element for handle.Defaults to false.By default it works on clicking on any area of sortable,but if it receives true, it will apply default handles so mouse will have to be click on handle for sorting purpose.If it receive any element, the element will work as handle
handleClass it recieves string class to apply on handle.any customization for handle can be handled from css through provided class.
onStart It receives callback funtion.The function will invoked if user starts sorting any element.It gives itemdetails in parameter of callback.
onSort It receives callback funtion.SortableJS call this function if item has been succesfully sorted.It gives itemdetails in parameter of callback.
onDrop It receives callback funtion.SortableJS call this function for every drop,even if item is sorted or not.Item details can be found in it's paramter
itemClass It receives string class,The class will apply for sortable element.
draggingClass It also receives class.The class will apply if item starts moving for sorting.
.disbale() this method is returned from new Sortable() method.any item can be disabled for sorting through this method
disabledClass if item is disabled , the provided class will apply until the item is re-enable