Friday, October 7, 2011

Auto Complete in Razor MVC with JQuery and LINQ to Entities

I had to create an auto-complete text box this week in Razor and didn’t see anything specific to doing it in Razor so I thought I’d throw this out there. I would like to say this post for getting it to work in MVC was very helpful and it didn’t take much effort to move from that to Razor and the Entity Framework.
In my example below I’ll be auto populating the product name based on the existing product names in the database using LINQ to Entities.
Step 1 : Download the JQuery Auto-Complete Library from google code
http://code.google.com/p/jquery-autocomplete/downloads/list
Step 2: Extract the following files into your scripts directory
jquery.autocomplete.js
jquery.autocomplete.css
indicator.gif
You can move them around later but for now lets keep them all in one folder and modify the css file to point to our new location for the loading gif.
background : url(‘/scripts/indicator.gif’) right center no-repeat;
Step 3 : Build your controller class
I’m selecting the top 10, distinct where the product name contains the typed in text.
01using System;
02using System.Collections.Generic;
03using System.Linq;
04using System.Web;
05using System.Web.Mvc;
06using MyNameSpace.Models;
07 
08namespace MyNameSpace.Controllers
09{
10    public class AutoCompleteController : Controller
11    {
12        MyNameSpaceEntities mhgDb = new MyNameSpaceEntities();
13 
14        public ActionResult ProductName(string q)
15        {
16            var productNames = (from p in mhgDb.Products where p.ProductName.Contains(q) select p.ProductName).Distinct().Take(10);
17 
18            string content = string.Join<string>("\n", productNames);
19            return Content(content);
20        }
21 
22    }
23}
Step 4:  Add the JS and CSS files to your view
1<script src="@Url.Content("~/Scripts/jquery.autocomplete.js")" type="text/javascript"></script>
2<link href="@Url.Content("~/Scripts/jquery.autocomplete.css")" rel="stylesheet" type="text/css" />
Step 5 : Bind the Textbox to the Controller

01<div class="editor-label">
02@Html.LabelFor(model => model.ProductName)
03</div>
04<div class="editor-field">
05@Html.EditorFor(model => model.ProductName)
06@Html.ValidationMessageFor(model => model.ProductName)
07</div>
08 
09<script type="text/javascript">
10 
11$(document).ready(function () {
12$("#ProductName").autocomplete('@Url.Action("ProductName", "AutoComplete")', { minChars: 3 });
13});
14 
15</script>
Step 6 : Build and Test
That’s all, there’s some tips around styling and parameters for autocomplete in the link to the other blog post I linked to above. I’d be interested in seeing a better LINQ statement if anyone has one.