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.
[Sample removed. Please download the new version instead]
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.
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!
I can’t get the example to run Sho. It just hangs…
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).
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… :(
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.
I definitely like it. One comment, it would be a better proof of concept if you used the countries in both examples.
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”.
On second look, “c” it doesn’t pull up “pistachio” because it isn’t in the list. =) But if it were it would.
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!
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
I’ll be posting an updated example shortly. Thanks!
This is pretty cool
Will this component support itemRenderer as per normal Flex combox in the future?
so that the “dropdown list” can render more then just text?
cheers
Thanks, nz.
I probably won’t support itemRenderer, although you’re more than welcome to add it. (Shouldn’t be too much work, since the list is built using a List control, which already knows about itemRenderer).
The main reasons are:
1) I wanted to create a control of moderate complexity to illustrate what it’s like to create a control. It doesn’t do everything that the framework controls do (so it’s much easier to read and understand), but it is complex enough that it gets into some meaty issues.
2) Auto-complete implies that the items are strings, or at least have a strong relationship to strings. This does not mean that I can’t imagine ways to use item renderers. However, it does mean that you’re somewhat less likely to need them in auto-complete controls than in, say, TileList, which is just a way of laying stuff out on the screen.
Of course, if enough people ask for it, or if you can help me think of some cool use cases, you might end up convincing me after all…
Just mainly for eye candy :) e.g. maybe we want to show the text and description on the next line, or an icon next to each of the items in the list etc like you can with the lists in combo boxes etc.
Agree with Kevin though, hope too see a community developing Flex 2 components etc
cheers