|
-
Senior Member
Finally, a ComboBox that works.
The AS3 ComboBox has always been really irritating in data-driven apps. In short, it just doesn't work the way you expect a dropdown menu to work as far as keyboard accessibility. Any time you hit a key, it jumps to the first label starting with that letter, instead of letting you keep typing a word out. This irritates clients, who might have a combobox with a few thousand usernames in it. If three hundred of them start with "S", they have to type "S" and scroll down or arrow down to find the right one. Worst of all, it's very easy to forget that an app works this way, so there's the repeated aggravation of starting to type and then remembering that AS3 components are stupid. Or, as a client asked me, "why the **** can't it just work like everything else on the web?"
Well, now it can. The following is a drop-in replacement for ComboBox that works the way everything else on the web does. It's fast, fun and free. I'm putting this out for all to enjoy.
Cheers,
Josh
Code:
package {
import flash.utils.Timer;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.TimerEvent;
import fl.controls.ComboBox;
import fl.data.DataProvider;
public class StrikeCB extends ComboBox {
private var buffer:String = "";
private var timer:Timer = new Timer(400);
private var dict:Array = new Array();
private var ds:Array;
public function StrikeCB() {
super();
init();
}
public function init():void {
addEventListener(Event.ADDED_TO_STAGE,addListeners,false,0,true);
addEventListener(Event.REMOVED_FROM_STAGE,remListeners,false,0,true);
}
private function addListeners(evt:Event):void {
this.addEventListener(FocusEvent.FOCUS_IN,openListen,false,0,true);
this.addEventListener(FocusEvent.FOCUS_OUT,openListen,false,0,true);
timer.addEventListener(TimerEvent.TIMER,clearBuffer,false,0,true);
buffer = "";
}
private function remListeners(evt:Event):void {
removeEventListener(FocusEvent.FOCUS_IN,openListen);
removeEventListener(FocusEvent.FOCUS_OUT,openListen);
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,clearBuffer);
buffer = "";
}
private function openListen(evt:Event):void {
if (evt.type == "open" || evt.type=="focusIn") {
addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown,false,0,true);
} else {
removeEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);
}
}
private function onKeyDown(evt:KeyboardEvent):void {
if (evt.charCode == Keyboard.SPACE) return (void);
buffer += String.fromCharCode(evt.charCode);
if (!ds) ds = dict.slice();
for (var m:int = 0;m<buffer.length;m++) {
for (var k:String in ds) {
if (ds[k] === null) continue;
if ((ds[k].length<buffer.length ||
buffer.substr(m,1).toLowerCase()!=ds[k].substr(m,1).toLowerCase()) &&
ds.length>1) {
ds[k] = null;
}
}
}
for (var u:String in ds) {
if (ds[u]!=null) {
this.selectedIndex = int(u);
this.highlightCell(int(u));
this.dropdown.scrollToIndex(int(u));
break;
}
}
timer.reset();
timer.start();
}
private function clearBuffer(evt:TimerEvent):void {
buffer = "";
ds = null;
}
override public function set dataProvider(arg0:DataProvider):void {
super.dataProvider = arg0;
for (var i:int=0;i<arg0.length;i++) {
dict[i] = arg0.getItemAt(i).label;
}
}
override protected function highlightCell(arg0:int=-1):void {
if (arg0>-1) selectedIndex = arg0;
super.highlightCell(arg0);
}
}
}
Last edited by joshstrike; 04-12-2011 at 02:14 PM.
Reason: fixed what happens when it's closed, but focus is on.
-
ohh wow dude thank you, I had a client complaining about this the other day!
-
Senior Member
=)
One little note; it still doesn't work if the CB isn't open. That is, the normal behavior takes over if the CB is closed but still has focus on it. With a little tweaking though, it could do that too.
...actually, scratch that, I'm editing it right now to fix it.
-
let me know when you have an update... also I have a problem for you if you feel up to it, im sure someone with your experience will be able to explain to me what I am doing wrong!
-
Senior Member
Oh yeah. The update's already in there. I just edited the code in the original post 
Feel free to ask me anything you like, but maybe start a new thread and shoot me a PM or email about it so this one doesn't get off-topic?
Cheers,
Josh
-
weird problem
whats up man, Ive had a problem thats been bugging me for a while that makes no since to me...
Im having a problem with my add engine for some reason...
http://board.flashkit.com/board/showthread.php?t=822302
Ive had buttons embedded in a MC functional before (and easily) why is this time different?
-
Is there something I'm missing in your code, here? I pasted it as is, but I when i render my movie, I get a flashing comboboxes, and an error that says "Packages cannot be nested" - what am I missing?
-
Senior Member
There's nothing wrong with the code. It's inside a package. That means it goes in its own actionscript file, which you then import when you want to use it. You're supposed to change package {} to package folder.folder2.whatever {} depending on the relationship of the actionscript file to your actual FLA. You can't copy and paste this into the Actions panel.
For more information...
http://bit.ly/wwPwcj
-
ohh! I see (said the blind man to his deaf dog) - that makes more sense. Thanks for the clarification.
-
 Originally Posted by joshstrike
There's nothing wrong with the code. It's inside a package. That means it goes in its own actionscript file, which you then import when you want to use it. You're supposed to change package {} to package folder.folder2.whatever {} depending on the relationship of the actionscript file to your actual FLA. You can't copy and paste this into the Actions panel.
For more information...
http://bit.ly/wwPwcj
What if the .as file is in the same folder as the .fla? I saved the code in a separate .as file and named is StrikeCB.as, but I still get the same Nested Package Error when I play my movie ugh
-
override protected function highlightCell
I don't find highlightCell as a methode of Combobox
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|