A ScriptAculoUs autocomplete web control
To the reader - this post has evolved much and contains many comments. You don't need to read through them all to find things which have been forgotten or to find bug fixes and new features, because each of them, if valuable, has already been included in the release version of the code.
To contributors and readers - please don't use this post' comments anymore for anything related to the project, since it has now a dedicated page on the SVN hosting offered by Sourceforge, where you can submit issues, patches, ask questions and so on. All info can be found into this other blog post I dedicated to the topic.
UPDATE 24/08/06: Added some features and fixed some bugs, thank to Laurentiu Macovei, details in the post.
UPDATE 19/08/06: Removed property AdditionalControl and added property Parameters, details in the post.UPDATE 29/07/06: Added a new boolean property,
CacheSuggestions, which lets you choose whether to cache the suggestions on the client or not. Details in the post.
UPDATE 29/07/06: Now the controls work in conjunction with Atlas, read the post for the details.
UPDATE 08/07/06: Fixed a bug affecting the control when placed inside another WebControl.
UPDATE 05/07/06: Added a property -
ScrollSize - which allows to show the results in a scrolled fashion.
UPDATE 27/06/06: Now it can be embedded into a UserControl and can retrieve the values from a UserControl method.
UPDATE 24/06/06: Fixed the bug affecting Firefox and published sources.
ScriptAculoUs
is a top quality JavaScript library, useful for everything related to
client-side web programming, like effects, DOM programming, events and
so on.
Recently they included a new "control" in the package, which
is able to extend a normal HTML input text into an autocomplete
control. Does this remind you of the Atlas autocomplete extender? Read
on...
The word "control" is not the same as the one ASP.NET
programmers are used to hear, since it now refers to a client-side
behavior, which happens completely on the client.
This autocomplete control, whom you can see examples
here,
is very rich in features but not very developer-friendly from an
ASP.NET developer point of view, because almost everything has to be
programmed in the markup code and manually, so I decided to create a
custom control to wrap all those functionalities in a simple to use
component called ScriptAculoUs.Net.
But why is this better than the other thousand autocomplete controls available out there?
Well, first let me make a brief list of the ones I like most:
- Atlas Autocomplete extender: very cool, but you need a webservice to retrieve results.
- UPDATE 17/06/06: Atlas Smart Autocompletion:
a textbox built on top of Atlas framework which incorporates the Atlas autocomplete extender into a reusable web control, and enhances it by
allowing to retrieve the suggestion list from a page method other than
the classic web service method.
- Wilco Bauer's SmartTextBox: very well written webcontrol, source code is a must-see, but lacks client-side support.
- AspItalia TextBox Autocomplete: a must see too, can retrieve results from a DataSource control!
Ok, these are the coolest out there. My control can be better because:
- ScriptAculoUs is a client-side library, has great support for visual effects and the visual result is better than all of them;
- ScriptAculoUs is cross-browser, they mostly aren't;
- ScriptAculoUs is a continuous work in progress, it will improve and I won't have to care about it unless they change the API.
To sum it up, this is better because ScriptAculoUs preserves me from
caring about the client-side programming, which is the most part in an
autocomplete pattern, and provides us with a cool user interface made of fadings and scrollings (and well, much more).
Features and Usage
- No need for a web service or an external page to retrieve the
suggestions, just a page method, which has to be public, return an
object implementing the IEnumerable interface and accept a string as
input parameter (the typed keys) and/or a second array of strings parameter which contains the values of the controls specified within the property Parameters. Here is an example of how to write the method which returns the suggestions:
public string[] GetSuggestion(string key)
{
return new string[] { key + "aaa", key + "bbb", key + "ccc"};
}
In case the property Parameters contains values, the method will require a second parameter of type string[]:
public string[] GetSuggestion(string key, string[] parameters)
{
int i = parameters.Length;
return new string[] { key + parameters[0] + "aa", key + parameters[i-1] + "bb" };
}
and the markup of the page will look like the code below (the following result can be easilly achieved by using the Visual Studio designer and utilizing its straighforward collection editor):
<asp:TextBox id="TextBox1" runat="server"></asp:TextBox>
<ScriptAculoUs:AutocompleteTextBox id="AutocompleteTextBox1"
runat="server" methodname="GetSuggestions">
<Parameters>
<ScriptAculoUs:TextControlParameter ControlID="TextBox1">
</ScriptAculoUs:TextControlParameter>
</Parameters>
</ScriptAculoUs:AutocompleteTextBox>
- The support for effects, key navigation and everything related to client-side behaviors is great thanks to script.aculo.us.
- The results are cached on the client by default, so that when you type again the same characters they are retrieved by the local cache instead of performing a request to the server. Caching can be disabled using the property CacheSuggestions.
- Can be easilly configured to show an animated image next to it just
using a simple property. The image shows up when the control is
retrieving the results from the server and hides when the operation is
complete.
- Can be extended to use an AutocompleteProgress control, also
shipped, which can be placed anywhere on the page and customized using
templates, which makes its content visible when the main control is
retrieving results and makes them invisible when the callback is
complete. For those using Atlas, this is the same as the UpdateProgress
control.
- You can choose how many chars are needed to be typed before the
control performs a callback to the server. The default value is 1.
- The list of results appearance can be customized using some
style properties called Suggestionxxx and SelectedSuggestionxxx. Easy
to use.
- It is possible to scroll through the results using the ScrollSize property. It sets the height in pixels of the suggestion list area.
- UPDATE 29/07/06: The controls now do WORK in conjunction with the Atlas framework. In this post, Steve Marx describes his discovery of how Atlas and ScriptAculoUs can work together when the ScriptAculoUs scripts are injected in the page AFTER the Atlas scripts. Don't ask me why!
Since I inject the scripts programmatically in the control code (I use to do it in the PreRender phase), I have not much freedom on that, but Reflectoring the Atlas ScriptManager control I found that it injects its script during the Page PreRenderComplete event. Thus the problem turns out to be how to inject them LATER than Atlas.
As far as I know there is no event which fires after that one in which you can safely inject something in the page, so I subscribed to that event too and I did my injections there. Of course, since both Atlas and my controls inject their scripts at the same time, it becomes important the order they assume in the page. Ok, the solution is that you'll have to place your Atlas ScriptManager control BEFORE any ScriptAculoUs.Net controls, and everything will work fine! That won't be an issue I guess, since usually the ScriptManager control is placed by default on the top of the page, before any other controls.
I even played around with it a bit, and have been able to extend my AutoCompleteTextBox with the Atlas Control Toolkit's TextBoxWaterMarkExtender. Simply great. - UPDATE 19/08/06: Removed property AdditionalControl and added property Parameters. The only difference is that the Parameters property accepts a collection of values instead of only one. You can choose among the controls of the page which implement the ITextControl interface, that is, that can contain a text value. Those values are then passed to the method set with the property MethodName.
If one or more values are set in the Parameters property, then the method signature which returns the suggestion list must accept a second parameter of type string[]. - UPDATE 24/08/06: Laurentiu Macovei submitted a great contribution, here are the details:
Features added
- AutoCompleteAsHint property: for example you want to make a search form, but you
don't know what to type to get some results. This feature actually returns a set
of letters who are possible at a moment.
Eg. These are the simplified
keywords in DB: City, Police, Design, Magician and Motorcycle
If you will
type i, it will suggest you a, c, g and t. You pick one from
the list, eg. c and then it will suggest you c and e. And so on. Basically when
this feature is enabled, the suggestion is concatenated to the text, instead of
replacing the text with it.
- Ability to play with page_up, page_down, home, and end keys.
- Auto-suggest when click into the textbox.
Bugs fixed
- Annoying click on scroll (was closing the list)
- Annoying scroll into view (it didn't work, or work bad)
- Some wierd behaviour was fixed.
- Big scroll size, when not needed (now the list size adapts itself to how
much it needs, as maximum as you specifiy in the ScrollSize attribute. If not
needed, the scroll is not displayed).
I welcome any feedback and suggestion to improve it. A screencast
about how to set it up is available too. Please watch it at double
speed since it was recorded on a slow virtual machine, otherwise you
risk to fall asleep :-)
Download
Binaries: no more binaries, at the moment, too hard to keep track of them, please download the source.
Sources: only available on the SVN repository, read here for details.
Screencast: ScriptAculoUs.Net Demo.wmv