Click here to Skip to main content
15,908,254 members
Articles / Web Development / HTML
Tip/Trick

Reorganisable List with JavaScript

Rate me:
Please Sign up or sign in to vote.
4.80/5 (2 votes)
19 Nov 2013CPOL1 min read 13.2K   50   3   5
Example of how to make a list whose items can change positions

Introduction

This tip shows how one can make a <ul>'s <li>s can be reorganised by "swapping" positions between different <li>s as the mouse is dragged over them.

A working example can be found here (pure JavaScript version) or here (jQuery version).

This currently works on Google Chrome well. I cannot speak for other browsers.

Using the Code

The "swap" is actually done by taking the content of one <li> and exchanging it with another one. The HTML for this looks as follows:

HTML
<ul>
    <li>
        <span class="item">Kevin</span>    <!-- The content -->
        <span class="drag"></span>    <!-- The drag icon -->
    </li>
    ...
    <li>
        <span class="item">Roe</span>
        <span class="drag"></span>
    </li>
</ul> 

The phantom list item that follows the mouse as you hold down the mouse and drag is positioned above the <ul> and positioned absolutely in the CSS;

HTML
<div id="phantom">
    <span class="item">Amygdala</span>
    <span class="drag"></span>
</div> 

The JavaScript is configured to listen for a mousedown event on the drag icon for any list item. This sets a flag to true so that any mousemove event triggered any <li> triggers a "swap" between the <li>s. Once the mouseup event which is attached to the <ul> element is triggered, the flag is negated to false preventing any other swaps. The code looks like this:

JavaScript
window.onload = function() {
    var index = -1;        //This is the item index of the item being moved
    var over = -1;        //This is the new position
    var item = '';        //This is the current items content
    var swap = '';        //This is the content of the item it will replace
    var move = false;    //This determines if we can change two items' positions

    var container = document.getElementById('container');        //This is the parent of our list
    var ul = document.getElementById('container').children[2];    //This is the list of items
    var phantom = document.getElementById('phantom');            //This is the opaque copy of the item being moved

    phantom.onmousemove = function(e) { e.preventDefault(); }    //This prevent the mouse from highlighting stuff

    ul.onmouseup = function(e) {
    //This function is called when the action of shifting positions is done when dragging items
        phantom.style.display = 'none';
        move = false;
    }

    for(var i = 0; i < ul.children.length; i++) {
            ul.children[i].children[1].onmousedown = function(e) {    
             //This event is attached to the drag icon in the list item
            move = true;
            index = Array.prototype.indexOf.call(ul.children, 
            	e.target.parentElement);    //Get the index of the item in question
            item = ul.children[index].children[0].innerHTML; //Get it's content as well
            phantom.children[0].innerHTML = item; //Give the phantom item the same content
            phantom.style.display = 'block';      //Display the phantom item
        }
    }

    for(var i = 0; i < ul.children.length; i++) {
        ul.children[i].onmouseover = function(e) { //This function ensures all list item positions can be swapped
            if(Array.prototype.indexOf.call(ul.children, 
            	e.target) != -1 && move) {    //Ensure you get the list item position and can move
                over = Array.prototype.indexOf.call(ul.children, e.target); // The new position
                swap = ul.children[over].children[0].innerHTML;   //Get the current content of the new position
                ul.children[index].children[0].innerHTML = swap;  //Change the content of the item in question
                ul.children[over].children[0].innerHTML = item;   //Change the content of the other item i.e the swap
                index = over;   // This ensure that your positions swap every time your move the mouse
            }
        }
    }

    ul.onmousemove = function(e) {    //This function displays the phantom list item appropriately
        e.preventDefault();
        if(index != -1) {
            //Its position is based on the containers offset top and 
            //it should be some pixels below the cursor hence the 5
            var top = e.pageY - parseInt
            (document.getElementsByTagName('ul')[0].getBoundingClientRect().top) + 5;
            phantom.style.marginTop = top + 'px';
        }    
    }
}

History

Update: 19-11-2013

I made a few small changes to the code to support Internet Explorer 7+. The changes are just work arounds so the logic remains the same. I unfortunately still can't tell what's going on with Mozilla but if I get it, I'll make the necessary changes.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Kenya Kenya
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionBTW Pin
Dewey4-Nov-13 15:38
Dewey4-Nov-13 15:38 
AnswerRe: BTW Pin
Kevin Murani4-Nov-13 17:43
Kevin Murani4-Nov-13 17:43 
GeneralRe: BTW Pin
Dewey16-Nov-13 6:41
Dewey16-Nov-13 6:41 
GeneralRe: BTW Pin
Kevin Murani18-Nov-13 23:38
Kevin Murani18-Nov-13 23:38 
Try it now. I made some changes. Does it still have an issue?
QuestionjQuery? Pin
Dewey4-Nov-13 15:26
Dewey4-Nov-13 15:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.