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

Wednesday, June 10, 2009

Use RegularExpressionValidator to validate a URL / web address

This is a nice RegularExpressionValidator to validate URLs:

<asp:RegularExpressionValidator ID="RegularExpressionValidator2" runat="server"
ControlToValidate="uxRssUrl" ErrorMessage="<%$ Resources:Texts, InvalidUrl %>"
ValidationExpression="^(ht|f)tp(s?)\:\/\/([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z]))*\.([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z]))*\.(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$"
ValidationGroup="ResellerValidation"></asp:RegularExpressionValidator>">

This RegularExpressionValidator will check whether the content starts with:
(ftp:// ftps:// http:// https://) and before the next '/' comes whether there is at least 2 '.' in it.

This site is helpful for RegularExpressionValidator:
How To: Use Regular Expressions to Constrain Input in ASP.NET

Tuesday, June 2, 2009

How to check whether a variable has been declared from Javascript

Sometimes we declare javascript variables from serverside pageload method and use it in a common javascript file's method. The problem is, when that common javasript method is used by another serverside file, it might find that variable undefined. The best way to check is use typeof method of javascript. Consider the following method:

if(typeof(uxDocumentsOrImagesRadioButton)!= 'undefined'){
if(document.getElementById(uxDocumentsOrImagesRadioButton)!=null){

var thisradioGroup = document.getElementById(uxDocumentsOrImagesRadioButton);
if(thisradioGroup.disabled==true){
thisradioGroup.disabled=false;
}
}
}

uxDocumentsOrImagesRadioButton variable is declared from a page's pageload method. But if another page wants to use this method before that variable has been declared, then it will throw error. So, we need to check whether the variable has been declared previously.