How to copy or move TreeNodes depending on the CTRL key
Description
The code below shows a pure client-side logic about how to perform drag and drop. Additionally, holding the CTRL
key determines whether the node will be copied or moved. The example below will copy
the node if the CTRL
key is pressed and move
it otherwise.
Solution
Option 1
<script>
var isCtrl = false;
document.onkeydown = function(e)
{
if(!e) e=window.event;
if(e.keyCode == 17)
isCtrl = true;
}
document.onkeyup = function(e)
{
if(!e) e=window.event;
if(e.keyCode == 17)
isCtrl = false;
}
function OnClientNodeDropping(sender, args)
{
var sourceNode = args.get_sourceNode();
var destNode = args.get_destNode();
if(destNode)
{
sender.trackChanges();
if(!isCtrl)
{
var newNode = new Telerik.Web.UI.RadTreeNode();
newNode.set_text(sourceNode.get_text());
newNode.set_value(sourceNode.get_value());
destNode.get_nodes().add(newNode);
CloneNode(newNode, sourceNode);
}
else
{
destNode.get_nodes().add(sourceNode);
}
destNode.set_expanded(true);
sender.commitChanges();
}
}
function CloneNode(newNode, sourceNode) {
if (sourceNode.get_nodes().get_count()>0) {
for (var i = 0; i < sourceNode.get_nodes().get_count(); i++) {
var node = sourceNode.get_nodes().getNode(i);
var newChildNode = new Telerik.Web.UI.RadTreeNode();
newChildNode.set_text(node.get_text());
newChildNode.set_value(node.get_value());
newNode.get_nodes().add(newChildNode);
CloneNode(newChildNode, node);
}
}
}
</script>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<telerik:RadTreeView
ID="RadTreeView1"
runat="server"
LoadingStatusPosition="BeforeNodeText"
EnableDragAndDrop="True"
OnClientNodeDropping="OnClientNodeDropping">
<Nodes>
<telerik:RadTreeNode runat="server" ExpandMode="ClientSide" Text="Root RadTreeNode11">
<Nodes>
<telerik:RadTreeNode runat="server" ExpandMode="ClientSide" Text="Child RadTreeNode 11">
</telerik:RadTreeNode>
</Nodes>
</telerik:RadTreeNode>
<telerik:RadTreeNode runat="server" ExpandMode="ClientSide" Text="Root RadTreeNode12">
<Nodes>
<telerik:RadTreeNode runat="server" ExpandMode="ClientSide" Text="Child RadTreeNode 12">
</telerik:RadTreeNode>
</Nodes>
</telerik:RadTreeNode>
</Nodes>
<CollapseAnimation Duration="100" Type="OutQuint" />
<ExpandAnimation Duration="100" Type="OutQuart" />
</telerik:RadTreeView>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<telerik:RadTreeView ID="RadTreeView2" runat="server" LoadingStatusPosition="BeforeNodeText" EnableDragAndDrop="True">
<Nodes>
<telerik:RadTreeNode runat="server" ExpandMode="ClientSide" Text="Root RadTreeNode21">
<Nodes>
<telerik:RadTreeNode runat="server" ExpandMode="ClientSide" Text="Child RadTreeNode 21">
</telerik:RadTreeNode>
</Nodes>
</telerik:RadTreeNode>
<telerik:RadTreeNode runat="server" ExpandMode="ClientSide" Text="Root RadTreeNode22">
<Nodes>
<telerik:RadTreeNode runat="server" ExpandMode="ClientSide" Text="Child RadTreeNode 22">
</telerik:RadTreeNode>
</Nodes>
</telerik:RadTreeNode>
</Nodes>
<CollapseAnimation Duration="100" Type="OutQuint" />
<ExpandAnimation Duration="100" Type="OutQuart" />
</telerik:RadTreeView>
Option 2
Another approach to use is simply indicating whether the action should be copy
or move
and perform the Drag And Drop at the server. There is a Clone()
method at the server side. You can use the NodeDrop
event to clone the source node and add it to the destination node. You can pass the value of the isCtrl
variable from the OnClientNodeDropping
event to the server NodeDrop
event by setting this value as a custom attribute to the source node, like:
<script>
var isCtrl = false;
document.onkeydown = function(e)
{
if(!e) e=window.event;
if(e.keyCode == 17)
isCtrl = true;
}
document.onkeyup = function(e)
{
if(!e) e=window.event;
if(e.keyCode == 17)
isCtrl = false;
}
function OnClientNodeDropping(sender, args)
{
var sourceNode = args.get_sourceNode();
var destNode = args.get_destNode();
if(destNode)
{
sender.trackChanges();
if(!isCtrl)
{
sourceNode.get_attributes().setAttribute("isCtrl", "no");
}
else
{
sourceNode.get_attributes().setAttribute("isCtrl", "yes");
}
sender.commitChanges();
}
}
</script>
Then, in the server-side NodeDrop
event handler, you can do the following:
protected void RadTreeView1_NodeDrop(object sender, Telerik.Web.UI.RadTreeNodeDragDropEventArgs e)
{
RadTreeNode sourceNode = e.SourceDragNode;
RadTreeNode destNode = e.DestDragNode;
if (destNode != null)
{
if (sourceNode.Attributes["isCtrl"] == "no")
{
RadTreeNode newNode = sourceNode.Clone();
destNode.Nodes.Add(newNode);
}
else
{
sourceNode.Owner.Nodes.Remove(sourceNode);
destNode.Nodes.Add(sourceNode);
}
destNode.Expanded = true;
}
}