Click here to Skip to main content
Click here to Skip to main content

JavaScript Reorderlist

, 22 Aug 2007
Rate this:
Please Sign up or sign in to vote.
Reorderlist using JavaScript that allows dragging between lists

Screenshot - reorderlist1.gif

Introduction

I was playing around with the Microsoft AJAX Reorderlist control and I wanted to be able to drag items between the 2 Reorderlists. I realized this wasn't going to happen any time soon unless I wrote it myself in JavaScript.

Background

To create this kind of functionality, I decided to use a container div with divs inside representing the items to reorder. I used DOM to maneuver the divs appropriately based on jscript mouse dragging events (ondragstart, ondrag, ondragover, ondrop). I checked the Y-axis position of the mouse cursor inside the container div against all of its child divs' Y-axis positions (plus half the child's height) to determine where the dragged div should go. If the mouse cursor position is outside of a container div when ondrop is fired, the child div's original placement is restored. Currently, it only works for IE because I haven't looked into FF mouse dragging events yet.

Using the Code

Just copy and paste this into an HTML file to run it.

<head>
<script type="text/javascript">

var divFollow, divPreview, divDrag, divMove, divParent, divBefore, 
    divAfter, mouseX, mouseY, halfY, isInDiv;

function debug(s)
{
  document.getElementById("debug").innerHTML=s;
}

function getMouseX(e) 
{
    return e.pageX
        || ( e.clientX+(document.documentElement.scrollLeft
        || document.body.scrollLeft));
}

function getMouseY(e) 
{
    return e.pageY
        || (e.clientY+(document.documentElement.scrollTop
        || document.body.scrollTop));
}

function childDragStart(obj,e)
{
    divDrag=obj;
    divBefore=null;
    divAfter=null;
    divBefore=divDrag.previousSibling;
    divAfter=divDrag.nextSibling;
}

function childDrag(obj,e)
{
    mouseX=getMouseX(e);
    mouseY=getMouseY(e);
    divFollow.innerHTML=obj.innerHTML;
    halfY=divFollow.offsetHeight/2;
    divFollow.style.left=mouseX+15;
    divFollow.style.top=mouseY-halfY;
  
    if((mouseY>divParent.offsetTop+divParent.offsetHeight) 
        ||(mouseX>divParent.offsetLeft+divParent.offsetWidth)
        ||(mouseY<divParent.offsetTop)
        ||(mouseX<divParent.offsetLeft)) isInDiv=false;
    else isInDiv=true;
  
    for(var i=0;divParent.childNodes[i];i++)
    {
        node=divParent.childNodes[i];
       if(mouseY-divParent.offsetTop < (node.offsetHeight/2)+node.offsetTop)
        {    
            divParent.insertBefore(divPreview,divParent.childNodes[i]);
            return;    
        }
    }    
    divParent.appendChild(divPreview);
}

function parentDragOver(obj,e)
{
    divParent=obj;
}

function parentDrop(obj,e)
{ 
    var p=document.getElementById("divPreview");
    var n;
    if(divDrag && isInDiv)
    {
        if(p)
        {
            divParent.insertBefore(divDrag,p);            
            divParent.removeChild(p);            
            divDrag=null;
        }
    }
    else if(divDrag)
    {
        //restore original position
        n=divDrag.parentNode;
        if(divAfter) n.insertBefore(divDrag,divAfter);
        else n.appendChild(divDrag);
        divDrag=null;
        if(p) divParent.removeChild(p);
    }
    divFollow.style.left=-1000;
    divFollow.style.top=-1000;
    divDrag=null;
}

//do some initialization.
function initReorderlists(page)
{
    eventpage=page; //page to pass reorderlist events to.
    divDrag=null;
  
    divFollow=document.createElement("div");
    divFollow.style.border="1px solid black";
    divFollow.style.color="black";
    divFollow.style.fontWeight="bold"
    divFollow.backgound="transparent";
    divFollow.id="divFollow";
    divFollow.style.position="absolute";
    divFollow.style.left=-1000;
    divFollow.style.top=-1000;
    document.body.appendChild(divFollow);
  
    divPreview=document.createElement("div");
    divPreview.innerHTML=" ";
    divPreview.style.color="red";
    divPreview.backgound="transparent";
    divPreview.id="divPreview";
    divPreview.style.border="1px dotted black";  
}
</script>
</head>

<body onload="initReorderlists()">

<div ondragover="parentDragOver(this,event)" 
    ondragend="parentDrop(this,event)" id="div1" 
    style="border:1px solid black;width:300px">
    <div><img ondrag="childDrag(this.parentNode,event);" 
        ondragstart="childDragStart(this.parentNode,event);" 
        src="drag.gif"/>div1 child1</div>
    <div><img ondrag="childDrag(this.parentNode,event);" 
        ondragstart="childDragStart(this.parentNode,event);" 
        src="drag.gif"/>div1 child2</div>
    <div><img ondrag="childDrag(this.parentNode,event);" 
        ondragstart="childDragStart(this.parentNode,event);" 
        src="drag.gif"/>div1 child3</div>
    <div><img ondrag="childDrag(this.parentNode,event);" 
        ondragstart="childDragStart(this.parentNode,event);" 
        src="drag.gif"/>div1 child4</div>
    <div><img ondrag="childDrag(this.parentNode,event);" 
        ondragstart="childDragStart(this.parentNode,event);" 
        src="drag.gif"/>div1 child5</div>
</div>

<div ondragover="parentDragOver(this,event)" 
    ondragend="parentDrop(this,event)" id="div2" 
    style="border:1px solid black;width:300px">
    <div><img ondrag="childDrag(this.parentNode,event);" 
        ondragstart="childDragStart(this.parentNode,event);" 
        src="drag.gif"/>div2 child1</div>
    <div><img ondrag="childDrag(this.parentNode,event);" 
        ondragstart="childDragStart(this.parentNode,event);" 
        src="drag.gif"/>div2 child2</div>
    <div><img ondrag="childDrag(this.parentNode,event);" 
        ondragstart="childDragStart(this.parentNode,event);" 
        src="drag.gif"/>div2 child3</div>
    <div><img ondrag="childDrag(this.parentNode,event);" 
        ondragstart="childDragStart(this.parentNode,event);" 
        src="drag.gif"/>div2 child4</div>
    <div><img ondrag="childDrag(this.parentNode,event);" 
        ondragstart="childDragStart(this.parentNode,event);" 
        src="drag.gif"/>div2 child5</div>
</div>

<div id="debug"></div>

</body>

History

  • 22 August, 2007 -- Rewritten to use ondrag* events instead of onmouse* events
  • 17 August, 2007 -- Original version posted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Jassem Abdal

United States United States
No Biography provided

Comments and Discussions

 
GeneralThis has been done PinmemberAntonioCS21-Aug-07 10:31 
GeneralRe: This has been done PinmemberTom Hawkins23-Aug-07 4:51 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140709.1 | Last Updated 22 Aug 2007
Article Copyright 2007 by Jassem Abdal
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid