Flex Smart Combo (aka look ahead combo)

A few weeks back a fellow UM-er asked if there had been a look ahead combo created at some point and possibly checked into our library.

To my knowledge such a component didn't exist except for a few components running around that didn't exactly do what he was looking for. So I spent some time extending combo box to create the functionality he was looking for.

This component allows a user to hot key filter the combos list/data provider which means, when the combo box gains focus it becomes editable allowing key entry to filter the list items based on the keys pressed.

It is quite slick and is written entirely as a single class extending ComboBox. Feel free to enhance, chop, criticize... It's yours to use how you wish and I hope it assists you in your efforts. Enjoy!

I would like to thank Adam Flater for adding case sensitivity option and label filtering. Check out his blog: Here

********* UPDATE: 6/26/2008 ************

Resolved focus issues. Enabled view source (right click on the swf).

package com.universalmind.controls
{
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.MouseEvent;

import mx.controls.ComboBox;

public class SmartCombo extends ComboBox
{
private var _trackText:String = "";
private var _caseSensitiveSearching : Boolean = true;

public function SmartCombo()
{
//TODO: implement function super();
}

public function set caseSensitiveSearching (bool : Boolean) : void {
_caseSensitiveSearching = bool;
}

public function get caseSensitiveSearching () : Boolean {
return _caseSensitiveSearching;
}

override protected function textInput_changeHandler(event:Event):void {
_trackText = this.textInput.text;

// variables used in the loop var label : String = null;
var matchingIdx : int = 0;
var foundMatch : Boolean = false;
var searchString : String = this.textInput.text;

if ( caseSensitiveSearching == false ) searchString = searchString.toLowerCase();


// using a for each loop on dataProvider does not strongly // couple to it only being an ArrayCollection... simlar // with weak typing on the items in the set for each ( var item : Object in this.dataProvider )
{
// using itemToLabel() checks a few things like // if the item is a String, or it there's a // labelFunction being used label = this.itemToLabel( item );


// if searching should not be case sensitive // do a toLowerCase() on label if ( this.caseSensitiveSearching == false )
{
label = label.toLowerCase();
}


// find the first item that starts with searchString // if there's a match, break out of the loop if ( label.substr( 0, searchString.length ) == searchString )
{
this.dropdown.selectedIndex = matchingIdx;
this.dropdown.scrollToIndex( matchingIdx );
foundMatch = true
break;
}
matchingIdx++;
}


// if there was no match found set selectedIndex to -1 // (unselect the list) if ( foundMatch == false )
{
this.dropdown.selectedIndex = -1;
}
}

override public function close(trigger:Event=null):void{
super.close(trigger);
if (this.text == "")
{
this.selectedIndex = 0;
}
this.editable = false;
}

override protected function focusOutHandler(event:FocusEvent):void
{
super.focusOutHandler(event);
if (this.text == "")
{
this.selectedIndex = 0;
}
this.textInput.selectionEndIndex = this.textInput.width;
this.editable = false;
}

override protected function focusInHandler(event:FocusEvent):void
{
super.focusInHandler(event);
this.editable = true;
this.textInput.setFocus();
this.open();
}


}
}

Example:

Download Source Project: Here

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Thanks for the shout out. You've ended up with a slick control there.

cheers
-adam
# Posted By Adam Flater | 5/7/08 1:11 AM
great implementation;
Have a similar working component done by extending combobox; I did not use the editable option to cache the input text; did the caching in a variable instead; SmartCombo offers a better UI option to the user though;
# Posted By Sameer | 5/21/08 4:00 AM
thanks! it is very useful... but, it haves an error.. in extInput_changeHandler method i replaced this line: "var searchString : String = this.textInput.text;" for this line:
"var searchString : String = this.textInput.text + e.text;"

and it is working very well now... it is because input.text has not all text before event. Regards. Fede
# Posted By Federico Schluter | 6/25/08 11:25 AM
Hi Fede, thanks for the reply but I am not understanding the issue. What does your var "e" refer to? I am not seeing the issue with your all text concern?

Please let me know I will update the component if what you have found is proven to be an issue.
# Posted By Strikefish | 6/26/08 8:08 AM
Hi! I am sorry... it was a little error...
e.text refers to event.text for your code.

If you executes
<code>
var searchString : String = this.textInput.text + event.text;"
</code>

you will see it works better.. it is because last chat entered is not yet in this.textInput.text

I hope it was useful for you..
Regards
you will
# Posted By Federico Schluter | 6/26/08 2:30 PM
sorry...
i needed to make this change because i used your code in other event handler... keyDownHandler
Your component works well, sorry..
see you...
# Posted By Federico Schluter | 6/26/08 2:32 PM
Very nice control. I found one wart - if you select the same entry twice using the keyboard, it doesn't show the selected text properly. For example, in your demo, select &quot;Macstercard&quot; any way - it works as expected. Then, if you type &quot;Macs&quot; into the control when it's editable, and press enter, it doesn't show &quot;Macstercard&quot; in full - just &quot;Macs&quot;. I think it's because the selected item doesn't change.

I got around it as follows: at the end of the close() method, I added the following (pseudocode):

if (selectedIndex &gt;= 0) {
if (textInput.text != label of selected item) {
textInput.text = label of selected item
select all the text in textInput
}
}

This then behaves consistently, but I'm not sure it's the best solution.

Thanks for sharing.
# Posted By Krasna Halopti | 12/5/08 1:51 PM
Decent component. The only problem I have with it has something to do with focusManager. If, for example, you click inside the combobox's textInput and type &quot;v&quot;, the area inside the textInput says &quot;v&quot;. Now, instead of tabbing out, click somewhere in the stage to take focus away from the combobox. Click inside of the combobox's textinput again and type &quot;mb&quot; It will not go to mbstercard because it is now acting like a combobox and not a textinput, going to the first 'M' item in the list. If I decide to use it I'll gladly clean it up a bit and send the changes your way. Thanks for the smoothly acting component.
# Posted By jeremy | 12/11/08 12:23 PM

Copyright Strikefish, Inc., 2005. All rights reserved.