« 10 favorite things about Flex Builder Beta 1 | Main | Evolution of a feature - layout constraints »
February 15, 2006
MXML text completion control v. 0.5 (aka down with combo boxes!)
I've always been frustrated by the way HTML applications use pull down menus. How many times have you had to pick a country out of a huge pull down menu? Do you use the mouse to scroll down to the country? What about using the keyboard? You have to keep hitting the same key over and over. Neither approach is easy.
Meanwhile, text fields that offer completion hints are starting to become standard for Flex and AJAX applications. Typicaly, these are used to let you quickly pick things that you've already typed into the box. They are not used for picking, say, a country from a list of countries.
I believe text input fields that offer hints for possible completions should be used instead of combo boxes 95% of the time. Down with combo boxes!
1) When you want to use the mouse, it is just as simple.
2) When you want to use the keyboard, it gives you better feedback on what you have typed already.
3) It gives you an obvious affordance to "start over" when you've made a typo.
4) It gives you more immediate feedback.
Here is a relatively simple version of a text completion control for MXML. Unlike most versions of this type of control, this is also optimized for the above case: picking from a list of predefined strings.
When you want to pick from a list of predefined strings, just supply the list of all strings as the dataProvider of the control (just like how ComboBox works), and set the "mustPick" flag to true.
Let me know what you think. Are there bugs? Do you think the heuristics are wrong? Is this a good idea in general?
P.S. I've also had to include some other random classes as part of this. I plan on officially distributing these classes and other classes once they are more baked.
Posted by sho at February 15, 2006 08:25 PM
Trackback Pings
TrackBack URL for this entry:
http://weblogs.macromedia.com/mtadmin/mt-tb.cgi/7081
Comments
Nice work - it's a great idea and so far as I can tell works brilliantly. I'm with you - I'd love to see more of these rather than the combos :-) Look forward to the final release!
Posted by: Mike at February 16, 2006 10:38 AM
I can't get the example to run Sho. It just hangs...
Posted by: todd at February 16, 2006 10:39 AM
How funny! I had a customer ask for this exact feature just the other day. Historically, I've always had to say "well, you can build it". Now I'll just send them here (smile).
I think ideally one of the things Flex 2 needs to be really successful is a rich component development community. You see these in place already with .NET, Java from a UI perspective. I think it would also be beneficial to see something along the lines of a package manager (i.e. Perl mods). Looking for a library that does X? No need to go searching, just run the Flex package manager and query it for availability. Done!
Great post - looking forward to the GA release (smile).
Posted by: Kevin Hoyt at February 16, 2006 11:04 AM
I think I know my prob...This requires 8.5, right?
I thought I had installed it on this machine, but a simple right click told me otherwise... :(
Posted by: todd at February 16, 2006 12:29 PM
hey Sho - nice work ! In the entry on the iteration::two blog at http://www.richinternetapps.com/archives/000079.html we posted an example of an optimisation for this sort of functionality - we didn't publish the source (because we were iteration::two back then, and had to keep SOME goodness to ourselves :) ) but I'll see if we can dig out some source to share on the implementation.
In the meantime, it might be a good approach to incorporate into your component (which has a nicer UI to show the possible completions in a drop-down).
Hope to catch up with you again soon - Steven.
Posted by: Steven Webster at February 16, 2006 12:44 PM
I definitely like it. One comment, it would be a better proof of concept if you used the countries in both examples.
Posted by: Mark Belanger at February 16, 2006 12:55 PM
One little thing that would help is to have the search string highlighted in the suggested completions. The most common autocomplete systems (like in IE and Firefox) only use the first letter to filter. For people not accustomed to substring filtering, they may be confused as to why "c" pulls up "pistachio".
Posted by: Robert Penner at February 16, 2006 02:21 PM
On second look, "c" it doesn't pull up "pistachio" because it isn't in the list. =) But if it were it would.
Posted by: Robert Penner at February 16, 2006 02:23 PM
Todd: yes, you need 8.5
Kevin: Glad this helps!
Steven: Interesting you mention this. I played around with this approach but decided to go with sorted lists instead, because they were easier for me to think about and seemed fast enough.
The data structure you describe in your article is a trie (sometimes pronounced "tree", sometimes pronounced "try"). It is definitely the fastest data structure for doing prefix filtering, but takes the most space. There is a variant which is more space efficient called a Patricia Tree, which collapses nodes that only have one child. There are other popular variants, in which an array is sorted, and then a jump table is built for the first several characters that point to indices in the sorted array. Kind of a like a trie that points into an array.
Theoretically, a trie is a constant time lookup for fixed key lengths, whereas I am using a binary search, which is a log N process. However, the main performance issues arise not in the lookup, but the handling of the data after the lookup.
When no characters have been typed, the filtered result is the same as the original list of strings. In my code, these strings are copied into a separate array. That is obviously an order N operation. There is also a just-as-obvious solution to this, which is to make an empty prefix a special case and return the original array instead of a copy.
Finally, I deal with the sort order of the results by creating my list of candidates and then sorting them. This is an N log N operation. If you can help me speed this up, this would be the biggest bang.
In any event, if you can help me make this code faster, I'd be all for it!
Posted by: Sho Kuwamoto at February 16, 2006 02:54 PM
This is really nice example, but it doesn't works in flex 2 beta 2 (some problem with ModelChangedEvent). Would you update it to work with beta 2?
Thanks,
Milan
Posted by: milan at March 24, 2006 12:56 AM
I'll be posting an updated example shortly. Thanks!
Posted by: Sho at March 24, 2006 08:46 AM