Drag and copy with Dojo

This article applies to Dojo version 0.4. The latest version is 1.2.0


Click here to see the demo



Recently I was asked how drag and paste can be implemented using Dojo. Means you start dragging an object and instead of dropping the object itself , you drop a copy of it. There can be quite a few ways of doing this. I'll discuss the lazy programmers way of doing it. No deriving your own class or going through the source code.

The basic idea is, when content is dropped onto target, create another copy at its original location. We can write a javascript function that does this (using innerHTML method) and hook up this function to 'onDrop' event of single or multiple targets.

One important thing for drag and drop in Dojo is your content needs to be enclosed in a container tag with distinct 'id'. This is referred to as source. So when we speak of creating another copy of original content, we need to ensure that we create a new id every time.

Without wasting time let us look at the example. Here we have a single source (content that is to be dragged) and three targets(where source can be dropped). The HTML looks like this:

<div id="placeholder">
    <div id="w1"><img src='images/ball.jpg'/></div>
</div>
<table><tr valign=top>
<td>
<strong>Target R</strong>
<div id="leftdiv" style="height:100px;width:100px;border:dotted 3px red;"></div>
</td>
<td>
<strong>Target G</strong>
<div id="centerdiv" style="height:100px;width:100px;border:dotted 3px green"></div>
</td>
<td>
<strong>Target B</strong>
<div id="rightdiv" style="height:100px;width:100px;border:dotted 3px blue"></div>
</td>
</tr></table>

In the above HTML snippet, <div id="placeholder"> acts as a placeholder for the source. It itself does not take part in drag and drop.The source only contains an image. A new copy of source is created inside this placeholder, after a drop(or paste) operation.
There is a single source with id "w1" and three targets where it can be dragged and pasted(dropped).

Lets now see the javascript that gets job done. The important piece of code is the 'CreateCopy' function that creates new copy of the source under 'placeholder'. Notice how the function is attached to 'onDrop' event of all the targets. The variable 'i' is incremented after every paste(drop) operation to generate a distinct id for the newly created source copy.

var i=0;
var t1,t2,t3;
			
function init()
{
    new dojo.dnd.HtmlDragSource("w1", "left");
    		
    t1 =   new dojo.dnd.HtmlDropTarget("leftdiv", ["left"]);
    t2 = new dojo.dnd.HtmlDropTarget("rightdiv",["left"]);
    t3 = new dojo.dnd.HtmlDropTarget("centerdiv",["left"]);
	            
    dojo.event.connect(t1,"onDrop","CreateCopy");
    dojo.event.connect(t2,"onDrop","CreateCopy");
    dojo.event.connect(t3,"onDrop","CreateCopy");	
}
    	    
function CreateCopy()
{   i++;  
    var newid="copy"+i;
    document.getElementById("placeholder").innerHTML="<div id='"+newid+"'><img src='images/ball.jpg'/></div>";
    new dojo.dnd.HtmlDragSource(newid, "left");
}
        
dojo.event.connect(dojo, "loaded", "init");

The rest of code is self-explanatory. You should check out the demo page and its source for complete listing. Now, suppose you want to restrict the number of total copies made, then simply change the value of 'acceptedTypes' member of the target. In above code it can be achieved by modifying 'CreateCopy' like this:

function CreateCopy()
{   i++;  
    
    if(i ==5)
    {   t1.acceptedTypes =[""];
        t2.acceptedTypes =[""];
        t3.acceptedTypes =[""];
    }
    else
    {
        var newid="copy"+i;
        document.getElementById("placeholder").innerHTML="<div id='"+newid+"'><img src='images/ball.jpg'/></div>";
        new dojo.dnd.HtmlDragSource(newid, "left");
    }
  
}

Similarly using different handler functions or counters it is possible to restricts number of copies in a particular target.


Copyright (c) 2007-2013 Ashish Patil . Please read FAQ for more details.

comments powered by Disqus