See my question here jQuery, autocomplete using json, id and display values
We actually โborrowedโ (read the copy and pasted) SO autofill javascript, and then slightly changed it - for example, renamed it so that it would not interfere with jquery ui autocomplet e.
Both are actually very similar, but we wanted to specifically have a tag system like SO.
you can use the code that i used http://pastebin.com/t29RCCZg
and here is an example of the action we used for tags
public ActionResult ProfileTags(string prefix, int? limit) { if (!limit.HasValue) limit = ConfigurationHelper.Paging.TagList; if (String.IsNullOrEmpty(prefix)) prefix = String.Empty; ProfileTagModel model = new ProfileTagModel() { Tags = profileTagRepository.GetList(new ProfileTagsByPrefixQuery(prefix)).OrderBy(x => x.Name).Take<ProfileTag>(limit.Value) }; return View(model); }
And the view looks like this:
<%@ Page Language="C#" ContentType="text/html" Inherits="System.Web.Mvc.ViewPage<ProfileTagModel>" %> <% if(Model.Tags != null) { %> <% foreach (ProfileTag tag in Model.Tags) { %> <%= tag.Name + ((tag.ProfileCount > 0) ? " (" + tag.ProfileCount.ToString() + ")" : String.Empty) %> <% } %> <% } %>
And then our use on the page looks something like this.
$().ready(function () { $("#ProfileTags").troppinautocomplete('<%= Url.Action("ProfileTags", "Filter") %>', { max: 10, highlightItem: true, multiple: true, multipleSeparator: " ", matchContains: false, scroll: true, scrollHeight: 300, dataType: "html" }); })
You donโt have to do this. You can force the action method to return an array of objects as json, and then by changing the way your autocomplete is declared, you can actually format the tags for display using the icon or other functions.
Here is an example that json took for formatted view
$('#troppinSearch').troppinautocomplete(url, { dataType: 'json', parse: function (data) { var rows = new Array(); if (data != null) { for (var i = 0; i < data.length; i++) { rows[i] = { data: data[i], value: data[i].Id, result: data[i].Title }; } } return rows; }, formatItem: function (row, i, n) { return '<table><tr><td valign="top"><img height="28" width="28" src="' + row.ImageUrl + '" /></td><td valign="top" style="padding:0px 0px 0px 6px;"><div>' + row.Title + '</div><div><small>' + row.ResultType + '</small></div></td></tr></table>'; }, formatResult: function (row, i, n) { return row.Id; }, width: 336, max: 20, highlightItem: true, multiple: false, matchContains: true, scroll: true, scrollHeight: 300 }).result(function (event, data, formatted) { var type = data.ResultType.toLowerCase(); var id = data.Id; if (type == "product") { window.location.href = '/Shop/Product/' + id; } else { window.location.href = '/Profile/Index/' + id; } });
And the action looks like this:
public ActionResult Search(string contentType, string prefix, int? limit) { if (!limit.HasValue) limit = ConfigurationHelper.Paging.ProfileList; SearchResponse response = GetSearchResults(contentType, prefix); var dropDownResults = (from r in response.Results select new { Id = r.Id, Title = r.Name, ImageUrl = r.DefaultImage, ResultType = r.ResultType.ToString() }).Distinct().Take(limit.Value); return Json(dropDownResults.ToList(), JsonRequestBehavior.AllowGet); }
When you do this, you do not need a view. Autostart takes json data and does everything magically. The .Result function at the end allows you to customize the event that occurs when selected. in this case, it actually sends the user to another page, but we used it to set the value in a hidden field.
EDIT
I forgot the built-in CSS classes for this code. Here is an example of CSS.
.ac_results{ padding:0; border:1px solid #4c4c4c; background-color:#ffffff; overflow:hidden; z-index:99999; text-align:left; font-size: 14px; line-height:14px; color: #333333; } .ac_highlight{ font-weight:bold; text-decoration:underline; background-color: #ff6600; color: #ffffff; } .ac_results ul{ width:100%; list-style-position:outside; list-style:none; padding:0; margin:0; } .ac_results li{ margin:0; padding:3px 6px 3px 6px; cursor:default; display:block; line-height:14px; overflow:hidden; } .ac_loading{ background:#fff url(/Content/images/loading.gif) right center no-repeat; } .ac_over{ background-color:#ff6600; color:#ffffff; }