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

6 posts, 0 answers
  1. Ram
    Ram avatar
    3 posts
    Member since:
    Jul 2010

    Posted 24 Jul 2010 Link to this post

    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.


  2. Veronica
    Admin
    Veronica avatar
    1213 posts

    Posted 25 Jul 2010 Link to this post

    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
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Marbry
    Marbry avatar
    26 posts
    Member since:
    Aug 2012

    Posted 11 Jun 2012 Link to this post

    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();
    }
  5. Marbry
    Marbry avatar
    26 posts
    Member since:
    Aug 2012

    Posted 11 Jun 2012 Link to this post

    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());
  6. Dimitar Terziev
    Admin
    Dimitar Terziev avatar
    1266 posts

    Posted 15 Jun 2012 Link to this post

    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.
  7. Marbry
    Marbry avatar
    26 posts
    Member since:
    Aug 2012

    Posted 13 Jul 2012 Link to this post

    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];
    }
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017