Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 UL LI Draggable

I have an unordered list:

  • List item 1
  • List item 2
  • List item 3
  • List item 4
  • List item 5

Implemented with this code:

<ul>
  <li>List item 1</li>
  <li>List item 2</li>
  <li>List item 3</li>
  <li>List item 4</li>
  <li>List item 5</li>
</ul>

Now, I want it to be draggable. For example, if I drag "List item 5" upward, I can place it between "List item 2" and "List item 3", and it'll become third.

I want to do this without jQuery, just plain Javascript. Also, I'd like to use native HTML5 draggable="true". Any help would be appreciated.

like image 443
Anand Chowdhary Avatar asked Sep 08 '12 16:09

Anand Chowdhary


2 Answers

Attribute "draggable" only enables the element for dragging. You need to implement the DnD listener and implement the drop event to make the changes you want.

You will find the same problem you want to solve in this example: http://www.html5rocks.com/en/tutorials/dnd/basics/

In the example they implement drag-drop for columns A, B and C. User can change the order by DnD.

like image 71
18bytes Avatar answered Sep 30 '22 18:09

18bytes


This code will solve your problem. Redone example with MDN Try it this jsfiddle.net

HTML 5

<ul>
  <li class="dropzone" id='0' draggable="true">List item 1</li>
  <li class="dropzone" id='1' draggable="true">List item 2</li>
  <li class="dropzone" id='2' draggable="true">List item 3</li>
  <li class="dropzone" id='3' draggable="true">List item 4</li>
  <li class="dropzone" id='4' draggable="true">List item 5</li>
</ul>

pure JS

let dragged;
let id;
let index;
let indexDrop;
let list;

  document.addEventListener("dragstart", ({target}) => {
      dragged = target;
      id = target.id;
      list = target.parentNode.children;
      for(let i = 0; i < list.length; i += 1) {
        if(list[i] === dragged){
          index = i;
        }
      }
  });

  document.addEventListener("dragover", (event) => {
      event.preventDefault();
  });

  document.addEventListener("drop", ({target}) => {
   if(target.className == "dropzone" && target.id !== id) {
       dragged.remove( dragged );
      for(let i = 0; i < list.length; i += 1) {
        if(list[i] === target){
          indexDrop = i;
        }
      }
      console.log(index, indexDrop);
      if(index > indexDrop) {
        target.before( dragged );
      } else {
       target.after( dragged );
      }
    }
  });
like image 43
Владимир Казак Avatar answered Sep 30 '22 20:09

Владимир Казак