RSS Valid
XHTML Valid
CSS Valid

Forcing ComboBox Component Open Direction in Flex

Tuesday, October 14th, 2008

The ComboBox component is neat because it automatically determines if there is enough space for it to open down and if there isn’t, it’ll tween upwards instead. However, I came across an issue recently where I needed to force it to open up or down. Unfortunately, the displayDropdown method is private, so overriding and re-writing the code is out of the question. You could override keyDownHandler, close, open, and downArrowButton_buttonDownHandler and then replace displayDropdown with a custom function in each, but that seems annoying to me! I’m not sure why the displayDropdown function is private, but anyway, here’s a simple solution to force direction.

First navigate to the Flex framework codebase (mine is in /Applications/Adobe Flex Builder 3/sdks/3.0.0/frameworks/projects/framework). What you’re going to do is copy the ComboBox source file and it’s required classes/files to your local classpath. This will force flex to use mx.controls.ComboBox in your classpath instead of the Frameworks. I found that I needed to copy over the following files (core.Version and a number of the files from styles/metadata are “included” in ComboBox.as). Don’t worry, you’ll only have to modify ComboBox.

/mx
    /controls
        /ComboBox.as
    /core
        /Version.as
    /styles
        /metadata

Once you’ve added these to your class path, open up ComboBox. First add some hacky public vars to the class:

public var forceDirectionDown:Boolean = false;
public var forceDirectionUp:Boolean   = false;
Then in the definition for displayDropdown, starting at around line 1553, change the method to look something like this (I didn’t rewrite much, just hacked in the new stuff because I needed this quickly):
var pt:Point = new Point(point.x, point.y);

// if we donot have enough space in the bottom display the dropdown
// at the top. But if the space there is also less than required
// display it below.
if (point.y + _dropdown.height > screen.height &&
    point.y > _dropdown.height)
{
    // Dropdown will go below the bottom of the stage
    // and be clipped. Instead, have it grow up.
    point.y -= (unscaledHeight + _dropdown.height);
    initY = -_dropdown.height;
    tweenUp = true;
}
else
{
    initY = _dropdown.height;
    tweenUp = false;
}

// hack in the force support
if (forceDirectionDown) {
	// reset to point.y
    point.y = pt.y;
    initY = _dropdown.height;
    tweenUp = false;
} else if (forceDirectionUp && !tweenUp) {
    point.y -= (unscaledHeight + _dropdown.height);
    initY = -_dropdown.height;
    tweenUp = true;
}
That’s pretty much it. Now when you declare your combo in mxml, you can specify to force it up or down. Example:
<mx:ComboBox id="mapType" 
             forceDirectionUp="true"
             labelField="label"
             labelFunction="labelFunction"
             visible="{ready}" 
             width="150"/>

Got a better way of doing this? Show me!!

4 Responses to "Forcing ComboBox Component Open Direction in Flex"

  1. Damien says:
    November 14th, 2008 at 7:57 am

  2. Andrew says:
    January 6th, 2009 at 1:22 pm

  3. radley says:
    January 27th, 2009 at 11:31 am

  4. Craig Grummitt says:
    March 3rd, 2009 at 6:04 pm

Leave a Reply

Availability

We'd love to hear about your project! Please see the services and contact sections for more information or for work inquiries.