Link to home
Start Free TrialLog in
Avatar of Murali
MuraliFlag for India

asked on

How to goto a particular vertical position of scroll in a dynamic canvas

Hi

I have a canvas which displays a dynamic tree. the tree changes on runtime. everytime the tree changes the page gets refreshed  and the scroll button of the canvas moves to the top most position. As the tree is big, users find it difficult everytime to scroll down or to their desired position after every refresh. Users who use the product want the scroll position of a canvas exactly at the same place where it was before refreshing. i tried using vertical scroll position, but it doesnt seem to be working. I use Action script 3. Any suggestions
ASKER CERTIFIED SOLUTION
Avatar of conagraman
conagraman
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Murali

ASKER

Hi

I took the verticalScrollBarPosition and set it after refresh. It is not working. I tried doing tree.verticalScrollPosition =  tree.maxVerticalScrollPosition; it is still not working.

Is there any way to do it by capturing the current session.

Let me know if there is any other way to do it.
SOLUTION
Avatar of petiex
petiex
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Murali1984:
As you can see in my post I mentioned you must set old value after collection event:

"and after collection event dispatching set verticalScrollBarPosition value to last value"

You can set in you custom component by overriding validateDisplayList function like this

override public function validateDisplayList():void{
     this.verticalScrollPosition == this.maxVerticalScrollPosition;
    super.validateDisplayList();
 }

or attach an event listener

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx">
	<fx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.events.CollectionEvent;
			import mx.events.FlexEvent;
			
			[Bindable]
			public var ac:ArrayCollection = new ArrayCollection();

			public function clickAddChildren():void {
				var newChild:Object = new Object();
				newChild.label = "New Child " + ac.length;
				newChild.children = new ArrayCollection();
				tree.dataDescriptor.addChildAt(tree.selectedItem, newChild, ac.length, ac);
			}

			protected function creationCompleteHandler(event:FlexEvent):void{
				tree.dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE, function(event:Event):void{
					tree.verticalScrollPosition = tree.maxVerticalScrollPosition;
				});
			}
			
		]]>
	</fx:Script>
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<mx:Tree width="200" id="tree" dataProvider="{ac}" creationComplete="creationCompleteHandler(event)"/>
	<mx:Button label="Add Child" click="clickAddChildren()"/>

</s:Application>

Open in new window

can you post your fla file or code you are using?
I just realized you said you refresh the page every time the data is updated. Is this true? Are you actually reloading the application every time you get new data? How exactly are you loading the data?
Avatar of Murali

ASKER

am sorry i wont be able to paste the code. Here is what happens....

my tree is inside canvas. the data provider to the tree is an xml. There are alot  of nodes. each leaf of a node is an executable command. when a command (i.e the leaf of the tree) is executed the status is sent and stored in the xml. Hence the entrie tree is refreshed and the updated value if the xml is obtained as the dataprovider. the nodes in my tree are fixed. it is not added dynamically. the data in the data provider (xml) is refreshed every time. this refreshes my canvas.  during this refresh i want my scroll bar to be fixed and not move on to the top..
Ok, in this case you need to listen tree CoolectrionEvent type, BUT...
If the old max verticalscrollbar is highest then new max vertical scrollbar the tree will reset to zero.
One more workaround Binding maxVerticalScroll bar. In this example I am providing two solutions either one should work for you

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx">
	<fx:Declarations>
		<fx:XML id="xml">
			<node label="Root">
				<node label="Folder a">
					<node label="item 1 a"/>
				</node>
				<node label="Folder b">
					<node label="item 1 b"/>
					<node label="item 2 b"/>
				</node>
				<node label="Folder c">
					<node label="item 1 c"/>
					<node label="item 2 c"/>
				</node>
				<node label="Folder d">
					<node label="item 1 d"/>
					<node label="item 2 d"/>
				</node>
				<node label="Folder a">
					<node label="item 1 a"/>
				</node>
				<node label="Folder b">
					<node label="item 1 b"/>
					<node label="item 2 b"/>
				</node>
				<node label="Folder c">
					<node label="item 1 c"/>
					<node label="item 2 c"/>
				</node>
				<node label="Folder d">
					<node label="item 1 d"/>
					<node label="item 2 d"/>
				</node>
				<node label="Folder a">
					<node label="item 1 a"/>
				</node>
				<node label="Folder b">
					<node label="item 1 b"/>
					<node label="item 2 b"/>
				</node>
				<node label="Folder c">
					<node label="item 1 c"/>
					<node label="item 2 c"/>
				</node>
				<node label="Folder d">
					<node label="item 1 d"/>
					<node label="item 2 d"/>
				</node>
			</node>
		</fx:XML>
	</fx:Declarations>
	<fx:Script>
		<![CDATA[
			import mx.collections.XMLListCollection;
			import mx.events.CollectionEvent;
			import mx.events.FlexEvent;
			
			[Bindable]
			public var ac:XMLListCollection = new XMLListCollection();
			
			public function refresh():void {
				tree.dataProvider = xml.node;
			}
			
			protected function creationCompleteHandler(event:FlexEvent):void{
				ac = new XMLListCollection(xml.node);
				tree.addEventListener(CollectionEvent.COLLECTION_CHANGE, function(event:Event):void{
					tree.verticalScrollPosition = tree.maxVerticalScrollPosition;
				});
			}
			
		]]>
	</fx:Script>
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<fx:Binding source="tree.maxVerticalScrollPosition" destination="tree.verticalScrollPosition"/>

	<mx:Tree width="200" id="tree" labelField="@label" dataProvider="{ac}" creationComplete="creationCompleteHandler(event)" showRoot="false"/>
	<mx:Button label="Refresh" click="refresh()"/>
	
</s:Application>

Open in new window

Avatar of Murali

ASKER

Hi

I am using older version of flex. so "xmlns:fx="http://ns.adobe.com/mxml/2009" " is not working in my program.. i tried adding an event listener as you showed in your previous program.

public function listenToTree(event:FlexEvent) : void
             {
                   tree.addEventListener(CollectionEvent.COLLECTION_CHANGE, function(event:Event):void{
                              tree.verticalScrollPosition = tree.maxVerticalScrollPosition;});
             }


i called this function the creationcomplete of the tree. but it is not working and the scroll is still on the top of the page after every refresh.


Is there any way i can get the exact co ordinates of the current position of my scroll button. so that i can goto that point after refresh. i tried capturing the value of tree.verticalscrollposition before the refresh and print it using alert.show.  but i found that it is giving random values and the values are increasing with every refresh.
did you try using Binding Metadata?

<fx:Binding source="tree.maxVerticalScrollPosition" destination="tree.verticalScrollPosition"/>


or for SDK 3

<mx:Binding source="tree.maxVerticalScrollPosition" destination="tree.verticalScrollPosition"/>
Avatar of Murali

ASKER

Hi

I tried using binding. It seems the refresh happens many times during the execution of the command. Hence it is not working. Is there any way we can get the co ordinates of the scroll bar position.
You said before you want to scroll to bottom (last scroll position)

Binding should fix your problem. What Flex SDK are you using 3 or 4?

<mx:Binding source="tree.maxVerticalScrollPosition" destination="tree.verticalScrollPosition"/>
 
Avatar of Murali

ASKER

Thanks...