There are alternate ways to implement autocomplete dropdown/textbox component in your Website. One option is to implement Chosen: A jQuery Plugin by Harvest to Tame Unwieldy Select Boxes
For this, you need to bind the dropdownlist in a similar way; it is done and configured when choosing a plugin over the dropdownlist control. Here is a sample auto complete dropdownlist, using chosen plugin. It also allows you to give selected items on Postbacks on the code at the back-end.
- <!DOCTYPE html>
-
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- <link href="Content/chosen.min.css" rel="stylesheet" />
- <script src="Scripts/jquery-1.12.4.min.js"></script>
- <script src="Scripts/chosen.jquery.min.js"></script>
- <script type="text/javascript">
- $(document).ready(function () {
- InitDropDown();
- })
-
- function InitDropDown() {
- var config = {
- '.ChosenSelector': { allow_single_deselect: true, search_contains: true, width: "350px" },
- }
- for (var selector in config) {
- $(selector).chosen(config[selector]);
- }
- }
- </script>
- </head>
- <body>
- <form id="form1" runat="server">
- <asp:DropDownList
- runat="server"
- ID="ddlDropDown"
- DataTextField="EmpName"
- DataValueField="EmpId"
- CssClass="ChosenSelector"
- data-placeholder="Select Employee"
- AppendDataBoundItems="true">
- <asp:ListItem Text="" Value="-1"></asp:ListItem>
- </asp:DropDownList>
- </form>
- </body>
- </html>
The code is given at the back-end to bind dropdownlist.
- protected void Page_Load(object sender, EventArgs e)
- {
- if (!IsPostBack)
- {
- BindDropdown();
- }
- }
-
-
- private void BindDropdown()
- {
- DataTable dtAutoCompleteSrc = GetSampleData();
- ddlDropDown.DataSource = dtAutoCompleteSrc;
- ddlDropDown.DataBind();
- }
-
-
- private DataTable GetSampleData()
- {
- DataTable dtAutoCompleteSrc = new DataTable();
- dtAutoCompleteSrc.Columns.Add(new DataColumn("EmpId"));
- dtAutoCompleteSrc.Columns.Add(new DataColumn("EmpName"));
- for (int i = 0; i < 10; i++)
- {
- DataRow dr = dtAutoCompleteSrc.NewRow();
- dr["EmpId"] = i + 1;
- dr["EmpName"] = "EmpName " + (i + 1).ToString();
- dtAutoCompleteSrc.Rows.Add(dr);
- }
- return dtAutoCompleteSrc;
- }
The output is given below.
However, this would not be a pure auto complete dropdownlist, since we are actually binding all dropdown values at once and the items are not coming on demand.
Another alternative is to implement Bootstrap autocomplete, which is also called "typeahead". This one can be an actual autocomplete, which fetches the data from WebMethod/API based on what the user has requested by typing in TextBox. To implement, you will need to reference Bootstrap related CSS, scripts and write WebMethod to fetch the data upon the user request as they type. Here is a sample code on a similar scenario. Notice that once you select any element, you will be able to get the ID of the selected item in an HiddenField in an updater function:
- <!DOCTYPE html>
-
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- <script src="Scripts/jquery-1.12.4.min.js"></script>
- <link href="Content/bootstrap.min.css" rel="stylesheet" />
- <link href="Content/bootstrap-theme.min.css" rel="stylesheet" />
- <script src="Scripts/bootstrap.min.js"></script>
- <script type="text/javascript" src="http://cdn.rawgit.com/bassjobsen/Bootstrap-3-Typeahead/master/bootstrap3-typeahead.min.js"></script>
- <script type="text/javascript">
- $(document).ready(function () {
- $('#txtEmp').typeahead({
- hint: true,
- highlight: true,
- minLength: 1,
- source: function (request, response) {
- $.ajax({
- url: '<%=ResolveUrl("~/WebForm68.aspx/GetEmployeeDataSample") %>',
- data: "{ 'SearchParam': '" + request + "'}",
- dataType: "json",
- type: "POST",
- contentType: "application/json; charset=utf-8",
- success: function (data) {
- items = [];
- map = {};
- $.each(data.d, function (i, item) {
- var id = item.split('-')[0];
- var name = item.split('-')[1];
- map[name] = { id: id, name: name };
- items.push(name);
- });
- response(items);
- $(".dropdown-menu").css("height", "auto");
- $(".dropdown-menu").css("width", "400");
- },
- error: function (response) {
- console.log(response.responseText);
- },
- failure: function (response) {
- console.log(response.responseText);
- }
- });
- },
- updater: function (item) {
- $('#hdnEmpId').val(map[item].id);
- return item;
- }
- });
- });
- </script>
- </head>
- <body>
- <form id="form1" runat="server">
- <asp:TextBox
- runat="server"
- ID="txtEmp"
- CssClass="form-control"
- AutoCompleteType="Disabled"
- ClientIDMode="Static"
- Width="400" />
- <asp:HiddenField
- runat="server"
- ClientIDMode="Static"
- ID="hdnEmpId" />
- </form>
- </body>
- </html>
Code at the back-end
- public partial class WebForm68 : System.Web.UI.Page
- {
- protected void Page_Load(object sender, EventArgs e)
- {
-
- }
-
-
- [WebMethod]
- public static string[] GetEmployeeData(string SearchParam)
- {
- List<string> empList = new List<string>();
- using (SqlConnection conn = new SqlConnection())
- {
- conn.ConnectionString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
- using (SqlCommand cmd = new SqlCommand())
- {
- cmd.CommandText = "select EmpName, EmpId from EmployeeTable where EmpName like @SearchParam + '%'";
- cmd.Parameters.AddWithValue("@SearchParam", SearchParam);
- cmd.Connection = conn;
- conn.Open();
- using (SqlDataReader sdr = cmd.ExecuteReader())
- {
- while (sdr.Read())
- empList.Add(string.Format("{0}-{1}", sdr["EmpName"], sdr["EmpId"]));
- }
- conn.Close();
- }
- }
- return empList.ToArray();
- }
-
-
- [WebMethod]
- public static string[] GetEmployeeDataSample(string SearchParam)
- {
- List<string> empList = new List<string>();
- for (int i = 0; i < 10; i++)
- {
- string data = (i + 1).ToString();
- data += "-EmpName " + (i + 1).ToString();
- empList.Add(data);
- }
- return empList.Where(x => x.ToLower().Contains(SearchParam)).ToArray();
- }
- }
Output is given below.
Reference link: Bootstrap AutoComplete
Another alternative is to use jQuery UI autocomplete: Autocomplete | jQuery UI
Here is a sample code on fetching the data, which is based on the user type.
- <!DOCTYPE html>
-
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- <link href="Content/themes/base/jquery-ui.min.css" rel="stylesheet" />
- <link href="Content/themes/base/base.css" rel="stylesheet" />
- <link href="Content/themes/base/autocomplete.css" rel="stylesheet" />
- <script src="Scripts/jquery-1.12.4.min.js"></script>
- <script src="Scripts/jquery-ui-1.12.1.min.js"></script>
- <script type="text/javascript">
- $(document).ready(function () {
- InitAutoCompleteEmployee();
- });
-
- function InitAutoCompleteEmployee() {
- $.widget("custom.combobox", {
- _create: function () {
- this.wrapper = $("<span>")
- .addClass("custom-combobox")
- .insertAfter(this.element);
- this.element.hide();
- this._createAutocomplete();
- this._createShowAllButton();
- },
- _createAutocomplete: function () {
- var selected = this.element.children(":selected"),
- value = selected.val() ? selected.text() : "";
- this.input = $("<input>")
- .appendTo(this.wrapper)
- .val(value)
- .attr("title", "")
- .attr("style", "width:200px")
- .attr("id", "txtEmp")
- .addClass("custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left")
- .autocomplete({
- delay: 0,
- //autoFocus: true,
- source: function (request, response) {
- $.ajax({
- type: "POST",
- url: '<%=ResolveUrl("~/WebForm69.aspx/GetEmployeeDataSample") %>',
- contentType: "application/json; charset=utf-8",
- dataType: "json",
- data: "{ 'SearchParam': '" + $("#txtEmp").val() + "'}",
- success: function (data) {
- var items = [];
- $.each(data.d, function (key, val) {
- var item = {
- label: val.EmpName,
- value: val.EmpId,
- id: val.EmpId,
- costFactor: val.EmpId
- };
- items.push(item);
- });
- source = items;
- response(items);
-
- },
- error: function (xhr) { debugger; }
- });
- },
- select: function (event, ui) {
- event.preventDefault();
- $("[id$=txtEmp]").val(ui.item.label)
- },
- focus: function (event, ui) {
- event.preventDefault();
- $("[id$=txtEmp]").val(ui.item.label);
- },
- })
- .tooltip({
- tooltipClass: "ui-state-highlight"
- });
- this._on(this.input, {
- autocompleteselect: function (event, ui) {
- this._trigger("select", event, {
- item: ui.item.label
- });
- },
- autocompletechange: "_removeIfInvalid"
- });
- },
- _createShowAllButton: function () {
- var input = this.input,
- wasOpen = false;
- $("<a>")
- .attr("tabIndex", -1)
- .attr("title", 'Select Employee')
- .tooltip()
- .appendTo(this.wrapper)
- .button({
- icons: {
- primary: "ui-icon-triangle-1-s"
- },
- text: false
- })
- .removeClass("ui-corner-all")
- .addClass("custom-combobox-toggle ui-corner-right")
- .mousedown(function () {
- wasOpen = input.autocomplete("widget").is(":visible");
- })
- .click(function () {
- input.focus();
- if (wasOpen) {
- return;
- }
- input.autocomplete("search", "*");
- });
- },
- _source: function (request, response) {
- var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
- response(this.element.children("option").map(function () {
- var text = $(this).text();
- if (this.value && (!request.term || matcher.test(text)))
- return {
- label: text,
- value: text,
- option: this
- };
- }));
- },
- _removeIfInvalid: function (event, ui) {
- if (ui.item) {
- return;
- }
- var value = this.input.val(),
- valuevalueLowerCase = value.toLowerCase(),
- valid = false;
- this.element.children("option").each(function () {
- if ($(this).text().toLowerCase() === valueLowerCase) {
- this.selected = valid = true;
- return false;
- }
- });
- if (valid) {
- return;
- }
- this.input
- .val("")
- .attr("title", value + 'not found!')
- .tooltip("open");
- this.element.val("");
- $("[id$=hdnEmpId]").val("");
- this._delay(function () {
- this.input.tooltip("close").attr("title", "");
- }, 2500);
- this.input.data("ui-autocomplete").term = "";
- },
- _destroy: function () {
- this.wrapper.remove();
- this.element.show();
- }
- });
- $("#ddlEmployee").combobox();
- }
- </script>
- </head>
- <body>
- <form id="form1" runat="server">
- <asp:DropDownList
- runat="server"
- ID="ddlEmployee"
- ClientIDMode="Static"
- Width="400" />
- <asp:HiddenField
- runat="server"
- ClientIDMode="Static"
- ID="hdnEmpId" />
- </form>
- </body>
- </html>
Here is WebMethod to bind the data, when the user types any character:
- public partial class WebForm69 : System.Web.UI.Page
- {
- protected void Page_Load(object sender, EventArgs e)
- {
- }
-
-
- [WebMethod]
- public static List<Employee> GetEmployeeData(string SearchParam)
- {
- List<Employee> empList = new List<Employee>();
- using (SqlConnection conn = new SqlConnection())
- {
- conn.ConnectionString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
- using (SqlCommand cmd = new SqlCommand())
- {
- cmd.CommandText = "select EmpName, EmpId from EmployeeTable where EmpName like @SearchParam + '%'";
- cmd.Parameters.AddWithValue("@SearchParam", SearchParam);
- cmd.Connection = conn;
- conn.Open();
- using (SqlDataReader sdr = cmd.ExecuteReader())
- {
- while (sdr.Read())
- empList.Add(new Employee() { EmpId = Convert.ToInt32(sdr["EmpName"]), EmpName = Convert.ToString(sdr["EmpId"]) });;
- }
- conn.Close();
- }
- }
- return empList;
- }
-
-
- [WebMethod]
- public static List<Employee> GetEmployeeDataSample(string SearchParam)
- {
- List<Employee> empList = new List<Employee>();
-
- for (int i = 0; i < 10; i++)
- empList.Add(new Employee() { EmpId = i + 1, EmpName = "EmpName " + (i + 1).ToString() });
- return empList.Where(record => record.EmpName.ToLower().Contains(SearchParam)).ToList();
- }
-
- public class Employee
- {
- public int EmpId { get; set; }
-
- public string EmpName { get; set; }
- }
- }
Output is given below.