Click here to Skip to main content
Licence 
First Posted 17 Aug 2007
Views 20,126
Bookmarked 22 times

JavaScript Reorderlist

By | 22 Aug 2007 | Article
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

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralThis has been done PinmemberAntonioCS10:31 21 Aug '07  
GeneralRe: This has been done PinmemberTom Hawkins4:51 23 Aug '07  

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.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 22 Aug 2007
Article Copyright 2007 by Jassem Abdal
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid