.Net ramblings
# Wednesday, 29 November 2006
Problems with the AJAX AutoCompleteExtender (arrgh)
I was interested to see that Atlas/AJAX has now made it to Beta 2.  I looked at it earlier in the year but didn't have time to really get stuck in.  So today i eventually got it working in conjunction with LINQ.  I wanted to get a basic AutoComplete thing working off my database, with which i am hopefully going to use LINQ throughout.

First of all, go to http://ajax.asp.net/ and download and install the 3 bits they recommend. 

Getting the darn thing to work

Brad Adams has a very good getting-started example on this post, i used his article as a starting point, but i had to sort out a few other things first.  i couldn't get any documentation on the AutoCompleteExtender so i scavenged some crucial facts off the net after a lot of fumbling around, i've listed these below.  One mistake i made was to start testing the AutoComplete control before making sure that the web service was returning correct data, my LINQ query was chucking exceptions and the AJAX control doesn't give you any feedback on exceptions, which is understandable and probably desirable.
  • you must mark your web service class with the [ScriptService] attribute, you'll need the Microsoft.Web.Script.Services namespace for this.
    [WebService(Namespace = "http://whatever")]
    public class AjaxService : System.Web.Services.WebService
  • you need two parameters in your web service method, the naming of the parameters is crucial:
    public string[] GetList(string prefixText, int count)
  • if you're using Linq, and if you're new at it like me, you might have trouble getting your LINQ query results into a string array for the web service.  I tried returning IEnumerable<TableName> and List<string> etc. but it didn't like that, i ended up using the ToArray() extended method that is part of System.Query.  Here is the query i used which concatenates some columns from the table into a collection of strings. 
    IEnumerable<string> ds =
                from r in MyDataBase.Restaurants
                where r.RestaurantName.Contains(prefixText)
                select (r.RestaurantName + "," + r.Address1 + "," + r.County); // join the name + address in a string
    string[] results = ds.ToArray<string>();
    return results;

Formatting the AutoCompleteExtender

The control has some nasty hard-coded values, but where there's a will there's a way.  Thanks to the Firefox dom inspector and the CSS !important modifier, all is not lost. 

The control does have a property called CompletionListElementID which specifies the container element where the results are inserted.  I put a simple DIV next to the textbox:
<div id="AutoComplete" runat="server"> </div>
Then in my stylesheet i have the following values to override the hard-coded styles set by the control:
    width: auto !important;   
    overflow: visible !important;
#AutoComplete div
    font-size: x-small !important;   
In case you're wondering, the control renders each result as a DIV inside your specified element.  The control applies the following styles to your specified element:
border: 1px solid buttonshadow; 
overflow: hidden;
visibility: visible;
background-color: window;
color: windowtext;
cursor: default;
width: 130px;
position: absolute;
left: 184px;
top: 27px;
display: inline;

You can override whichever ones you want by applying the !important attribute inside the #AutoComplete entry in the style sheet.  The individual items then can also be styled via the #AutoComplete div entry, i prefered a slightly smaller font size because the default setting looked too big.

Wednesday, 29 November 2006 16:54:25 (GMT Standard Time, UTC+00:00)  #    Comments [4]  Asp.Net