Server Side Re-Order

2 posts, 0 answers
  1. Philip Senechal
    Philip Senechal avatar
    152 posts
    Member since:
    Apr 2008

    Posted 04 Oct 2010 Link to this post

    I have a Tree View that controls a Left Navigation which is bound to a database. My database table has the following columns...

    NodeID
    NodeTxt
    NodeURL
    NodeVal
    NodeParentID
    NodeOrder

    I added the NodeOrder column because I'm trying to figure how to allow drag/drop reordering of nodes and save the position of the nodes server-side in the database. I've looked at the example in the demos and it shows how to achieve this client side...event though I don't believe the positions are actually stored to a database or anything.

    Do you have any examples of how this can be implemented server side so that the ordering of the nodes can be set and retrieved from a database when dragging and dropping child nodes?

    Thanks =)
  2. Philip Senechal
    Philip Senechal avatar
    152 posts
    Member since:
    Apr 2008

    Posted 04 Oct 2010 Link to this post

    AH! I think I may have gotten it. I looked more closely at the demo and there is coding in there for determining the order, I just had to figure how to use it to write to the database. This is what I came up with...

       protected void RadTreeView1_NodeDrop(object sender, RadTreeNodeDragDropEventArgs e)
       {
           RadTreeNode sourceNode = e.SourceDragNode;
           RadTreeNode destNode = e.DestDragNode;
           RadTreeViewDropPosition dropPosition = e.DropPosition;
     
           if (sourceNode.TreeView.SelectedNodes.Count <= 1)
           {
               PerformDragAndDrop(dropPosition, sourceNode, destNode);
           }
           else if (sourceNode.TreeView.SelectedNodes.Count > 1)
           {
               foreach (RadTreeNode ddnode in sourceNode.TreeView.SelectedNodes)
               {
                   PerformDragAndDrop(dropPosition, ddnode, destNode);
               }
           }
     
           destNode.Expanded = true;
           sourceNode.TreeView.UnselectAllNodes();
       }
     
       private static void PerformDragAndDrop(RadTreeViewDropPosition dropPosition, RadTreeNode sourceNode,
    RadTreeNode destNode)
       {
           EISDataContext db = new EISDataContext();
           tLeftNav snode = db.tLeftNavs.Single(p => p.NavID == int.Parse(sourceNode.Value));
           tLeftNav dnode = db.tLeftNavs.Single(p => p.NavID == int.Parse(destNode.Value));
     
           // Get the max order number from the parent node and add 1
           int maxOrder = (from nodes in db.tLeftNavs
                           orderby nodes.NavOrder descending
                           where nodes.NavParentID == dnode.NavID && nodes.NavID != int.Parse(sourceNode.Value)
                           select nodes.NavOrder).FirstOrDefault();
           maxOrder += 1;
     
           if (sourceNode.Equals(destNode) || sourceNode.IsAncestorOf(destNode))
           {
               return;
           }
           sourceNode.Owner.Nodes.Remove(sourceNode);
     
           switch (dropPosition)
           {
               case RadTreeViewDropPosition.Over:
                   // child
                   if (!sourceNode.IsAncestorOf(destNode))
                   {
                       destNode.Nodes.Add(sourceNode);
                       snode.NavParentID = int.Parse(destNode.Value);
                       snode.NavOrder = maxOrder;
                   }
                   break;
     
               case RadTreeViewDropPosition.Above:
                   // sibling - above                   
                   destNode.InsertBefore(sourceNode);
                   // Change the ParentID of the source node if moving to a new level in the tree
                   if (dnode.NavParentID != snode.NavParentID)
                   {
                       snode.NavParentID = dnode.NavParentID;
                   }
                   // Make the order number of the source node equal to the order number of the node we're dropping above
                   snode.NavOrder = dnode.NavOrder;
                    
                   // Then get all the sibling nodes of the destination node so we can adjust their order
                   // Root Level
                   if (dnode.NavParentID == null)
                   {
                       var siblingNodes = from nodes in db.tLeftNavs
                                          orderby nodes.NavOrder
                                          where nodes.NavParentID == null && nodes.NavID != int.Parse(sourceNode.Value)
                                          select nodes;
                       // Then increase the order number of all the nodes below it by 1
                       foreach (tLeftNav siblingNode in siblingNodes)
                       {
                           if (siblingNode.NavOrder >= dnode.NavOrder)
                           {
                               siblingNode.NavOrder += 1;
                           }
                       }
                   }
                   // Then get all the sibling nodes of the destination node so we can adjust their order
                   // Child Level
                   else
                   {
                       var siblingNodes = from nodes in db.tLeftNavs
                                          orderby nodes.NavOrder
                                          where nodes.NavParentID == dnode.NavParentID && nodes.NavID != int.Parse(sourceNode.Value)
                                          select nodes;
                       // Then increase the order number of all the nodes below it by 1
                       foreach (tLeftNav siblingNode in siblingNodes)
                       {
                           if (siblingNode.NavOrder >= dnode.NavOrder)
                           {
                               siblingNode.NavOrder += 1;
                           }
                       }
                   }
                   break;
     
               case RadTreeViewDropPosition.Below:
                   // sibling - below
                   destNode.InsertAfter(sourceNode);
                   // Change the ParentID of the source node if moving to a new level in the tree
                   if (dnode.NavParentID != snode.NavParentID)
                   {
                       snode.NavParentID = dnode.NavParentID;
                   }
                   // Make the order number of the source node equal to the order number of the node we're dropping above
                   snode.NavOrder = dnode.NavOrder;
     
                   // Then get all the sibling nodes of the destination node so we can adjust their order
                   // Root Level
                   if (dnode.NavParentID == null)
                   {
                       var siblingNodes = from nodes in db.tLeftNavs
                                          orderby nodes.NavOrder
                                          where nodes.NavParentID == null && nodes.NavID != int.Parse(sourceNode.Value)
                                          select nodes;
                       // Then increase the order number of all the nodes below it by 1
                       foreach (tLeftNav siblingNode in siblingNodes)
                       {
                           if (siblingNode.NavOrder <= dnode.NavOrder)
                           {
                               siblingNode.NavOrder -= 1;
                           }
                       }
                   }
                   // Then get all the sibling nodes of the destination node so we can adjust their order
                   // Child Level
                   else
                   {
                       var siblingNodes = from nodes in db.tLeftNavs
                                          orderby nodes.NavOrder
                                          where nodes.NavParentID == dnode.NavParentID && nodes.NavID != int.Parse(sourceNode.Value)
                                          select nodes;
                       // Then increase the order number of all the nodes below it by 1
                       foreach (tLeftNav siblingNode in siblingNodes)
                       {
                           if (siblingNode.NavOrder <= dnode.NavOrder)
                           {
                               siblingNode.NavOrder -= 1;
                           }
                       }
                   }
                   break;
           }
     
           db.SubmitChanges();
       }


    It may not be pretty, but it does work. The only thing that kind of bugs me, but it's not a big deal, is that the Order can get somewhat our of order if you drag things around enough...meaning that I could end up with 3 nodes under the same level with values in the Order column of 0, 4, 6. Everything still stays in the right order, they're just not sequential.

    If you have any suggestions on any way to improve my code, I'd appreciate the input. Thanks!
Back to Top