Rank: Newbie Groups: Member
Joined: 1/28/2009 Posts: 1
|
Hello,
I'm interrested in your TreeView product, but I'd like to know if the following scenario is possible with built-in functionality or if examples are available:
I have a hierachical table using self-referencing (ParentID). I'm also using a SortOrder field for the ordering of the elements. I'd like to be able to re-order items using drag&drop, and also drag&drop items or trees to different parents.
Question is how to update the Database ParentID & SortOrder.
Thanks,
Michael
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi, This involves several steps: 1. Store ID and SortOrder in each TreeNodeThe first step is to store the ID and SortOrder in each TreeNode. This way as soon as you have a TreeNode object, you will know the corresponding record ID in your DB. The TreeNode object provides an extra "Value" property for you store any values. In your case, if you would like to store two values, you can devise some sort of scheme to combine two values as one, for example, using a single string value "1,5" to represent "ID is 1, SortOrder is 5". You can either use a DataBinding object to map any data field value into the Value property, or set it with code inside your ItemDataBound handler. This page contains more information about how to map a DB field to a property: http://doc.essentialobjects.com/ViewDoc.aspx?book=1&t=MenuCommon%2fDataBinding%2fpopulate_table.htmlIf you use this approach, you will need to combine the two values within your SQL statement to produce a single calculated field. You can then use the following code to extract ID or SortOrder from a TreeNode at runtime:
Code: C#
private int GetNodeID(EO.Web.TreeNode node)
{
//This code assume you use integer record ID
return int.Parse(node.Value.Split(',')[0]);
}
private float GetSortOrder(EO.Web.TreeNode node)
{
//This code assumes you use a float value for sort order
return float.Parse(node.Value.Split(',')[1]);
}
2. Update parent IDThe second step is to handle ItemMoved event. The event handler passes you the Node object as well as it's old parent Node object. It is very easy to check whether a node's parent node has been changed by comparing the old parent Node's ID with the new one:
Code: C#
protected void TreeView1_NodeMoved(
object sender, EO.Web.TreeNodeMovedEventArgs e)
{
int newParentID= GetNodeID(e.Node.ParentNode);
if (newParentID != GetNodeID(e.OldParent))
{
//Need to update this node's parent ID
UpdateParentID(GetNodeID(e.Node), newParentID);
}
//Continue to update sort order
UpdateSortOrder(e.Node);
}
private void UpdateParentID(int id, int parentId)
{
//Update your database.....
.....
}
3. Update sort orderSort order is more complicated than parent ID because depending on how you maintain sort order, you may need to update multiple records. For example, if you use integer as sort order and you have five nodes with the following sort order:
Code:
Node: A, B, C, D, E Order: 1, 2, 3, 4, 5
Now if you move B to be between D and E, you will need to change at least two node's SortOrder. The following shows node's B and E's sort order has been changed:
Code:
Node: A, C, D, B, E Order: 1, 3, 4, 5, 6
Or you can change everybody's sort order after A:
Code:
Node: A, C, D, B, E Order: 1, 2, 3, 4, 5
The following sample code uses float sort order, which allows you to only modify one node. For example, the new sort order with float values can be:
Code:
Node: A, C, D, B, E Order: 1, 3, 4, 4.5, 5
Note B's new sort order is 4.5. This way neither D or E's sort order needs to be changed. You would need to calculate the new sort order based on the previous node and the next node's sort order. The following code demonstrates how to do this:
Code: C#
private void UpdateSortOrder(EO.Web.TreeNode node)
{
int nodeId = GetNodeID(node);
EO.Web.TreeNode parentNode = node.ParentNode;
//Find out the previous node's sort order
float prevNodeSortOrder = 0;
int nodeIndex = node.Index;
if (nodeIndex == 0) //We are the first node
prevNodeSortOrder = 0;
else
{
//There are nodes before us, so get the previous
//node's sort order
EO.Web.TreeNode prevNode = parentNode.ChildNodes[nodeIndex - 1];
prevNodeSortOrder = GetSortOrder(prevNode);
}
//Find out next node's sort order
float nextNodeSortOrder = prevNodeSortOrder + 2;
if (nodeIndex < parentNode.ChildNodes.Count - 1)
{
//Only get the next node's sort order if we are not
//the last node. In the case we are the last node,
//our new sort order is simply the previous node's
//sort order + 1
EO.Web.TreeNode nextNode = parentNode.ChildNodes[nodeIndex + 1];
nextNodeSortOrder = GetSortOrder(nextNode);
}
//Calculate the new sort order
float newSortOrder = (prevNodeSortOrder + nextNodeSortOrder) / 2;
//Update your database....
UpdateSortOrder(nodeId, newSortOrder);
}
private void UpdateSortOrder(int nodeId, float newSortOrder)
{
//Update your DB
}
Obviously you may want to change this scheme depending on how you actually store the sort order in your DB. But the basic idea should be the same. Hope this helps. Thanks
|
Rank: Newbie Groups: Member
Joined: 1/29/2009 Posts: 4
|
This functionality is exactly what I need but when I working the issue with the trial version I downloaded my tvEMP_ORG_NodeMoved is not firiring. Am I missing something?
Code: <eo:TreeView ID="tvEMP_ORG" runat="server" Height="250px" Width="342px" AutoSelect="ItemClick" AllowDragDrop="True" OnItemMoved="tvEMP_ORG_NodeMoved" > <LookNodes> <eo:TreeNode ItemID="_Default"> </eo:TreeNode> </LookNodes> </eo:TreeView> CS: protected void tvEMP_ORG_NodeMoved(object sender, EO.Web.TreeNodeMovedEventArgs e) { int newParentID = Convert.ToInt32(e.Node.ParentNode); if (newParentID != Convert.ToInt32(e.OldParent)) { //Need to update this node's parent ID UpdateParentID(Convert.ToInt32(e.Node), Convert.ToInt32(newParentID)); }
//Continue to update sort order //UpdateSortOrder(e.Node); }
It is populating correctly (I'm using a loop and .Add(NewNode) for now) But when a drag and drop occurs I can't get this or anyother event to fire. Please advise.
Thanks Matt
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
NodeMoved is not fired right after you moved the node. It is fired after the page is posted back. So it is possible for user to do multiple drag and drops, then post back the page, then all of them to be fired one after another.
We are posting a new build with a full working sample for this scenario. Hopefully it will be online this afternoon, you can download that sample and take a look of the source code by then.
Thanks!
|