Tuesday, March 29, 2011

Flex: Disable mouse wheel scrolling for Text

In several places in our application we have Text components that dynamically resize depending on their content. An annoying thing about these Text components is that they start scrolling when the user uses the mouse wheel while hovering the components. I have been trying to disable this scrolling for a while but all of the proposed solutions* that I have found have not worked.

It was only today when I broadened my search criteria to target the Flash community rather than limit the search to Flex that I finally found a solution:

http://www.eddieoneverything.com/articles/disabling-textarea-scrolling-in-flash-as3.php

Based on the solution proposed in this link I created a new text component for Flex that does not allow the user to scroll the content.

Here is the code. Feel free to re-use it in any way you deem fit.

package com.flexceptional.components
{
    import flash.events.Event;
    import flash.text.TextFieldAutoSize;
    
    import mx.controls.Text;
    import mx.events.FlexEvent;
    
    public class TextNoScroll extends Text
    {
        override protected function createChildren():void
        {
            super.createChildren();
            
            // To get rid of unwanted scrolling. Needs to
            // be done any time the component is resized
            // or the content changes.
            addEventListener(FlexEvent.UPDATE_COMPLETE,
                             updateCompleteHandler);
        }
        
        private function updateCompleteHandler(event:Event):void
        {
            textField.autoSize = TextFieldAutoSize.LEFT;
            var tempHeight:Number = textField.height;
            textField.autoSize = TextFieldAutoSize.NONE;
            textField.height = tempHeight + 20; // Padding 20px
        }
    }
}

* Proposed solutions that did not work:

  • Setting mouseWheelEnabled=false on the internal textfield
  • Stopping propagation of any mouse wheel events on the text component or the internal text field
  • Setting mouseEnabled = false on the Text component. Well, this actually does disable the scrolling but it also disables any other mouse action, like selecting text or clicking links.

9 comments:

  1. Thanks for the posting. Your solution is similar to a few others out there, but I was still having issues. I had to implement this with one extra line of code added as the last line of your updateCompleteHandler function - an additional event listener - and a function to handle it in order to get this working properly:

    textField.addEventListener(MouseEvent.MOUSE_WHEEL,function(event:MouseEvent):void{callLater(setScroll,new Array(textField));});

    And then the function "setScroll":

    private function setScroll(field:TextArea):void{
    field.verticalScrollPosition = 0;
    }

    ReplyDelete
  2. One other comment. You probably could implement this slightly different by sending "event.currentTarget" to setScroll as well. The overall idea is that you set the vertical scroll position to the top of the text area after all other things have completed with that mouse wheel event.

    ReplyDelete
  3. Hi Doug. Thanks for your comment. Please note that the component proposed in my post addresses scrolling issues with the mx.controls.Text component and the textField variable mentioned in the code is a reference to the internal IUITextField member of that component.

    ReplyDelete
  4. I tried this component and it did not work for me. In Safari, the mouse wheel still scrolls the mx:Text vertically when it has wrapped.

    ReplyDelete
  5. Never mind. Browser cache. Cleared it, reloaded my Flex app page, and it does work. Thanks!

    ReplyDelete
  6. I had the same problem with an mx:List component and found that mouseChildren="false" fixed it.

    ReplyDelete
  7. mouseChildren="false" worked for me as well. Thanks Lawrence :)

    ReplyDelete
  8. How to remove tool tip on Mouse Wheel event functionality in ComboBox using flex3.0

    ReplyDelete
  9. Works perfect for me. Thank you!

    ReplyDelete