Creating a Google Suggest Style Filter with the AutoComplete Control
I spent some time playing around with the AutoComplete control to see if we could use it to provide smarter filtering capabilities for our data tables. The general idea was that I would allow the user to select a filter column from a drop down list. Then as they key in characters into the adjacent textbox I would use the AjaxControlToolkit's AutoComplete extender to suggest some values to filter by. You can see this in the screen shot below. I selected 'City' in the drop down and then typed 'be' into the textbox and like magic the 3 cities in my data set that have start with 'be' appear.
Live Demo (IE6, IE7 and FF) | Download (.Net 3.5 and Toolkit 3.5.11119.0)
If you are interested in how I created this sample, the details are below.
The AjaxControlToolkit's AutoCompleteExtender
If are familiar with Google Suggest, the concept behind the AutoComplete control is the same. As you type into a textbox, a drop down list appears that provides suggestions for what it is that you are trying to type.
Here is the description provided by the toolkit's documentation.
To add AutoComplete functionality to your page, you have to work your way through three tasks:
- Wiring the AutoComplete extender to the TextBox
- Implementing the ServiceMethod that returns the list of suggestions
- Define the style rules for the AutoComplete's flyout
Wiring the AutoComplete Extender to a TextBox
We start by adding a regular TextBox to your page. The auto complete features are applied by adding the AutoComplete control to the page and pointing it (setting the TargetControlID) to that of the TextBox. Nothing special here, this is pretty much the same as all of the other extender controls.
Implementing the ServiceMethod
Next, we need to implement a bit of logic on the server that returns our suggestions based on the characters the user has typed into the TextBox. We can place this logic within a PageMethod or a WebMethod. However, for the AutoComplete control to function properly the method must take on one of the following signatures (you can change the method's name, but the parameter name and type and the return type must match exactly).
The prefixText parameter is the text the user has entered so far. count is the maximum number of suggestions to return. The final parameter contextKey allows you to provide any extra user or page specific context your ServiceMethod might need. The return type is a string array that contains the suggestions. Below is the ServiceMethod I have implemented for this sample.
I wanted my routine to provide suggestions only for the column the user has selected in the drop down list. I am using the contextKey parameter to send this additional bit of context information back to my ServiceMethod. So if you look at the screen shot below, I typed 'be' into the textbox and the AutoComplete control rendered a drop down with the following three value: Berlin, Beaverton and Beverly Hills. Before the drop down was rendered the following sequence of operations occurred
- The AutoComplete control invoked my GetCompletionList ServiceMethod, passing the following values: prefixText: 'be', count: 5, contextKey:'City'
- My ServiceMethod processed the request and selected the top 5 distinct Cities in my data set that start with the prefix 'be' (it turned out here were only 3).
- These 3 cities {'Berlin', 'Beaverton', 'Beverly Hills'} are returned to the AutoComplete control back on the client
- After receiving the list of suggestions, the control renders the flyout, providing the user with the suggestions
Styling the AutoComplete Flyout
Now that the controls are wired and our ServiceMethod is implemented, we can focus on the styling of our suggestion flyout. The AutoComplete control injects a UL/LI structure into the page for the suggestion items and provides you with 3 CSS classes that you can use to style the control to you liking.
I wanted my flyout to look as close as I could to a standard drop down list, so I used the following style rules. This is pretty close to what the AutoComplete's demo site uses, except I use the Highlight and HighlightText colors for the highlighted classes.
A Few More Details
As I was creating this sample, I stumbled into a few issues that I had to resolve. The first was that I needed a way to dynamically determine what contextKey value to send with the call to my ServiceMethod. So to accomplish this, I attached a JavaScript event handler to the AutoComplete's populating event. This event fires right before the the AutoComplete invokes my ServiceMethod. I use this event to register a bit of code that updates the contextKey value to the value of drop down's currently selected item. Secondly, after the user selects one of the suggestions, I want to force a postback so the filter can be applied to the data. I resolved both of these issues by using the following piece of JavaScript that runs on pageLoad ...
Other Items I Would Like To Get To
There were a few items that I didn't quite get to ...
- Improve the Styling of the Flyout
If you search on ajaxrain for autocomplete, you will find a ton of cool AutoComplete flyout's that include some pretty nice styles. I would like to see if the toolkit's AutoComplete control would support creating flyout's like this.
![]()
![]()
- What about when there are no suggestions?
I would like to let the user know that no suggestions were found. I need to look into how to do this.
That's it. Enjoy!
Comments
Matt,
if you get hold of "Improve the Styling of the Flyout" please let us know....one more supburb post.
thanks
Hey Matt,
Thanks
You rock !!!!
U the best.
Matt-
This post helped me out a lot. Thank you VERY much. Hope you get the styling part to work as itll be a great addition to what youve already accomplished. Thanks!
Matt,
Great work..
Cant you have a background image for the div?
like..
.autocompletelist{
background:url("../images/bubble_arrow_top_some_image.png") no-repeat;margin:0 auto;
}
Srikanth
Hi Matt,
I send you solution for
your question
What about when there are no suggestions?
did it work ?
very nice,thanks
@Nisar Khan, @Matt -
That is on my list of items to look into next. I whatever I find, I will post about.
@Srikanth -
Have you tried that? It seems like we would need a few more elements/rules to ensure the flyout is fluid as the number of items grows and shrinks.
@Vish -
Hi Vish. I am more than a little behind on email from the holiday. I did read yours though and I think you are dead on with the approach. When I start working on styling the flyout, I am going to try to incoporate your suggestions into the solution. Thanks!
Matt, thanks for the great work. Is there a way to print these without the right-side navigation?
Thanks a lot
Great work i am going to try this out for a website i am creating, that will be accessed using a PDA.
You might want to check out http://jeffzon.net/Blog/post/Giving-rich-styles-to-auto-complete-feature-using-StyledAutoCompleteExtender.aspx
I think it does everything youd want for the styling. Also has some other handy features.
It also works in Opera 9.x ! Mention that too
Greetings Matt!
Ive been following your blog for a while and LOVE it! you have great insights and it has really inspired me to get back into the "design side" of my web applications.
Im not sure if any other folks have gotten this to work, but I starting pounding away and got a working model of the flyout styles. Im still working on becoming a "jedi master" of CSS, but here is what my CSS looks like:
.AutoCompleteFlyout
{
background-image: url(Images/AutoCompleteFlyout.png);
background-repeat: no-repeat;
cursor: pointer;
width: 250px;
height: 200px;
padding: 10px 0 0 0;
}
.AutoCompleteFlyoutItem
{
background-color: Transparent;
width: 250px;
color: Black;
font-family: Arial;
font-size: 8pt;
}
.AutoCompleteFlyoutHilightedItem
{
background-color: Transparent;
width: 250px;
color: Black;
font-family: Arial;
font-size: 8pt;
font-weight: bold;
}
You can see a quick snapshot of how it looks here: http://www.dillieodigital.net/ImageFlyoutExample.jpg
The tricks I found was that I had to give an actual box size so that the entire background would show.
In addition, setting the background to transparent on the item and hilighted items prevented anything going over the border. Im sure you can fudge with the opacity of the style or image itself to make it nicer.
Again, Im still working on my CSS skills, so hopefully somebody can pretty this up even more.
Keep blogging Matt! You do phenomenal work!
Quick update:
Make sure to add a
list-style: none;
to your Item styles so that the bullets dont show up in Firefox.
Can you do it in Java too please ?
Matt,
For fluid background images inside a div,please refer this articlehttp://archivist.incutio.com/viewlist/css-discuss/91082
I havent tried it by myself, but will do sometime.
Srikanth
Matt,
Your blog has helped me a lot. One question: the autocomplete values returned from my web service contain punctuation. This causes the values in the autocomplete flyout panel to be messed up. Do you know how I can encode the results before returning them from the web service? Thanks.
Steve
@Sean Patterson
im still puzzle where i will be getting the Images/AutoCompleteFlyout.png from ?
also where do you add the .css methods ?
@Nisar
Sorry for the ambiguity. The image reference is whatever reference you want to your flyout background. I have a single flyout image serving as the background for the panel. Upon introspection, this might not be the best idea since a super long return list would cause some issues, but thats where Im going to leave it to the CSS gurus to work on while Im still exploring all of this.
As for the .css methods, Im not sure I understand what you mean. Here is howI reference the styles though:
TargetControlID="txtContractor"
ServiceMethod="GetCompletionList"
ServicePath="~/Services/ContractorInformation.asmx"
MinimumPrefixLength="2"
CompletionInterval="500"
EnableCaching="False"
CompletionSetCount="10"
CompletionListCssClass="AutoCompleteFlyout"
CompletionListItemCssClass="AutoCompleteFlyoutItem"
CompletionListHighlightedItemCssClass="AutoCompleteFlyoutHilightedItem" />
Great work.
Does this work with ASP.Net 2.0 and AJAX 1.0?
I am using the following css to create an image background that should appear to the left of the text in each item, but while it works fine in a normal in the control the text overlays the image instead of padding to the right. Any ideas? A working example of what I am looking for can be found on an airport search on kayak.com
.Item
{
line-height: 22px;
width: 329px;
display: block;
padding: 0 20px;
background: url(/images/drop-down-search-icon.png) no-repeat 3px center;
color: #1280d0;
text-decoration: none;
}
I am trying to apply the grid style to a gridview
But i am not get the gridview as it is shown in
live demo
Any help would be appericated
Hi,
Great article but its possible to do with an external Webservice. AutoCompleteExtender in an webapplication on a server (server A) can work with a webmethod of webservice thats run in another server (Server B)?
You are the King! I have been looking for ASP/AJAX Listview examples for a couple of days. Your examples are the best Ive seen. Im really interested in AJAx oppertunities with the Listview control.
Thanks,
Dennis
Please can anybody tell me how to make the flyover list displayed with the search text box to dropdown..
Matt, Words are failing to express my appreciation to your work, dedication, passion and brilliance. There is no other web site in this whole world that is better than yours for .NET and AJAX. The examples you provide are immaculate and if you were standing in front of me, Id touch your feet to get your blessings!!!! You are the best of the best!!!
hello there im having an error with this line of code that you posted. "return new CustomerDataObject().GetCompletionList(contextKey, prefiText, count);" it says compilation error.. instead of using customerdataobjetc i used sqldatasource since i used sqldatasource to bind my gridview.. what could be the possible solution for this.. i really need your help..thanks...and by the way its a great post..=D
Im wondering if youve found an efficent way to use the AJAX Control Toolkits AutoCompleteExtender with a "Search" button that will invoke the auto-complete. This would be used in the case that you have some other way of entering the search parameter other than by keying it in manually. For instance, you may copy and paste a search string in from another location, or there may be some other javascript on the page that carries a value over from another control.
Ive only just started playing with it. The best Ive been able to come up with is adding a _onBtnclick method to the AutoComplete.js source file that simply mimics the current _onKeyPress method (without testing for the various key strokes, and just firing the the _timer. This will make it so that when you deliberatly click on the textbox that already has a value entered, you get the fly-out list of suggestions.
Im having some trouble finding a way to reference the _timer object from that JS. All of the references to it use the "this" identifier (which as far as I can tell is the document itself). But document._timer doesnt work, nor does referencing the TargetControlID Ive given the ACE.
Any suggestions?
Hi Matt,
You have very good stuff and I have enlisted your material in http://www.downloadjavascripts.com. Thanks a lot and keep generating nice stuff !!!!
Hi Matt,
Great auto complete test! It looks great and functions nicely. I was wondering if you could help me out with something. I managed to get a test page working with the AutoComplete extender to pull in city and state values into a search box area. For the life of me, though, I can't find a way to reduce the completion set count. For example, if it starts out with 10 suggestions, I'd like the drop down to reduce the number of suggestions as more characters are entered in the text box. I'm not sure whether I have to alter my stored procedure or the .asmx.vb file. Any thoughts on this?
Hi Matt,
This is great, but can you help me out with something like, we have a huge database and the autocomplete brings around 10K of records, when I use this it takes a huge amount to bring the results and some time it halt the screen.
Is there any work around.
Thanks,
Hi Matt,
Great work,
Just a small suggestion needed, if I change MinimumPrefixLength to 4 and then search for "New York",
then it does not count the space for it. ie "New " will not return any results.
Any suggestion for this?
Thanks
Hi there, great job!
Any chance you could show me how to bind this to a dataset in xsd format?
Thanks!
Grant
Hi Guys,
Could you advise how can I add a progress indicator gif when loading data?
Thanks a lot!
Michael
Thanks for your very visual examples. The problem I'm having though, is the same as with the examples that come with the toolkit itself. Where is it, exactly, that the WebMethod is wired to the AutoCompleteExtender? I have the following defined:
ID="SearchTagAutoComplete"
runat="server"
TargetControlID="txtSearch"
ServiceMethod="GetCompletionList"
ServicePath="~/AutoComplete.asmx"
MinimumPrefixLength="2"
CompletionInterval="100"
CompletionSetCount="5" />
I have a WebMethod defined as:
public string[] GetCompletionList(string prefixText, int count)
{
List strList = new List(count);
strList.Add("Ajax");
strList.Add("ActionScript3");
strList.Add("JavaScript");
strList.Add("Flash");
strList.Add("Flex");
return strList.ToArray();
}
This performs no checking for the prefixText, just outputs an array of names for testing purposes. However, this code never executes. Is there another step, perhaps one that seems so obvious to those who know it as to skip it in explanation, needed to wire this up?
Please note the difference between the documentation and Matt's ServiceMethod: Matt's is static (correct) and the documentation's is instance (wrong).
Try to zoom the page in IE 7. The position of the popup is incorrect. Does anyone have an idea of workarround?
Hi Matt
Thanks a lot for the great blog. I had a quick question about using the static keyword for the method GetCompletionList(...). Does it have any thread issues if I implement this in an web application ?
Please let me know.
thanks
kiran