Welcome Guest Search | Active Topics | Sign In | Register

Managing Treeview Options
hal4uk
Posted: Thursday, June 18, 2009 11:50:07 AM
Rank: Newbie
Groups: Member

Joined: 6/18/2009
Posts: 4
I am trying to learn how to use the treeview, but I primarily develop desktop applications (VB/C#), and my javascript skills are poor. I can usually tinker/modify, but I need good examples to start with.

I think most of the things I want to do would require client-side js..

That said, I have allowed drag drop + reorder, and that seems fast; I like the way it works as expected. But I need to know how to do several things... (I know it's a lot of questions, but hopefully it's just stuff that easy for you, but a mystery to me)..

1) How do I cancel the NavigateURL on a drop?

2) how to implement ADD, DELETE, and EDIT of nodes? Each node, for my purposes, is either a 'folder' node or a 'link' node... (I'm basically wanting to store bookmarks (URLs) ). So, a folder node, would basically just have its Text set, but a 'link' node would have Text + NavigateURL set. I mention this, because with an ADD or EDIT, the user would need to supply 2 strings somehow, whereas with a folder it would be 1 string. Also, ideally, the user would use a context menu to perform these actions.

3) After a user has modified the Treeview, I need to provide them a 'save' button, and preferably just do a partial postback and save the updated treeview info to a DB. I'm unclear on the mechanics to accomplish this.

Thanks for any help...
eo_support
Posted: Thursday, June 18, 2009 12:50:37 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

Thanks for posting in the forum. Some of your questions does require JavaScript, but we will give you sample code below so that you can copy and paste and see how it works. As to your questions:

#1. Cancel NavigateURL on drop

You can handle the TreeView's ClientSideOnDropDrop and ClientSideOnItemClick event. Inside your ClientSideOnDropDrop handler, you would record the current time and save it as "last drop time", and inside your ClientSideOnItemClick you would compare the current time with your "last drop time", if these two time values are close enough, then it means the item click event is triggered by a drop. In this case you would cancel this event. The following snippet provides all the code needed to implement this logic:

Code: HTML/ASPX
<eo:TreeView  runat="server" ....
    ClientSideOnDragDrop="dragdrop_handler" 
    ClientSideOnItemClick="itemclick_handler" ....>
   .....
</eo:TreeView>


//Global variable to record last drop time
Code: JavaScript
var g_LastDropTime;
            
function dragdrop_handler()
{
    //This function is called when you drop a node
    //We save the current time into g_LastDropTime
    g_LastDropTime = new Date();
}

function itemclick_handler()
{
    //This function is called when item click is about
    //to be fired (before NavigateUrl is carried out)    
    var time = new Date();

    //We compare the current time with g_LastDropTime
    //and if the two are close enough (less than 100ms)
    //then the item click is triggered by a drop. In this
    //case we simply return false to cancel the event
    if (g_LastDropTime &&
        (time.getTime() - g_LastDropTime.getTime() < 100))
    return false;                    
}


#2.1 Add & delete

Edit can be done directly on client side, while add and delete must be done on the server side. Doing it on the client side is faster since it does not cost a round trip to the server. It also offers better user experience because it does not do a full page reload. The second problem can be avoided by performing a partial page update (see #3.2 below).

To add a TreeNode, you simply creates a new TreeNode object and add it to the TreeView (very much similar to what you do with a desktop application). The following code adds a new TreeNode to the root:

Code: C#
EO.Web.TreeNode newNode = new EO.Web.TreeNode("new node");
TreeView1.Nodes.Add(newNode);


The following code adds a new child TreeNode to the second top level nodes:

Code: C#
TreeView1.Nodes[1].ChildNodes.Add(newNode);


The following code adds a new child TreeNode to the selected node:

Code: C#
TreeView1.SelectedNode.ChildNodes.Add(newNode);


You may want to take a look of the related class references in the documentation for TreeView, TreeNode, TreeNodeCollection etc.

Delete a node is similar. The following code delete the first top level node:

Code: C#
TreeView1.Nodes.RemoveAt(0);


All the code can be triggered by a regular server button control.

2.2 Edit node

Edit node is different. You must do it on the client side. The following code put the current selected node into edit mode:

Code: HTML/ASPX
<a href="javascript:EditSelectedNode()">Edit Node</a>


Code: JavaScript
function EditSelectedNode()
{
    //Get the selected node
    var treeView = eo_GetObject("TreeView1");
    var selectedNode = treeView.getSelectedNode();

    //Put the selected node into edit mode
    if (selectedNode)
        selectedNode.beginEdit();
}


#3.1: Save

There are two types of changes that you will need to consider:

1. Changes that are initiated from your server side code, such as add or delete. This is very simple. In this case, you update your DB when you database when you update the TreeView. For example, when user click "Add" button, the page goes back to the server side and call your button event handler, you add a new node to the TreeView and then update your database accordingly;

2. Changes that are initiated from the client side, such as drag drop and node editing. This is more complicated because you will not be able to update your database right away when the event occurs. For example, user can drag node A into B, then drag it out of B and into C and all are done on the client side. All such actions are logged on the client side and when the page is eventually posted back to the server (for example, by your Save button), the TreeView will calls corresponding event handler so that you can update database accordingly. For example, in the previous case where A is moved into B and then into C, ItemMoved event will be called twice. You can handle that event and update your database based on the event arguments. (ItemRenamed event for node editing).

Here is a working example that demonstrates how to handle ItemMoved event:

http://demo.essentialobjects.com/Default.aspx?path=TreeView\_i2\_i0

You can take a look of the sample source code to see how it works. You have the full source code on your local drive.

Regardless what type of update, the basic rule is actually quite simple: you handle the corresponding server event and update your database inside that event handler. For example, when user click a Button to add a new node, you handle that Button's Click event and update your DB there (also update the TreeView); When user moved a node, you handle the TreeView's ItemMoved event and update your DB there (you do not need to update the TreeView here since it has already been updated);

#3.2 Partial page update

Partial page update is very simple. We would suggest you try to get all the previous steps working first and then implement partial page update. To implement partial page update with our CallbackPanel, you simply put the TreeView inside a CallbackPanel and then set the CallbackPanel's Triggers property to include the "trigger" controls, for example, your "Add", "Delete" or "Save" button and you are all set.

Hope this can get you going. Please feel free to let us know if you have any more questions.

Thanks!
hal4uk
Posted: Thursday, June 18, 2009 1:20:49 PM
Rank: Newbie
Groups: Member

Joined: 6/18/2009
Posts: 4
Thanks for the quick reply! Will try suggestions...
hal4uk
Posted: Thursday, June 18, 2009 2:31:14 PM
Rank: Newbie
Groups: Member

Joined: 6/18/2009
Posts: 4
The code to cancel the navigate when dropping a node worked perfect. Thx...

I tried deleting a node using an eo toolbar button, but it failed. I just tried to do it straightforward (full postback), and stepped through the code - it looked like it should have worked, but the node was still there. So just to see if I could affect anything, I coded the 'Save' button to change the item's name - and that worked.

Why didn't my delete work?

Code: Visual Basic.NET
Protected Sub ToolBar1_ItemClick(ByVal sender As Object, ByVal e As EO.Web.ToolBarEventArgs) Handles ToolBar1.ItemClick

        With TreeView2
            Select Case e.Item.ToolTip
                Case "Delete Selected Item"
                    If .SelectedNode IsNot Nothing Then
                        .Nodes.Remove(.SelectedNode)
                    End If
                Case "Save"
                    If .SelectedNode IsNot Nothing Then
                        .SelectedNode.Text = "Save Clicked!"
                    End If
                Case "New Bookmark"

                Case "New Folder"

            End Select
        End With

    End Sub
Angel Angel
eo_support
Posted: Thursday, June 18, 2009 2:48:41 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

Check whether SelectedNode is a top level node. Remove function is called on the parent node's ChildNodes collection or the TreeView's Nodes collection, which contains all top level nodes. Because TreeView1.Nodes only contains top level nodes, "TreeView1.Nodes.Remove(node)" will only remove a node if the node is a top level node.

The more generic code to remove any node is:

Code: C#
node.ParentNode.ChildNodes.Remove(node);


Thanks!
hal4uk
Posted: Thursday, June 18, 2009 3:03:54 PM
Rank: Newbie
Groups: Member

Joined: 6/18/2009
Posts: 4
Duh! I need to swap my "list hat" for my "treeview hat" - thx!

Now I feel pretty confident that I can do the main things I want to, but let me ask one other thing regarding saving the treeview...

I know I could recurse the nodes, snagging all the current info, and save in a table with something like NodeID, ParentNodeID, etc., and reconstruct as needed...

I'm just wondering - is there a faster way? some way to serialize it or something?
Am I on the right track, or is there a "best practice" for this?
eo_support
Posted: Thursday, June 18, 2009 3:36:35 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,194
Hi,

Actually you almost never need to worry about saving the whole TreeView. When you update the TreeView, it’s almost never an action of "replacing TreeView A with TreeView B". In most cases, you would do "modify node A", "move node B", "add node C", etc. So what you really need to implement are those actions instead of capturing the whole TreeView. In another word, when it comes to updating/saving the TreeView, you almost always work on TreeNode (one at a time) instead of the TreeView.

You do not need to worry about the reconstructing part. The TreeView can do that automatically for you. For more information about this, you want to check out “Data Binding” documentations:

http://doc.essentialobjects.com/library/1/menucommon/databinding/databinding_overview.aspx

Hope this helps.

Thanks!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.