This is a migrated thread and some comments may be shown as answers.

How to Achive Move Up,Move Down in RadTreeView Control?

5 Answers 338 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Ram
Top achievements
Rank 1
Ram asked on 24 Jul 2010, 10:12 AM
I having Treeview with several nodes and sub nodes
The user must have the option to sort the treeview items,using context menu items Like MoveUp,MoveDown
Is their any methods available for moving the node up and down in the RadTreeview using clientside functions
like movenodeup,movenodedown etc,
Please let me know as  soon as possible,
this is very very urgent task.
thanks in advance.


5 Answers, 1 is accepted

Sort by
0
Veronica
Telerik team
answered on 25 Jul 2010, 02:36 PM
Hi Ram,

There is no client-side function for moving nodes up or down by design.

However I made a sample project to solve your scenario.
After subscribing to the OnClientContextMenuItemClicking event you can check the value of the context menu item and call one of the methods insertAfter or insertBefore:

function contextMenuItemClicking(sender, args) {
            var menuItem = args.get_menuItem();
            var treeNode = args.get_node();
            menuItem.get_menu().hide();
  
            switch (menuItem.get_value()) {
                case "up":
                    var previousNode = treeNode.get_previousNode();
                    if (previousNode) {
                        insertBefore(previousNode, treeNode);
                    }
                    else {
                        alert("Node cannot be moved up!")
                    }
                    break;
                case "down":
                    var nextNode = treeNode.get_nextNode();
                    if (nextNode) {
                        insertAfter(nextNode, treeNode);
                    }
                    else {
                        alert("Node cannot be moved down!");
                    }
                    break;
            }
        }
  
        function insertBefore(previousNode, currentNode) {
            var previousNodeParent = previousNode.get_parent();
            var index = previousNodeParent.get_nodes().indexOf(previousNode);
            previousNodeParent.get_nodes().insert(index, currentNode);
        }
  
        function insertAfter(nextNode, currentNode) {
            var nextNodeParent = nextNode.get_parent();
            var index = nextNodeParent.get_nodes().indexOf(nextNode);
            nextNodeParent.get_nodes().insert(index, currentNode);
        }

Find the full code in the attached .zip file.

Greetings,
Veronica Milcheva
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Marbry
Top achievements
Rank 1
answered on 11 Jun 2012, 01:09 PM
That doesn't work with templated content though.  The node that gets inserted loses everything that was generated by the templates.

Certainly there's a way to swap two nodes out and retain that content without having to go back to the server?  It's all just HTML rendered within the containing tag at that point.

I tried the code below, but the visible tree doesn't change.

function MoveNodeUp(node)
{
    var tree = $find( "<%= tkTree.ClientID %>" );

    
tree.trackChanges();
    var parent = node.get_parent().get_nodes();
    var prevIndex = node.get_previousSibling().get_index();
    if (prevIndex == null)
        return;
    var currIndex = node.get_index();
      
    var tmpNode = parent._array[prevIndex];
    parent._array[prevIndex] = parent._array[currIndex];
    parent._array[currIndex] = tmpNode;
    tree.commitChanges();
    tree.repaint();
}
0
Marbry
Top achievements
Rank 1
answered on 11 Jun 2012, 02:30 PM
I've tried several other variations, this below works as far as preserving the templated content, but the graphics for the lines to the parent are not updated, and there appear to be some event handler issues.

var prevSib = node.get_previousSibling();
var tmpElem = prevSib.get_element();
tmpElem.swapNode(node.get_element());
0
Dimitar Terziev
Telerik team
answered on 15 Jun 2012, 12:01 PM
Hi Marbry,

Could you open a support ticket and provide a runnable sample reproducing the experienced problem so we could inspect it.

All the best,
Dimitar Terziev
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
0
Marbry
Top achievements
Rank 1
answered on 13 Jul 2012, 02:06 PM
I've seen where a number of other people were looking for the same thing, so here's the solution I ended up with.  Thanks to patient support from Telerik, we were able to get something working.

This will allow you to move nodes on the client side and preserve the content generated by the server templates, as well as basic formatting and keep the event handlers hooked up for embedded controls.  Note that it has to handle nodes that are templated slightly differently from those that aren't.

You may need to play around with what node to reference as the destination node and adding a temporary node perhaps as a destination if moving to a parent that doesn't have any children to start with.

Use this as a purely client side handler in conjunction with a web method call to make any update on the server and it is very responsive.

// Moves the source node up or down to the slot of the destination node on the client side
function MoveNode(sourceNode, destinationNode, moveUp)
{
    var html = "";
    var sourceIsTemplated = false;
    var tree = $find( "<%= tkTree.ClientID %>" );
    var sourceClass = "rtIn";
    var sourceTitle = "";
    tree.trackChanges();
    var styleRef = $telerik.$(sourceNode.get_element()).find(".rtIn");
    if (styleRef != null)
    {
        sourceTitle = styleRef[0].title;
        sourceClass = styleRef[0].className;
    }
    var nodeRef = $telerik.$(sourceNode.get_element()).find(".rtIn").first().find(".rtTemplate");
    if (nodeRef.length == 0)
    {
        sourceIsTemplated = false;
        html = $telerik.$(sourceNode.get_element()).find(".rtIn").html();
    }
    else
    {
        sourceIsTemplated = true;
        html = nodeRef.detach();
    }
    var childRef = null;
    var cStyleRef = null;
    var childNodes = sourceNode.get_allNodes();
    var childrenHtml = new Array(childNodes.length);
    var childIsTemplated = new Array(childNodes.length);
    var childTitle = new Array(childNodes.length);
    var childClass = new Array(childNodes.length);
    for (var i = 0, length = childNodes.length; i < length; i++)
    {
        cStyleRef = $telerik.$(childNodes[i].get_element()).find(".rtIn").first();
        childTitle[i] = cStyleRef[0].title;
        childClass[i] = cStyleRef[0].className;
        childRef = cStyleRef.find(".rtTemplate");
        if (childRef.length == 0)
        {
            childIsTemplated[i] = false;
            childrenHtml[i] = cStyleRef.html();
        }
        else
        {
            childIsTemplated[i] = true;
            childrenHtml[i] = childRef.detach();
        }
    }
    sourceNode.get_parent().get_nodes().remove(sourceNode);
    var newNode;
    if (moveUp)
        newNode = insertBefore(destinationNode, sourceNode);
    else
        newNode = insertAfter(destinationNode, sourceNode);
    var newChildren = newNode.get_allNodes();
    $telerik.$(sourceNode.get_element()).find(".rtIn").first().replaceWith("<div class='" + sourceClass + "' title='" + sourceTitle + "'></div>");
    var srcRef = $telerik.$(sourceNode.get_element()).find(".rtIn").first();
    if (sourceIsTemplated)
        srcRef.append(html);
    else
        srcRef.html(html);
    for (var i = 0; i < newChildren.length; i++)
    {
        $telerik.$(newChildren[i].get_element()).find(".rtIn").first().replaceWith("<div class='rtIn'></div>");
        if (childIsTemplated[i])
            $telerik.$(newChildren[i].get_element()).find(".rtIn").first().append(childrenHtml[i]);
        else
            $telerik.$(newChildren[i].get_element()).find(".rtIn").first().html(childrenHtml[i]);
        var newRef = $telerik.$(newChildren[i].get_element()).find(".rtIn").first();
        newRef[0].title = childTitle[i];
        newRef[0].className = childClass[i];
    }
    tree.commitChanges();
}
// Inserts a node in the specified slot, but will lose templated content
function insertBefore(destinationNode, sourceNode)
{
    var destinationParent = destinationNode.get_parent();
    var index = destinationParent.get_nodes().indexOf(destinationNode);
    destinationParent.get_nodes().insert(index, sourceNode);
    return destinationParent.get_nodes()._array[index];
}
          
function insertAfter(destinationNode, sourceNode)
{
    var destinationParent = destinationNode.get_parent();
    var index = destinationParent.get_nodes().indexOf(destinationNode);
    destinationParent.get_nodes().insert(index + 1, sourceNode);
    return destinationParent.get_nodes()._array[index + 1];
}
Tags
TreeView
Asked by
Ram
Top achievements
Rank 1
Answers by
Veronica
Telerik team
Marbry
Top achievements
Rank 1
Dimitar Terziev
Telerik team
Share this question
or