Welcome Guest Search | Active Topics | Sign In | Register

Treeview doesn't maintain position on postback Options
aaronh
Posted: Thursday, September 25, 2008 5:42:19 PM
Rank: Newbie
Groups: Member

Joined: 9/25/2008
Posts: 8
Hi there,

I was hoping that the TreeView was capable of maintaining it's position after performing a Callback postback. Am I doing something wrong, or is the control incapable of this functionality within this scenario?

Here's what I've done:

1.) Placed a Treeview in a Callback panel.
2.) The nodes were set to populate on demand. The nodes maintain position when this is done.
3.) Each node is set to execute client side script, via the ClientSideOnItemClick property.
4.) The client side script invokes the Callback panel postback (via eo_Callback), which is handled by the Callback's Execute handler.
5.) The code executes within the handler properly, BUT, after this, the treeview nodes reposition themselves, shifting around and losing their original placement within the treeview.

What seems strange is that when the nodes populate themselves on demand, they maintain their position perfectly. But something about the eo_Callback and handling the Execute event causes them to shift and lose their original position.

Does this make sense, and Is there a way around this?

Thanks much!
eo_support
Posted: Thursday, September 25, 2008 8:24:40 PM
Rank: Administration
Groups: Administration

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

Populate on demand and Callback both uses AJAX but the scope they act upon is different. Populate on demand only changes the child nodes of a given node and it does not touch anything else. Callback on the other hand updates the whole TreeView --- the whole client side TreeView object is reloaded.

The TreeView does maintain certain state information when it is does a normal postback. The state information includes whether a node is expanded and selected, but does not include scroll position. However if you recreate the whole TreeView (for example, repopulate from the database), then all state information is discarded.

If you are not recreating the TreeView in CallbackPanel_Execute, try to set the TreeView's RaisesServerEvent to true and set the TreeView as a callback trigger. This way you no longer need to call eo_Callback to trigger the AJAX call. Clicking any TreeNode automatically generates a postback (raising server event). Since the TreeView is set as a trigger, it is intercepted by the CallbackPanel and converted to an AJAX call. The good thing about this is you would write your code as if a real post back occurs. For example, you would be handing server side TreeView_ItemClick event instead of CallbackPanel_Execute event. This gives you more context information, for example, which node was clicked.

You may wish only some nodes to raises server event. You can do that either by explicitly setting some nodes' RaisesServerEvent to NullableBool.False, or set the TreeView's ClientSideOnItemClick to a JavaScript function and return false from that function for certain nodes. Returning false from that JavaScript function cancels the postback.

Hope this helps.

Thanks
aaronh
Posted: Friday, September 26, 2008 6:41:36 AM
Rank: Newbie
Groups: Member

Joined: 9/25/2008
Posts: 8
Hi there, I've tried what you suggested and still no luck. I've copied everything in the X:\Essential Objects\Net20\Samples\VB\Demos\TreeView\Features\Populate On Demand\.ascx,.vb files and have pasted their contents into one .aspx page (default2.aspx) within the EOWebDemo_VS9 solution. Here is the code. You can simply copy and paste the contents into a page within your EOWebDemo_VS9 solution and run, and you should notice the undesirable behavior that I speak of. Any thoughts? Thanks again!

<%@ Page Language="VB" %>
<%@ Import Namespace="System.IO" %>
<%@ Register assembly="EO.Web" namespace="EO.Web" tagprefix="eo" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

Protected Sub TreeView1_ItemClick(ByVal sender As Object, ByVal e As EO.Web.NavigationItemEventArgs)
System.Diagnostics.Debug.WriteLine(e.TreeNode.Value)
End Sub

Protected Sub TreeView1_ItemPopulate(ByVal sender As Object, ByVal e As EO.Web.NavigationItemEventArgs)
'Get the parent node
Dim parentNode As EO.Web.TreeNode = CType(e.NavigationItem, EO.Web.TreeNode)
If parentNode.SubGroup.Nodes.Count > 0 Then Return
'Get the root path
Dim parentDir As String = Server.MapPath("~/Demos")
'Combine the root path with the node's Value property,
'in which we stores the relative path to the root
If parentNode.Value Is Nothing Then
parentNode.Value = String.Empty
End If
parentDir = Path.Combine(parentDir, parentNode.Value)
'Find all the directories
Dim dirs As String() = Directory.GetDirectories(parentDir)
Dim dir As String
For Each dir In dirs
Dim dirName As String = Path.GetFileName(dir)
Dim dirNode As New EO.Web.TreeNode(dirName)
'Directories can have child items. So at here we
'store the path associated with this directory to
'its Value property and set PopulateOnDemand to true
dirNode.Value = Path.Combine(parentNode.Value, dir)
dirNode.PopulateOnDemand = True
parentNode.SubGroup.Nodes.Add(dirNode)
Next dir
'Find all files
Dim files As String() = Directory.GetFiles(parentDir)
Dim file As String
For Each file In files
Dim fileName As String = Path.GetFileName(file)
Dim fileNode As New EO.Web.TreeNode(fileName)
parentNode.SubGroup.Nodes.Add(fileNode)
Next file
End Sub
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<eo:CallbackPanel ID="CallbackPanel1" runat="server" Height="150px" Triggers="{ControlID:TreeView1;Parameter:}" Width="200px">
<eo:TreeView runat="server" id="TreeView1" OnItemClick="TreeView1_ItemClick" OnItemPopulate="TreeView1_ItemPopulate" ControlSkinID="None" Width="156px" Height="200px" RaisesServerEvent="true">
<LookNodes>
<eo:TreeNode ItemID="_Default">
</eo:TreeNode>
</LookNodes>
<TopGroup>
<Nodes>
<eo:TreeNode PopulateOnDemand="True" Text="Demo Files"></eo:TreeNode>
</Nodes>
</TopGroup>
<LookNodes>
<eo:TreeNode ImageUrl="00030203" DisabledStyle-CssText="background-color:transparent;border-bottom-style:none;border-left-style:none;border-right-style:none;border-top-style:none;color:Gray;padding-bottom:1px;padding-left:1px;padding-right:1px;padding-top:1px;"
CollapsedImageUrl="00030301" ItemID="_Default" NormalStyle-CssText="PADDING-RIGHT: 1px; PADDING-LEFT: 1px; PADDING-BOTTOM: 1px; COLOR: black; BORDER-TOP-STYLE: none; PADDING-TOP: 1px; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: transparent; BORDER-BOTTOM-STYLE: none"
ExpandedImageUrl="00030302" SelectedStyle-CssText="background-color:#316ac5;border-bottom-color:#999999;border-bottom-style:solid;border-bottom-width:1px;border-left-color:#999999;border-left-style:solid;border-left-width:1px;border-right-color:#999999;border-right-style:solid;border-right-width:1px;border-top-color:#999999;border-top-style:solid;border-top-width:1px;color:White;padding-bottom:0px;padding-left:0px;padding-right:0px;padding-top:0px;"></eo:TreeNode>
</LookNodes>
</eo:TreeView>
</eo:CallbackPanel>
</form>
</body>
</html>
aaronh
Posted: Friday, September 26, 2008 7:07:07 AM
Rank: Newbie
Groups: Member

Joined: 9/25/2008
Posts: 8
Ok, I've just noticed that TreeView1_ItemClick is not firing? Am I missing something?

Thanks!
eo_support
Posted: Friday, September 26, 2008 7:10:19 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,193
I am a bit confused about what you are trying to do. As we have mentioned in our previous post, when a postback (or an AJAX callback that updates the whole TreeView) occurs, the whole client side TreeView is reloaded. In this case it keeps selected node, expand state but not scrolling positions. This is also what we saw with your sample code. Please let us know if you meant something else.

Neverthelss, automatically persisting scrolling position on postback makes perfect sense though. So we will look into it and see if we can put that in. It should not be difficult so I am hoping we can provide an update build to you very soon.

The item click event does fire during our test.
aaronh
Posted: Friday, September 26, 2008 7:27:22 AM
Rank: Newbie
Groups: Member

Joined: 9/25/2008
Posts: 8
Thanks for your patience through all of this. I don't think you're confused, I think you understand. Here's what I'm trying to do:

I want all of the nodes to populate dynamically, when being expanded. That part is working flawlessly, it seems to make the ajax call, bring back the data, and populate itself client-side. The position remains how it should, and the item remains highlighted.

After selecting (not expanding) an item, I want it to make another ajax call and raise a different server-side event (in which I can handle) to do something else. I don't want the TreeView itself to postback, I would like it to remain intact and send a notification to the server. I have set everything up according to your suggestion, but the TreeView still forgets it's location (it's as if the TreeView is still posting back to the server and forgetting it's position when it comes back). This is not what I want. I want the same behavior that I get when I expand a node. Essentially, I think it should behave as the windows explorer behaves (the nodes never forget their position)

It would make sense to me to catch an item click event in javascript, and send an ajax message to the server, however, that doesn't seem to be what's going on. So I'm thinking that the EO TreeView will behave as I think it should, but perhaps I'm not hooking it up correctly?

What do you think?
eo_support
Posted: Friday, September 26, 2008 8:10:03 AM
Rank: Administration
Groups: Administration

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

In that case you shouldn't be putting the TreeView inside the CallbackPanel at all. The CallbackPanel is not only an AJAX engine, it also defines the boundary to be AJAX updated. My understanding is when you click a tree node, your intention is not to update the TreeView itself. Your intention is to update something else. In that case put the CallbackPanel around that "something else". As a test, you can try to do the following based on your previous test page:

1. Move the TreeView outside of the CallbackPanel;
2. Place a Label inside the CallbackPanel. Now the Label should be the only child control of the CallbackPanel since the TreeView has been moved out;
3. Inside your ItemClick event handler, set the Label's Text to some value, such as DateTime.Now.ToString()

Run the page and when you click a TreeNode, you should see:

1. Your server side ItemClick event is fired;
2. The Label is updated;
3. The TreeView however stays intact;

Please let us know if that works out for you.

Thanks!

aaronh
Posted: Friday, September 26, 2008 8:17:18 AM
Rank: Newbie
Groups: Member

Joined: 9/25/2008
Posts: 8
That worked! Thanks so much. I'm very impressed with the quality of service that you've provided me, I really appreciate it.

-Aaron


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.