AutoComplete.Net

18 06 2011


Suggested Books

.Net Architecting Applications For The Enterprise Patterns of  Enterprise Application Architecture Design Patterns

1. Why AutoComplete.Net?
2. Download
3. Asp.Net Documentation
3.1. AutoCompleteTextBox
3.2. Tutorial
4. Asp.Net MVC Documentation
4.1. Extension Methods
4.2. Tutorial

1. Why AutoComplete.Net?

In this article I will introduce my CodePlex project: AutoComplete.Net.

Such project is made up of a library containing an Asp.Net WebControl and a bunch of Asp.Net MVC HtmlHelper extension methods.
Their purpose is to provide .Net developers with an easy interface to the cool JQuery UI Autocomplete Widget.

I will describe separately the Asp.Net WebControl and the Asp.Net MVC extension methods.

→ top of post

2. Download

Download the latest version of AutoComplete.Net here.
You will get a zip package containing the binary and few other files.
Unzip the release package wherever you want,
e.g. under C:\Program Files\AutoComplete.Net.
For most of the time you will need only the AutoComplete.dll but in the following paragraphs you will be instructed about when you will need the other files included in the release package.

→ top of paragraph
→ top of post

3. Asp.Net Documentation

3.1. AutoCompleteTextBox

The AutoCompleteTextBox WebControl found in the AutoComplete.dll assembly exposes the following properties:

MinCharsRequired

Specifies the minimum number of characters to digit before the autocomplete is fired and the ajax request to the server is started.
The default value is: 2, so you can ignore this property if you feel confortable with such value.

JsonDataSourceUrl

This is the most important property.
Here you must specify an Uri identifying a resource returned in Json format.
The value you will specify will represent the place to retrieve the source data from.
Tipically you will provide the address of an Http Handler.
This is a required property so you have to provide a valid url.
You can safely use the ~ (tilde) character in the url provided.

Example:
JsonDataSourceUrl=”~/CountriesHandler.ashx”

HttpMethod

Specifies the method to be used for the http invocation.
It will be used to instruct JQuery about how to send the underlying ajax invocation.
The legal values are: GET and POST.
If a value is not specified for this property it will default to GET.
I suggest not to use the POST option because the autocomplete widget works invoking an ajax request at each key pressed.
Such an high number of ajax post requests causes Internet Explorer to receive an error 12030 from the server.
I planned to refine the behavior of the control to do some more work on the client, in order to workaround this problem. In the meanwhile GET is the option to go with and also the natural choice when invoking an Http Handler.

LabelField

Specifies the name of a property of the returned object type that will be used to fill the suggestions displaied in the list.
If this property is not set, the value in the property: ValueField will be used as LabelField as well.

ValueField

Specifies the name of a property of the returned object type.
Such property will be used to fill the textbox once one of the items in the suggestions list has been selected.
If a LabelField property is not specified, this property’s value will be used as LabelField value in the autocomplete initialization.
This is a required property.

OnClientSelection

If you need some more client side processing of the data related to the item selected you can use this property to specify the name of a javascript function.
The javascript function specified will be invoked when an item in the list is selected.
You must define the javascript function with the following signature:

function OnClientSelectionHandler(selectedItem)

The argument passed to this function: ‘selectedItem’ is a client side representation of the server side object instance corresponding to the selected item.
In this way you can access all the properties (and then retrieve all available information) about the selected item.
You can, for example, set a hidden field as in the following sample code:

 // set hidden field with the value corresponding to the selected item.
 function OnClientSelectionHandler(selectedItem) {
	 var codeHiddenField = '<%=(FindControl("SelectedCountryHiddenField").ClientID)%>';
	 $('#' + codeHiddenField).val(selectedItem.Code);
	 alert("Code value is: " + $('#' + codeHiddenField).val());
 }

OnClientError

If you want to notify errors happened during the ajax request to the server, you can set this property to specify the name of a javascript function.
The javascript function specified will be invoked when an error occurs during the ajax request.
You must define the javascript function with the following signature:

function NotifyError(error)

The argument ‘error’ passed to this function is a message describing the error happened.

RegisterJQueryAndJQueryUI

Instructs the control wether to emit script tags to include references to jquery.js and to jquery-ui.js.

<script type="text/javascript" src="/Scripts/jQuery-1.4.1.js"></script>
<script type="text/javascript" src="/Scripts/jquery-ui.js"></script>

By setting this property to “true” or “false” you can decide if a reference to the jquery and jquery UI javascript libraries is required or they’re already declared in the page.
The versions bundled with the WebControl are: jquery 1.4.4 and JQuery UI 1.8.7.
The default value is false, so the control won’t work unless you drop it in a page containing the required references or you explicitly set the property as below:

RegisterJQueryAndJQueryUI="true" 

RegisterDefaultStyleSheet

Instructs the control wether to emit a link reference to the default stylesheet for the autocomplete dropdownlist.
The reference will be emitted if this property is set to “true” and it will point to a .css file embedded as resource in the AutoComplete.dll assembly.
The Stylesheet has been built with the Jquery UI ThemeRoller.
If a JQuery UI full theme has already been added to the page, setting this property is not necessary.
Worse it could override the style set at page level.
Default value is true.

If you want to have a look at the style rules applied to the AutoComplete widget you can find, in the release package, the file: jquery-ui.css and have a look.

The style relative to the Autocomplete widget starts at row: 304:

.ui-autocomplete { position: absolute; cursor: default; font: normal 82.5% inherit; }
.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; }

/* workarounds */
* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */

In the rule:

.ui-autocomplete 
{ 
  position: absolute; cursor: default; font: normal 82.5% inherit; 
}

the font style has been added by me in order to have a default style for the item in the dropdownlist of suggestions.

The rule: ‘ui-autocomplete-loading’ has been removed in the stylesheet produced by recent versions of the ThemeRoller because the ThemeRoller itself is not able to produce the required image too.
I modified the stylesheet by restoring this rule, retrieved from a previous version (JQuery UI 1.8.2).
I also added to the package the corresponding image, retrieved from the same version (1.8.2).

If you want to see the spinner image in the textbox you need to place it in a folder named: ‘images’ in the root of the web application.
If you want to place it elsewhere you need to modify the stylesheet rule with the desired file path and rebuild the WebControl.

If you want to customize the stylesheet without recompiling the control, just set the
RegisterDefaultStyleSheet property to “false” and place the jquery-ui.css file you find in the release package wherever you want in the website directory structure, e.g.: {root}\Style.
Then add to the head of the page the following snippet:

<link href="/Style/jquery-ui.css"
	  rel="stylesheet" 
	  type="text/css" />

You can then modify the stylesheet as you like.

NoResultsMessage

If the letters you typed in the textbox led to no results, the textbox will still be empty and no suggestion list will popup.
With this property you can provide an informational message, to be displaied in the autosuggest list in case the ajax request returns an empty resultset, as you can see in the image below:

NoResults Message

Obviously if the user selects the item in the suggestion list, nothing will happen: the TextBox will not be filled with the value and the OnClientSelection handler will not be invoked.

ErrorMessage

This property specifies the text to be displaied in the autosuggest list when an error occurs during the ajax request.
Such property will be used to display an informational message in the suggestions list, in case of error.
The behavior is the same as in the previous property.

→ top of paragraph
→ top of post

3.2. Tutorial

Let’s see how to create an example application to test the AutoCompleteTextBox WebControl for Asp.Net.

First of all create a new Visual Studio Solution and add a new Asp.Net Web Application project.
Download the latest version of AutoComplete.Net and unzip the release package wherever you want.
Browse to the folder in which you unzipped the release package and locate the AutoComplete.dll assembly. Copy and paste it in the folder in which you want your Visual Studio Solution to find it.
You can then place it in a folder common to all projects on the machine (it can be even the same: C:\Program Files\AutoComplete.Net) or in a folder specific to the current solution.
I usually create a Libs folder in the root of the solution and show its contents in Visual Studio by adding a Solution Folder with the same name.

Add a reference to the assembly in your web application project.

Go to the ToolBox and select the Tab in which you want the AutoCompleteTextBox to appear (create a new tab if you want), then select:

Tools –> Choose ToolBox Items…, browse to find the AutoComplete.dll and confirm.

Now you’re ready to drag and drop the AutocCompleteTextBox control.
Go to the Web page in which you want to add the control, e.g.: Default.aspx.
Place the cursor in the exact position in which you want to drop it, go to the ToolBox window and double click the control.

Select control in toolbox

As you can see in the image above you will find the control registered at the top of the page:

<%@ Register Assembly="AutoComplete" Namespace="AutoComplete" TagPrefix="IM" %>

and a control instance declared at the row where you placed the cursor:

<IM:AutoCompleteTextBox ID="AutoCompleteTextBox1" runat="server" 
                        JsonDataSourceUrl=""
                        ValueField="" />

Maybe you need some formatting to see it exactly as above and maybe you want to change the ID (by removing the ‘1’ at the end for example!).

The control instance requires you to provide a value at least for the two properties you find explicitly set in the control declaration: JsonDataSourceUrl and ValueField

If you run the page as is, you will get the following exception:

Required property: JsonDataSourceUrl for: AutoCompleteTextBox1
A value must be provided for the specified property.

You need to provide an url address to a resource returning a result in JSon format, as a value for the property: JsonDataSourceUrl.
Below you will se a simple way to provide such a resource just to test the WebControl.
You can add few simple classes to your web application (remember to add using statements as needed).

First add an IHttpHandler to your project, name it CountriesHandler and replace the ProcessRequest method with the following code:


public void ProcessRequest(HttpContext context)
{
	context.Response.ContentType = "application/json";
	context.Response.ContentEncoding = Encoding.UTF8;
	string startsWith = context.Request["startsWith"];

	CountriesRepository repository = new CountriesRepository();
	IEnumerable<Country> countries = repository.GetCountriesStartingWith(startsWith);

	JavaScriptSerializer serializer = new JavaScriptSerializer();
	context.Response.Write(serializer.Serialize(countries));
}

then add a new class named: Country defined as below:


public class Country : IEquatable<Country>
{
	public Country(RegionInfo region)
	{
		Name = region.EnglishName;
		Code = region.TwoLetterISORegionName;
	}

	public string Name { get; set; }

	public string Code { get; set; }

	#region IEquatable<Country> Members

	public bool Equals(Country other)
	{
		if (ReferenceEquals(other, null)) return false;
		return Code.Equals(other.Code) && Name.Equals(other.Name);
	}

	#endregion

	public override int GetHashCode()
	{
		return Name.GetHashCode() ^ Code.GetHashCode();
	}
}

The IEquatable implementation and the GetHashCode override are needed to avoid duplicate countries in the lists.
Then add another class: CountriesRepository defined as below:


public class CountriesRepository
{
	readonly IEnumerable<Country> countries;

	public CountriesRepository()
	{
		countries = (from culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)
			  select new Country (new RegionInfo(culture.LCID)))
			  .Distinct<Country>()
			  .OrderBy(n => n.Name);
	}

	public IEnumerable<Country> GetCountriesStartingWith(string startsWith)
	{
		var result = from country in this.countries
			  where country.Name.StartsWith(startsWith, StringComparison.InvariantCultureIgnoreCase)
			  select country;
		return result;
	}
}

Now you can set the first property as follows:
JsonDataSourceUrl=”~/CountriesHandler.ashx”

If you run your application you still get an exception because the ValueField property is required too:

Required property: ValueField for: AutoCompleteTextBox1
A value must be provided for the specified property.

By setting such property you tell the control wich property of the object returned will be used to fill the autosuggest list.
Set the property as below:

ValueField=”Name”

Now the control is configured correctly and the page will load but you will get an alert, warning you that you forgot to add a reference to the JQuery library:

Jquery not loaded alert

Now you have to made a choice: you can tell the WebControl to provide by itself a reference to the required javascript libraries (Jquery and JQueryUI) or to rely on the page in which it’s contained to include references to the right javascript libraries.

If you want to use the control in a page in which you already use JQuery for other purposes you will have your reference right in place in the head of the page:


<head runat="server">
    <title></title>
    <script type="text/javascript" src="/Scripts/jQuery-1.4.1.js"></script>
    <script type="text/javascript" src="/Scripts/jquery-ui.js"></script>
</head>

If this is not the case you can simply set another property of AutoCompleteTextBox:

RegisterJQueryAndJQueryUI=”true”

You’re ready to use your Page.
Just type ‘in’ in the textbox and you will get a list of country names starting with ‘in’.
If you type few random letters, say: ‘ee’ you won’t see any result.
If you prefer to be prompted with a message you can set the following property:

NoResultsMessage = “No results”

Still you miss a pretty aesthetic functionality: you can have a loading image spinning inside the textbox while waiting that the information is retrieved.
The WebControl already looks for such image. You only need to provide it in a path in which the control can find it.
In the folder in which you unzipped the release package you can find the file:

ui-anim_basic_16x16.gif

In your Visual Studio Solution add a folder named: Images to the web application root folder and place the gif file inside it. That’s it!
Reload the page, type ‘un’ and you will see the spinner for a while before the results are presented.

If you want to place the spinner image elsewhere, for instance if you already have an images folder but with a different name, you can modify the default stylesheet as explained in the paragraph: RegisterDefaultStyleSheet.

You must download the source of the project, open the stylesheet jquery-ui.css, go to row: 305:

.ui-autocomplete-loading 
{ 
   background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; 
}

and replace the relative path in the url with the path you want.

If you want to customize the stylesheet without recompiling the control, just set the
RegisterDefaultStyleSheet property to “false” and place the jquery-ui.css file you find in the release package wherever you want in the website directory structure, e.g.: {root}\Style.
Then add to the head of the page the following snippet:

<link href="/Style/jquery-ui.css"
	  rel="stylesheet" 
	  type="text/css" />

You can then modify the stylesheet as before.

By default the WebControl adds a reference to the default autocomplete stylesheet jquery-ui.css we saw above.
The stylesheet has been built with the Jquery UI ThemeRoller.
If a theme has already been added to the page, the WebControl’s default theme is not necessary and could override the style defined in the page.
In this case you should disable the default stylesheet by setting the following property as below:

RegisterDefaultStyleSheet=”false”

After the user selects the chosen item in the list of suggestions, you can do whatever you want with all the data available about the selected item.
In this case you have ‘Code’ and ‘Name’ of the selected Country.
Say you want to save the ‘Code’ in a hiddenfield in order to send it to the server during the next submit/postback.
You can write your own javascript function and the AutoCompleteTextBox will provide the function with the information about the selected country.
Just set the following property:

OnClientSelection=”SaveCodeForLaterUse”

add the following hidden field inside the form tag:

<asp:HiddenField ID="SelectedCountryHiddenField" runat="server" />

and add the following block of javascript immediately after the opening tag of the form element of the page:


<script type="text/javascript">
//<![CDATA[

// set hidden field with the value corresponding to the selected item.
function SaveCodeForLaterUse(selectedItem) {
    var codeHiddenField = '<%=(FindControl("SelectedCountryHiddenField").ClientID)%>';
    $('#' + codeHiddenField).val(selectedItem.Code);
    alert("Code value is: " + $('#' + codeHiddenField).val());
}

//]]>
</script>

The argument passed to the javascript function (selectedItem) represents an instance of a Country object and exposes the same properties as its server side counterpart: Name and Code.

The full declaration now is:

<IM:AutoCompleteTextBox ID="CountriesAutoCompleteTextBox" runat="server" 
			JsonDataSourceUrl="~/CountriesHandler.ashx"
			ValueField="Name" 
			RegisterJQueryAndJQueryUI="true" 
			NoResultsMessage = "No results"
			OnClientSelection="SaveCodeForLaterUse" />

Note:
If you place the above script in the head section, the control (and the page as well) won’t be able to manipulate the head anymore because the page header is readonly when there are codeblocks inside it.
The control needs to manipulate the header to add the default stylesheet.
If you don’t mind about it or if you are willing to add the stylesheet by yourself you can safely place your script in the page head section.
If you won’t use code blocks in your javascript function you can place the script in the page header as well.

→ top of paragraph
→ top of post

4. Asp.Net MVC Documentation

4.1. Extension Methods

WORK IN PROGRESS

→ top of paragraph
→ top of post

4.2. Tutorial

Let’s see how to create an example application to test the Asp.Net Mvc AutoComplete Extensions.

First of all create a new Visual Studio Solution and add a new Asp.Net Mvc Web Application project.

Download the latest version of AutoComplete.Net and unzip the release package wherever you want.
Browse to the folder in which you unzipped the release package and locate the AutoComplete.dll assembly. Copy and paste it in the folder in which you want your Visual Studio Solution to find it.
You can then place it in a folder common to all projects on the machine (it can be even the same: C:\Program Files\AutoComplete.Net) or in a folder specific to the current solution.
I usually create a Libs folder in the root of the solution and show its contents in Visual Studio by adding a Solution Folder with the same name.

Add a reference to the assembly in your Asp.net Mvc Web Application project.

First of all make some room in our new project: delete the controllers and model classes created by the project template:

AccountController.cs and HomeController.cs under the folder: Controllers
AccountModels.cs under the folder: Models
folders: Account and Home under the folder: Views
Remove the content of the Shared folder under the folder: Views

Create a folder named: Countries under the folder: Views, right click it and choose: Add… –> View.
Name it: Search and uncheck: ‘Select master page’.

A new page: Search.aspx will open.
Now you can add the markup for the AutoComplete control inside the main div of the page (together with a label):


<label for="country">Country:</label>

<%= Html.AutoCompleteTextBox("country", 
			     new Uri("/Countries/SearchByFirstLetters", UriKind.RelativeOrAbsolute), 
			     "Name") %>

Visual Studio will warn you that it cannot find the AutoCompleteTextBox extension method.
You need to instruct it about the namespace.
You can do it once for all in the web.config of the application:
Just open it and add:

<add namespace="AutoComplete"/>

to the namespaces in the tag:

<system.web>
    <pages>
        <namespaces>

or you can do it page by page using the import directive at the top of the page:

<%@ Import Namespace="AutoComplete" %>

In each case just rebuild the project and the Visual Studio error message will disappear.

The first argument we passed to the AutoCompleteTextBox extension method (“country”) will be the id of the html input field.
The second argument is the uri of the resource that will be invoked and the third argument is the name of the property to be used, of the objects returned by the uri resource, to populate the suggestions list.

The uri: “/Countries/SearchByFirstLetters” invoked in an Asp.Net MVC Web Application with the default routes in place will cause a controller named: CountriesController to be searched for.
Let’s add such a controller in the folder Controllers.
Let’s add to the controller the method that will be invoked when our view is loaded.
The method, by convention, will be called: Search and we will replaced it to the method: Index created by the controller template.
Here is the first method of our newly created controller:

//
// GET: /Countries/Search/

public ActionResult Search()
{
	return View();
}

if you now type the url: Countries/Search you will get the following javascript alert:

Autocomplete missing Message

In fact we still didn’t add the required javascript references in the head of the page.
We need a reference to JQuery, a reference to JQueryUI and a reference to the IM.AutoComplete.js javascript library.
Go to the folder in which you unzipped the release package and locate the following files:
jquery-ui.js
IM.AutoComplete.js

Copy and paste the 2 files in the Scripts folder of your project and add the following references to the head of the Search.aspx view:

<script type="text/javascript" src="/Scripts/jQuery-1.4.1.js"></script>
<script type="text/javascript" src="/Scripts/jquery-ui.js"></script>
<script type="text/javascript" src="/Scripts/IM.AutoComplete.js"></script>

Still the autocomplete functionality won’t work unless we add to the controller a SearchByFirstLetters method returning a JsonResult, representing the required resource.
Below you will see a simple way to provide such a resource just to test the Extension method.
You need to add a couple of simple classes to your Asp.Net Mvc Web Application.
First add a method named SearchByFirstLetters to your controller:

public ActionResult SearchByFirstLetters(string startsWith)
{
	if (!Request.IsAjaxRequest())
	{
		return Content(string.Empty);
	}

	CountriesRepository repository = new CountriesRepository();
	IEnumerable<Country> countries = repository.GetCountriesStartingWith(startsWith);
	return Json(countries.ToList(), JsonRequestBehavior.AllowGet);
}

Note:
we’re allowing the SearchByFirstLetters method to be invoked by e GET request because
internet explorer randomly causes HTTP errors when sending too many post requests to a server.

Now add the following two classes to the: Models folder.

public class Country : IEquatable<Country>
{
	/// <summary>
	/// Needed by Asp.Net Mvc framework.
	/// </summary>
	public Country()
	{

	}
	
	public Country(RegionInfo region)
	{
		Name = region.EnglishName;
		Code = region.TwoLetterISORegionName;
	}

	public string Name { get; set; }

	public string Code { get; set; }

	#region IEquatable<Country> Members

	public bool Equals(Country other)
	{
		if (ReferenceEquals(other, null)) return false;
		return Code.Equals(other.Code) && Name.Equals(other.Name);
	}

	#endregion

	public override int GetHashCode()
	{
		return Name.GetHashCode() ^ Code.GetHashCode();
	}
}

The IEquatable implementation and the GetHashCode override are needed to avoid duplicate countries in the lists.
Then add another class: CountriesRepository defined as below:

public class CountriesRepository
{
	readonly IEnumerable<Country> countries;

	public CountriesRepository()
	{
		countries = (from culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)
			    select new Country (new RegionInfo(culture.LCID)))
			    .Distinct<Country>()
			    .OrderBy(n => n.Name);
	}

	public IEnumerable<Country> GetCountriesStartingWith(string startsWith)
	{
		var result = from country in this.countries
			    where country.Name.StartsWith(startsWith, StringComparison.InvariantCultureIgnoreCase)
			    select country;
		return result;
	}
}

Now you can run the web site and type the url: Countries/Search.
You will get the page and can type the first 2 letters of a country to get suggestions.

Still the suggestions list is not very stylish. We forgot to add our default style sheet that was generated with the Jquery UI ThemeRoller (if you read the Asp.Net tutorial you know that the AutoCompleteTextBox WebControl added the reference by itself).
Go to the folder in which you unzipped the release package and locate the file:
jquery-ui.css

Copy and paste it in the Content folder of your project and add the following reference to the head of the Search.aspx view:

<link href="/Content/jquery-ui.css"
	  rel="stylesheet" 
	  type="text/css" />

If a theme has already been added to the page, this default theme is not necessary and could accidentally override the style defined in the page.

You can also have a loading image spinning inside the textbox while waiting for the information to be retrieved.
In the release package you can find the file:

ui-anim_basic_16x16.gif

In your Visual Studio Solution add a folder named: Images under the Content folder and place the gif inside it.
That’s it!
Reload the page, type ‘un’ and you will see the spinner for a while before the results are presented.

If you want to place the spinner image elsewhere, for instance if you already have an images folder but with a different name, you can modify the default stylesheet as explained in the ASP.NET WebControl section at the paragraph: RegisterDefaultStyleSheet.

You must modify the stylesheet file found in the release package: jquery-ui.css. Open the file and go to row: 305:

.ui-autocomplete-loading 
{ 
   background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; 
}

then replace the relative path in the url with the path you want.

There’s plenty of overloads to the AutoCompleteTextBox extension method we used but there’s another and more notable series of extension methods: the strongly typed ones, named: AutoCompleteTextBoxFor.

Let’s add another View under the Countries folder and call it: StronglyTypedSearch,
check the ‘Create a strongly-typed view’ checkbox and select:
AspNetMvcAutoComplete.Models.Country as ‘View data class’,
select the ‘Edit’ ‘View content’ and
uncheck the ‘Select master page’ checkbox.

Remove the fields related to the Code property and the Actionlink at the bottom of the page.
Replace:

<%= Html.TextBoxFor(model => model.Name) %>

with:

<%= Html.AutoCompleteTextBoxFor(model => model.Name, 
				new Uri("/Countries/SearchByFirstLetters", UriKind.RelativeOrAbsolute)) %>

and place the label in the same div as the textbox.
Add to the head of the page the same references as in the Search.aspx view:

<script type="text/javascript" src="/Scripts/jQuery-1.4.1.js"></script>
<script type="text/javascript" src="/Scripts/jquery-ui.js"></script>
<script type="text/javascript" src="/Scripts/IM.AutoComplete.js"></script>
<link href="/Content/jquery-ui.css"
	  rel="stylesheet" 
	  type="text/css" />

The page will now look like the following:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<AspNetMvcAutoComplete.Models.Country>" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>StronglyTypedSearch</title>
    <script type="text/javascript" src="/Scripts/jQuery-1.4.1.js"></script>
    <script type="text/javascript" src="/Scripts/jquery-ui.js"></script>
    <script type="text/javascript" src="/Scripts/IM.AutoComplete.js"></script>
    <link href="/Content/jquery-ui.css"
          rel="stylesheet" 
          type="text/css" />
</head>
<body>
<% using (Html.BeginForm()) {%>
	<%= Html.ValidationSummary(true) %>
	
	<fieldset>
		<legend>Fields</legend>
		
		<div>
			<%= Html.LabelFor(model => model.Name) %>            
			<%= Html.AutoCompleteTextBoxFor(model => model.Name, 
							new Uri("/Countries/SearchByFirstLetters", UriKind.RelativeOrAbsolute)) %>                
			<%= Html.ValidationMessageFor(model => model.Name) %>
		</div>
		
		<p>
			<input type="submit" value="Save" />
		</p>
	</fieldset>

<% } %>
</body>
</html>

Add the DisplayNameAttribute to the Name property of the Country class if you want a meaningful label, e.g.:

[DisplayNameAttribute("Country:")] 
public string Name { get; set; }

Add a method named StronglyTypedSearch to the controller (CountriesController):

public ActionResult StronglyTypedSearch()
{
	return View();
}

so that it will be invoked when typing the url: ‘Countries/StronglyTypedSearch’.

If you add the following method to the controller, to manage the submit of the page, you will be able to debug and see the selected value sent back to the server:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult StronglyTypedSearch(Country country)
{
	return View(country);
}

Now just run the website and type the above url.
Type few letters in the textbox and select a country.
Place a breakpoint in the method above and hit the save button.
You can now watch the argument passed to the method and notice that the Name property is correctly set based on your selection.

You can download the full sample code: AutoCompleteNetExamples Source Code at the project home page.

→ top of paragraph
→ top of post

Advertisements







%d bloggers like this: