Tuesday, June 30, 2009

Drag and Drop UltraWebTree nodes in Mozilla Firefox using Infragistics Drag and Drop Framework

Infragistics dont support drag and drop tree nodes for UltraWebTree in Firefox. To go around this, you need to use Infragistics drag and drop Framework.

First, in your project/ website, add this reference: "Infragistics2.Web.v9.1" if Infra CLR 2.0 is installed. For CLR 3.5, you should add: "Infragistics35.Web.v9.1". Its a bit tricky to add it in websites. For websites, you may need to copy the dll into the deploy folder first. Then add the reference in the website.

Then, in your usercontrol, or page, or in master page (whichever applicable) add these assembly:

<asp:ScriptManager ID="ScriptManager1" runat="server" EnableScriptGlobalization="true"
AsyncPostBackTimeout="9600">
<Scripts>
<asp:ScriptReference Assembly="Infragistics2.Web.v9.1, Version=9.1.20091.2040, Culture=neutral, PublicKeyToken=7dd5c3163f2cd0cb" Name="Infragistics.Web.UI.SharedScripts.igDragDrop.js" />
<asp:ScriptReference Assembly="Infragistics2.Web.v9.1, Version=9.1.20091.2040, Culture=neutral, PublicKeyToken=7dd5c3163f2cd0cb" Name="Infragistics.Web.UI.Scripts.5_igObjects.js" />
</Scripts>
</asp:ScriptManager>

You need to be careful about the CLR and version of the infragistics. Here, the version is 2040. But you can check it from your web.config, which version of infragistics is installed in your PC. Use your own version in the string.

In the page/ usercontrol, add this script:

<script type="text/javascript">
Sys.Application.add_load(app_loaded);

function app_loaded()
{
InitiateDragDropFrameWorkToNodes();
}
</script>

This must follow the script manager.

now add scripts in a separate javascript file, and reference it in the page/ usercontrol. I always prefer to use a separate javascript file, because it allows you to debug the script. Add this in the .js file:

var ddR = new $IG.DragDropBehavior();
var dropLoop=true;


function InitiateDragDropFrameWorkToNodes()
{
var treeInstance = igtree_getTreeById(UltraWebTreeClientID); //tree client id passed from pageload.


var firstlevel=treeInstance.getNodes();



//loops through all the first level nodes, usually there wont be more than 1 in our project

for(var i=0;i<firstlevel.length;i++)
{
var treeNode= firstlevel[i];
ddR.addSourceElement(treeNode.getElement());//this line was not needed, but if the root node is not included, then infra's built in drag drop starts, and gives different look.
ddR.addTargetElement(treeNode.getElement());
if(treeNode.hasChildren())
{
AssaignDragSource(treeNode);
}

}
if(ddR._events._handlers.Drop==null||ddR._events._handlers.Drop.length<1){ //this is the most important line, handler should be added only once and not again.
ddR.get_events().addDropHandler(drop);
}

}


function AssaignDragSource( treeNode)
{

var children=treeNode.getChildNodes();

for(var j=0;j<children.length;j++)
{

var element=children[j].getElement();
ddR.addSourceElement(element);
ddR.addTargetElement(element, true);

if(children[j].hasChildren())
{
AssaignDragSource(children[j]); //recursively call all children to add dragdropbehavior


}

}
}

function drop(sender, eventArgs) {
if ( dropLoop==true){

var treeInstance = igtree_getTreeById(UltraWebTreeClientID);
var source = eventArgs.get_manager().get_source().element;
var startNode=treeInstance.getNodeById(source.id);
var startNodes = startNode.getChildNodes();
var target= eventArgs.get_manager().get_target().element;
var endNode=treeInstance.getNodeById(target.id);
if(startNode==endNode){

return;
}

// alert('I am here');

var parentNode = endNode.getParent();
while (parentNode != null) {
if (parentNode == startNode) {
dropLoop=false;//whenever an alert is shown, it reenters the drop event even return is called, its fixed here
alert(msgCannotMoveParentUnderChild);
return;
}
parentNode = parentNode.getParent();
}

CopyNode(endNode, startNode);
//endNode.addChild(startNode.getText());
if (startNode.hasChildren()) {
addDroppedChildren(endNode.getChildNodes()[endNode.getChildNodes().length - 1], startNodes);
}


startNode.remove();


igtree_needPostBack(UltraWebTreeClientID);
var ts = igtree_treeState[UltraWebTreeClientID];
__doPostBack(ts.UniqueId, endNode.element.id + ":Update");
}
dropLoop=true; //allow to enter drop function after the alert message hastle is over.
}

function CopyNode(toNode, fromNode) {

newNode = toNode.addChild(fromNode.getText());
newNode.setTag(fromNode.getTag());
}

function addDroppedChildren(endNode, startNodes) {

for (var i = 0; i < startNodes.length; i++) {
CopyNode(endNode, startNodes[i]);
//endNode.addChild(startNodes[i].getText());
if (startNodes[i].hasChildren()) {
addDroppedChildren(endNode.getChildNodes()[endNode.getChildNodes().length - 1], startNodes[i].getChildNodes());
}
}

}

This will allow you to drag and drop tree nodes (including children nodes) in firefox. These two posts was really helpful with drag and drop framework:
Drop it Like its Windows
Introduction to the Infragistics Web Drag and Drop Framework

No comments: