Scroll automatically to the bottom of a Container or TextArea

Someone recently asked the question of how do I scroll to the bottom of a container whenever I add a child. The easy answer was to just specify:

vbox2.verticalScrollPosition = vbox2.maxVerticalScrollPosition;

However, this is only part of the answer. I figured that you would set the verticalScrollPosition on the childAdd event and you were done. But, when I tried this, it didn’t work. I found that when childAdd is triggered, the Container had not fully re-measured itself. Therefore, the maxVerticalScrollPosition that it returned was not correct. However, if you wait and do a callLater, the code works. Here’s the full example:

Demo: scrollExample.swf

Example Code: scrollExample.mxml

In addition to wanting to scroll automatically in a container, I have heard the question of “How do I scroll to the bottom of TextArea as the text is dynamically changing?” The immediate thought is to set the verticalScrollPosition of the TextArea in its “change” event. However, again, this doesn’t work. Instead, you need to use the valueCommit event. This event is triggered later than the change event when the component has already re-measured. So, your code will look like this:

<mx:TextArea id=”ta1″ text=”{ta2.text}” valueCommit=”ta1.verticalScrollPosition=ta1.maxVerticalScrollPosition” />

Demo: scrollExample2.swf

Example Code: scrollExample2.mxml

33 responses

  1. thanks for posting this. In my particular case – for whatever reason – childAdd would not take care of it and the last added item was not visible; the Canvas I was using would not scroll right to the bottom. I fixed it by using the updateComplete event instead. And with a small mod you can also cut out the childAddHandler and do this (this is code from my app and may differ a little from yours):
    <mx:VBox id=”chat_list” updateComplete=”{callLater(updateChatScroll)}”…

    cheers

    Stefan

  2. I had the same problem stefan, still can’t see the most recently added child in the vbox. If i use the updateComplete then it works and scrolls to the very bottom. But that event gets called everytime you try and scroll through the container, making the scrollbar next to useless.. any ideas folks?

    1. Why not try on addedToStage

  3. instrumentArray is the dataprovider for your UIComponent
    also have this setting ===> creationComplete=”init()”

    [Bindable]
    public var instrumentArray:ArrayCollection = new ArrayCollection;

    private function init():void{
    instrumentArray.addEventListener(CollectionEvent.COLLECTION_CHANGE,onInstrumentArrayChange);
    }

    private function onInstrumentArrayChange(event:CollectionEvent):void {
    switch(event.kind) {
    case CollectionEventKind.ADD:
    callLater(focusNewRow);
    Logger.getInstance().debug(“Item “+ event.location + ” added”);
    break;
    case CollectionEventKind.REMOVE:
    Logger.getInstance().debug(“Item “+ event.location + ” removed”);
    break;
    case CollectionEventKind.REPLACE:
    Logger.getInstance().debug(“Item “+ event.location + ” Replaced”);
    break;
    case CollectionEventKind.UPDATE:
    Logger.getInstance().debug(“Item updated”);
    break;
    }
    }

    private function focusNewRow():void {
    instrumentGrid.verticalScrollPosition = instrumentGrid.maxVerticalScrollPosition;
    }

  4. callLater aint working so replace the line with the following
    //callLater(focusNewRow);
    instrumentGrid.verticalScrollPosition = instrumentGrid.maxVerticalScrollPosition;
    instrumentGrid.validateNow();

  5. It does not work well, if you use a DataGrid with word wrap. It scrolls only to the first line of your ward wrapped line. And after that the scrolling is broken. It seems that the calculations of the vertical dimensions of your data are wrong.

  6. @colonetz: I’m not 100% sure what your situation is, but, I’m assuming you are using a TextArea as an itemRenderer and can’t get the scrolling to work correctly? I tried this and posted an example here:

    http://butterfliesandbugs.bravehost.com/scrollingItemRenderer.mxml

    http://butterfliesandbugs.bravehost.com/scrollingItemRenderer.swf

    Because the measuring of the itemRenderer doesn’t seem to finish until the updateComplete event, I changed the scrollPosition after both a valueCommit and updateComplete had fired.

  7. This workaround are work for me. Thank you!

  8. Thanks alot for posting this…
    This works great…had no idea valuecommit even existed

    CHEERS!!

  9. I really needed this, and the solution is very easy!

    Thanks a lot!

  10. Nice example but can the scrolling be made more smoothly, especially in the first example with the buttons so that they do more of a “slide” than a non-animated repositioning?

  11. Thanks a lot. You have saved my time

  12. Hi ! I am trying to drag and drop controls/containers onto a container. however when i try to position my dragged item to the extreme right of the container, the container doesn’t scroll. so i have to drop the control anywhere on the container, then manually scroll the container, and again drag and drop the control on the desired location.

    Can anyone tell me the code such that when i drag a control on a container to its extreme edges, the container should auto scroll?

  13. Thanks for your post on “valueCommit”!

  14. Hi Joan,

    Thanks a ton for the post. It really helped me a lot.

  15. Thanks from another very happy person to have found this post!
    I was trying all sorts of goofy things — and was able to find this post at long last. I had no idea about valueCommit — wow. Cool stuff. Thanks again!

  16. Thank you very much for this valuable information!

  17. Use validateNow() after you made changes to the child list, then set scrollbar to maxScrollbar…

  18. Hey Thanks. It really helped solving the same problem i faced.

  19. WOW YOU’RE ROCKS!!!!

    you’re helping me, thanx

  20. The validateNow() did the trick for me. Thanks!

  21. Hi! Thank you for your post!I have the same problem!
    I used the method you gave!But it does not work well! Then I replaced the ChildExistenceChangedEvent with Event.ADDED. It works!
    I don’t know why!Can you tell me which event is triggered first?

  22. thanks so much, don’t know how long i’ve spent trying to get the scroll bar to stop jumping to the top.

  23. Scrolling TextArea is a bit more tricky. My problem was solved my adding listened to TextFlow UpdateCompleteEvent.UPDATE_COMPLETE event and scrolling only then.

    The issue is that scrollbar’s maximum value is inaccurate and you need to handle several sequential UpdateCompleteEvent.UPDATE_COMPLETE events to scroll REALLY to the end.

  24. FOR SPARK TEXTAREA, THE FOLLOWING WORKED FOR ME

    private function doUpdateComplete():void
    {
    ta.scroller.verticalScrollBar.value = ta.scroller.verticalScrollBar.maximum;
    }
    }

  25. Thanks a lot, helpful for me

  26. thank you, man!! That really works! however, using TextArea in Flash not Flex, doesn’t make such problem!

  27. Does not work in flex 4.5(hero)(beta)

  28. Thanks for saving my day!

  29. Hi, Excellent work. Don’t know how long i’ve spent trying to get the scroll bar to stop jumping to the top. thanks

  30. You could try myCanvas.validateNow() before setting the scroll position. Worked for me.

  31. Yes the following code is really help full ………

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: