[Part One] [Part Two] [Part Three] [Part Four] [Part Five]
So in my journey to create an autocomplete control, I had it working except something really screwy with the stylesheet and how to make it look… oh I don’t know… not hideous. So on a whim I decided to give the Ajax Control Toolkit Autocomplete a try. I figured that if so many other people use it, why shouldn’t I? Or when properly translated: I hate dealing with style sheet issues and someone already had a control that works in both Firefox and IE.
Introduction… Skip if you know what this is already and just want the stupid code.
So where to begin? Well the autocomplete control itself is free and comes along with the Toolkit assembly.
Sounds good so far, so what does it do? It’s a “control”, for lack of a better word… more on that later, that can be used to attach to a textbox and allow a user to type in parts of a word and get back dropdown list like item… list.
Pretty good huh? What’s the catch? Well basically you need to use a web service to work with it, meaning either old school (.asmx?) or new school Communication Foundation services. For this example I will actually be doing it the “hard” way and use WCF. I’ve done it with both, but I figure I might as make it the more difficult of the two for fun. If I remember, the old web services are really easy to do this with. Another catch is that the web service has to be on the same server as the project.
So what isn’t it? End of world hunger, world peace, or the meaning of life. Sorry, I can only give you one of those and the autocomplete doesn’t cover that subject.
End Introduction and Begin the stupid code
Ok so you want to use the autocomplete control, huh? Well, you’ve come to the right place.
For this example, I’ll be doing the most simple version of adding the autocomplete control. This basically means setting up the service and creating some markup. Really easy. Next post I will get into how to create a web control class in a non web assembly.
Right off the bat you’ll need the toolkit assembly and create a project reference to it. Next you have to set up the WCF Service which is actually a lot easier than it sounds? Why? Because Microsoft was nice enough to create a default one for us. I’ve created a folder named Service (Brilliant!) and then I right clicked and chose Add New Item -> Ajax-Enabled WCF Service (I called it AutocompleteWebControl)… and boom already almost there.
You should now have a AutocompleteWebControl.svc.cs file in the folder and if you look at the code you get this:
namespace Test.Frontend.Service { [ServiceContract(Namespace = "")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class AutocompleteWebControl { // Add [WebGet] attribute to use HTTP GET [OperationContract] public void DoWork() { // Add your operation implementation here return; } } }
Only thing of real importance at this point is the method with the [OperationContract] attribute. If you are going to expose a method to the autocomplete it has to have this tag. Now as you can see, we’ll need a method. At this point though I have to note two things that for the method to be correct:
- It has to take in a String and an Integer. The first is the string that the user has typed in to search on, the second (If you choose to use it) is for limiting the number of items back. (This is set by the CompletionSetCount property on the control, more on this later.)
- The second thing is that without any changes to how the control works, you have to send back a list of strings. This could be a deal breaker if you need to send back more information. I think it’s possible to do so, but I haven’t gotten to that point yet.
Ok so let’s create a quick method. My example is using the typical Linq to Sql stuff I’ve been using but I have faith you can figure out how to get some kind of needed information whether it’s LInq to Sql, NHibernate, LLBLGEN, or Stored Procedures…
.... [OperationContract] public String[] GetUserNameList(String prefixText, Int32 count) { String[] userNames; userNames = LinqData.DataClasses.User .GetUserListByLikeName(prefixText) .Select(currentUser => currentUser.UserName) .ToArray(); return userNames; } ....
Now I didn’t use the passed in integer, but I didn’t need it for this situation. As you can see this method, however follows the two rules: Takes in a string and integer and returns a string array.
Now you have the servce set up, next up is the mark up and let me tell you, it’s freakishly hard.
<%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagPrefix="controlkit" %> <asp:ScriptManager ID="smMain" runat="server" /> <asp:TextBox ID="textboxTarget" runat="server" /> <ajax:AutoCompleteExtender ID="autoCompleteMain" runat="server" ServicePath="~/Service/AutocompleteWebControl.svc" ServiceMethod="GetUserNameList" CompletionSetCount="10" MinimumPrefixLength="1" TargetControlID="textboxTarget" />
So there it is. Now you have a working autocomplete. But just in case you need it, I’ll run through this stuff.
ServicePath – This is where the web service is “located” relative to the project.
ServiceMethod – This is the name of the method it will call to fill itself.
CompletionSetCount – This is the other parameter passed into the web method and used if you want to limit the count of items returned.
MinimumPrefixLength – The minimum amount of characters needed to trigger the method call.
TargetControlID – Come on, honestly? You can’t figure that one out?
At this point you’re thinking this is great and all but what if you want to make a composite control? Well that’s the next post and it’s fairly easy.
hi
this is good one..
but related to this i m having one problem..
i want to use AutoCompleteExtender for filtering Country and state
like if some one type in country it will display option from db for country.. that is clear.. i can do it..
but for State.. i have to pass filter of country.. it should display only those states which is part of given country..
so actualy i want to pass country name or id as param in filter of state .. is it possible..
thanks..