Introduction
This tip describes how to implement autocomplete text feature using JQuery, JSON in .NET MVC application.
Background
Some basic knowledge of Razor syntax, JQuery call and MVC controller, Entity Framework to get data from database
The Basics
The basic idea is to pass a JSON array of strings and it will display as autocomplete which matched to the input term.
<script src="~/Scripts/jquery-2.0.3.js"></script>
<script src="~/Scripts/jquery-2.0.3.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var states = [ "Alabama", "Arkansa", "California", "Colorado",
"Illinois", "Indiana", "Iowa" ];
$("#autocomplete").autocomplete({
source: function (request, response) {
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(states, function (item) {
return matcher.test(item);
}));
}
});
});
</script>
The output for the above code will be as below.
-------------If you have tried the above code output action seems like below----------
Using the Code
Here my intention is to dynamically generate autocomplete feature for a textbox which will get the JSON objects from Action
method within the Controller. I am going to use multiple ‘Action
’ methods for user selection criteria to bind autocomplete feature for a textbox.
I have added a dropdown list control for search criteria and a textbox to bind/ attach autocomplete feature dynamically by selection criteria.
Initially, I am extending the above code for dynamic autocomplete feature.
By selecting the above dropdown list item, an autocomplete feature will bind to the textbox. If I select ‘Name’ in dropdown list, my JQuery function makes a request to ‘AutocompleteName
’ method, then it will attach autocomplete feature for ‘Name
’. If I select ‘State
’ in dropdown list, then autocomplete will populate state name result and by selecting ‘Country
’ then it will populate a country names in autocomplete by entering a term.
Here is my razor code:
@Html.DropDownList("SearchBy", new SelectList(ViewBag.SearchBy, "Value", "Text"),
"--Search By--", new { onchange = "bindfeature(this.options[this.selectedIndex].value);" })
@Html.TextBox("Term")
In the above code you can see dropdownlist, I have bind list items which are stored in ViewBag.SearchBy
here textbox id ‘Term
’ and ViewBag.Term
should be the same. So that I will get those values in Post
method of controller.
JQuery:
<script src="~/Scripts/jquery-2.0.3.js"></script>
<script src="~/Scripts/jquery-2.0.3.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
bindfeature = function (id) {
$("#Term").focus();
var ul = "";
if (id == '1') { ul = '@Url.Action("AutocompleteName", "Search")';
$("#Term").attr("placeholder", "Family Name"); }
if (id == '2') { ul = '@Url.Action("AutocompleteMemberID", "Search")';
$("#Term").attr("placeholder", "Member ID");}
if (id == '3') { ul = '@Url.Action("AutocompleteEmail", "Search")';
$("#Term").attr("placeholder", "Email");}
if (id == '4') { ul = '@Url.Action("AutocompleteCountry", "Search")';
$("#Term").attr("placeholder", "Country");}
if (id == '5') { ul = '@Url.Action("AutocompleteState", "Search")';
$("#Term").attr("placeholder", "State");}
if (id == '6') { ul = '@Url.Action("AutocompletePhone", "Search")';
$("#Term").attr("placeholder", "Phone");}
if (id == '7') { ul = '@Url.Action("AutocompleteStudentID", "Search")';
$("#Term").attr("placeholder", "Student ID");}
if (id == '8') { ul = '@Url.Action("AutocompleteSchoolYear", "Search")';
$("#Term").attr("placeholder", "School Year");}
if (id == '9') { ul = '@Url.Action("AutocompleteSSN", "Search")';
$("#Term").attr("placeholder", "S S N");}
if (id == '10') { ul = '@Url.Action("AutocompleteGrade", "Search")';
$("#Term").attr("placeholder", "Grade Level");}
if (id == '11') { ul = '@Url.Action("AutocompleteEnrollPlan", "Search")';
$("#Term").attr("placeholder", "Enroll Plan");}
var tags = [];
$.get(ul, function (responseText) {
$.each(responseText, function (key, value) { tags[key] = value.label; });
});
$("#Term").autocomplete({
source: function (request, response) {
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(tags, function (item) {
return matcher.test(item);
}));
}
});
}
});
</script>
In the above script, assigning url
to the ‘ul
’ variable based on user dropdown list item selected.$.get
will send the request to the specified URL and will give response as string
, added the responded string
to the ‘tags
’ array variable.
Action Method in Controller
public class SearchController : Controller
{
private Uow db = new Uow();
#region Member Search
[HttpGet]
public ActionResult MemberSearch()
{
List<SelectListItem> sli = new List<SelectListItem>()
{
new SelectListItem(){Text="Name",Value="1"},
new SelectListItem(){Text="Member ID",Value="2"},
new SelectListItem(){Text="Email Address",Value="3"},
new SelectListItem(){Text="Country",Value="4"},
new SelectListItem(){Text="State",Value="5"},
new SelectListItem(){Text="Phone",Value="6"},
new SelectListItem(){Text="Student ID",Value="7"},
new SelectListItem(){Text="School Year",Value="8"},
new SelectListItem(){Text="SSN",Value="9"},
new SelectListItem(){Text="Grade",Value="10"},
new SelectListItem(){Text="Enroll Plan",Value="11"},
};
ViewBag.SearchBy = new SelectList(sli.ToList(), "Value", "Text", "--");
ViewBag.Term = "";
return View();
}
[HttpPost]
public ActionResult MemberSearch(string SearchBy, string Term)
{
List<SelectListItem> sli = new List<SelectListItem>()
{
new SelectListItem(){Text="Name",Value="1"},
new SelectListItem(){Text="Member ID",Value="2"},
new SelectListItem(){Text="Email Address",Value="3"},
new SelectListItem(){Text="Country",Value="4"},
new SelectListItem(){Text="State",Value="5"},
new SelectListItem(){Text="Phone",Value="6"},
new SelectListItem(){Text="Student ID",Value="7"},
new SelectListItem(){Text="School Year",Value="8"},
new SelectListItem(){Text="SSN",Value="9"},
new SelectListItem(){Text="Grade",Value="10"},
new SelectListItem(){Text="Enroll Plan",Value="11"},
};
ViewBag.SearchBy = sli.ToList();
//do some thing here with SearchBy, Term value
return View();
}
#region Auto Complete
public JsonResult AutocompleteName()
{
var model = db.FamilyRepository.GetAll()
.Select(r => new { label = r.FamilyName });
return Json(model, JsonRequestBehavior.AllowGet);
}
public JsonResult AutocompleteMemberID()
{
var model = db.MemberRepository.GetAll()
.Select(r => new { label = r.MemberID });
return Json(model, JsonRequestBehavior.AllowGet);
}
public JsonResult AutocompleteEmail()
{
var model = db.UserProfiles.GetAll()
.Select(r => new { label = r.Email });
return Json(model, JsonRequestBehavior.AllowGet);
}
#endregion
#endregion
Final output seems like this.
Dynamic autocomplete feature for ‘Name
’.
Dynamic autocomplete feature for ‘Email
’.
Points of Interest
In this way, you can avoid multiple JQuery calls for each letter typed in textbox, so that burden will be reduced on database and server.
Here the dropdown list selected item will be sent to the server as request, but not the entered text in textbox so that server will return all the results based on dropdown list selected (Ex:Email Address not only ‘S’ related words).In the above example, all the Email address will be returned from the server and we will store them in array and sort them and we will also use regular expressions.
This means collecting response by dropdown list item selection then storing in array and using regular expression then showing as autocomplete.