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)

image

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.    

image

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.

image

 

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). 

image

image

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.  

image

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

  1. The AutoComplete control invoked my GetCompletionList ServiceMethod, passing the following values: prefixText: 'be', count: 5, contextKey:'City'
  2. 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).
  3. These 3 cities {'Berlin', 'Beaverton', 'Beverly Hills'} are returned to the AutoComplete control back on the client
  4. After receiving the list of suggestions, the control renders the flyout, providing the user with the suggestions

image 

 

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.

image

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.

image

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 ...    

image

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.

image  image

  • 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!


TrackBack

TrackBack URL for this entry:
http://mattberseth.com/blog-mt/mt-tb.fcgi/97

Listed below are links to weblogs that reference Creating a Google Suggest Style Filter with the AutoComplete Control:

» Google suggest style filter from ASP.NET AJAX Toolkit Forum Posts
I am trying to create a filter similar to Creating a Google Suggest Style Filter with the AutoComplete [Read More]

Comments


Posted by: Nisar Khan on December 28, 2007 12:00 AM

Matt,

if you get hold of "Improve the Styling of the Flyout" please let us know....one more supburb post.

thanks

Posted by: Vish on December 29, 2007 12:00 AM

Hey Matt,
Thanks

You rock !!!!

Posted by: Kasim on December 30, 2007 12:00 AM

U the best.

Posted by: Matt on December 31, 2007 12:00 AM

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

Posted by: Vish on January 2, 2008 12:00 AM

Hi Matt,

I send you solution for
your question
What about when there are no suggestions?

did it work ?

Posted by: T.Johnny on January 3, 2008 12:00 AM

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!

Posted by: DaveZ on January 4, 2008 12:00 AM

Matt, thanks for the great work. Is there a way to print these without the right-side navigation?

Thanks a lot

Posted by: MikeCiav on January 4, 2008 12:00 AM

Great work i am going to try this out for a website i am creating, that will be accessed using a PDA.

Posted by: michael on January 4, 2008 12:00 AM

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.

Posted by: Bob on January 7, 2008 12:00 AM

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

Posted by: Steve on January 15, 2008 12:00 AM

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

Posted by: Nisar Khan on January 19, 2008 12:00 AM

@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" />

Posted by: AGL on February 5, 2008 12:00 AM

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;
}

Posted by: jai ganesh on March 1, 2008 12:00 AM

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

Posted by: Jonix on March 18, 2008 12:00 AM

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)?

Posted by: Dennis Tindall on April 2, 2008 12:00 AM

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

Posted by: archana on April 14, 2008 12:00 AM

Please can anybody tell me how to make the flyover list displayed with the search text box to dropdown..

Posted by: Bharath on May 3, 2008 12:00 AM

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!!!

Posted by: gurly on June 23, 2008 12:00 AM

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?

Posted by: Deepesh Verma on August 14, 2008 09:00 AM

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

Posted by: Grant on August 24, 2008 11:37 AM

Hi there, great job!
Any chance you could show me how to bind this to a dataset in xsd format?
Thanks!
Grant

Posted by: Michael on August 24, 2008 08:40 PM

Hi Guys,

Could you advise how can I add a progress indicator gif when loading data?

Thanks a lot!
Michael

Posted by: Wil on August 26, 2008 04:52 PM

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).

Posted by: tanja on September 16, 2008 08:12 AM

Try to zoom the page in IE 7. The position of the popup is incorrect. Does anyone have an idea of workarround?

Posted by: kiran on October 8, 2008 10:34 AM

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

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Consulting Services

Yep - I also offer consulting services. And heck, I'll do just about anything. If you enjoy my blog just drop me an email describing the work you need done.

Recent Comments

  • kiran wrote: Hi Matt Thanks a lot for the great blog. I had a quick question about using the static keyword for ...
  • tanja wrote: Try to zoom the page in IE 7. The position of the popup is incorrect. Does anyone have an idea of wo...
  • Jacques wrote: Please note the difference between the documentation and Matt's ServiceMethod: Matt's ...
  • Wil wrote: Thanks for your very visual examples. The problem I'm having though, is the same as with the example...
  • Michael wrote: Hi Guys, Could you advise how can I add a progress indicator gif when loading data? Thanks a lot...
  • Grant wrote: Hi there, great job! Any chance you could show me how to bind this to a dataset in xsd format? Thank...
  • Deepesh Verma wrote: Hi Matt, Great work, Just a small suggestion needed, if I change MinimumPrefixLength to 4 and then...
  • Deepesh Verma wrote: Hi Matt, This is great, but can you help me out with something like, we have a huge database and th...