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

Server Side Re-Order

1 Answer 74 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Philip Senechal
Top achievements
Rank 1
Philip Senechal asked on 04 Oct 2010, 10:26 PM
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 =)

1 Answer, 1 is accepted

Sort by
0
Philip Senechal
Top achievements
Rank 1
answered on 05 Oct 2010, 01:21 AM
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!
Tags
TreeView
Asked by
Philip Senechal
Top achievements
Rank 1
Answers by
Philip Senechal
Top achievements
Rank 1
Share this question
or