Jquery ui autocomplete filling in hidden field with id

I am trying to get an autocomplete plugin to fill in one text box with the name of the university and another with the university code. The code below returns the results and fills in the text box of the university name, but I cannot figure out how to fill in another input.

I tried to follow this example , but ran into problems to even call the web method. One strange thing is that it seemed like ajax was called before autocomplete was attached to the text box in which the user types. Not sure what caused js to call the autocomplete method.

I had to combine parts of the above with jquery ui doc on autocomplete using json ( link ). But I still do not know how to get the second input, which will be filled, as in the first example.

any ideas?

Here is jquery and html

<script language="javascript" type="text/javascript"> $(function () { $("#university").autocomplete({ source: function (request, response) { $.ajax({ type: "POST", url: "AutoComplete.asmx/GetUniversities", dataType: "json", data: "{ 'data': '" + request.term + "' }", contentType: "application/json; charset=utf-8", success: function (data) { response($.map(data, function (item) { return { value: item.Descr, UnivCode: item.UnivCode } })); } }); } }); }); </script> <div class="ui-widget"> <label for="university">University: </label> <input id="university" type="text"/> <label for="universityID">ID: </label> <input id="universityID" type="text" /> </div> 

Here is my .net webmethod

 using System; using System.Web; using System.Collections; using System.Web.Services; using System.Web.Services.Protocols; using System.Collections.Generic; using System.Web.Script.Services; using System.Text; using System.Data; [ScriptService()] [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class AutoComplete : System.Web.Services.WebService { [WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public List<University> GetUniversities(string data) { List<University> UniversityList = new List<University>(); try { clsDataBase db = new clsDataBase(); DataTable dt = new DataTable(); StringBuilder sql = new StringBuilder(); Dictionary<string, object> parms = new Dictionary<string, object>(); sql.Append(" SELECT univ_code "); sql.Append(" , INITCAP(univ_desc) AS descr "); sql.Append(" FROM lk_university "); sql.Append(" WHERE UPPER(univ_desc) LIKE UPPER(?) "); sql.Append(" ORDER BY univ_desc "); parms.Add("university", "%" + data + "%"); dt = db.executeParmQuery(sql.ToString(), parms); DataView dv = new DataView(dt); ArrayList filteredList = new ArrayList(); foreach (DataRowView drv in dv) { University university = new University(); university.UnivCode= drv["univ_code"].ToString(); university.Descr = drv["descr"].ToString(); UniversityList.Add(university); } } catch (Exception ex) { throw new Exception(ex.Message); //return null; } //} return UniversityList; } public class University { string _value; public string value { get { return _Descr + " (" + _UnivCode + ")"; } } string _Descr; public string Descr { get { return _Descr; } set { _Descr = value; } } string _UnivCode; public string UnivCode { get { return _UnivCode; } set { _UnivCode = value; } } } } 

EDIT

I managed to get it working by adding a select event. In my previous testing, I had it there, but in the wrong place (originally nested in a success event). It was also necessary to add three lines in the success event that set the value: item.Descr, Descr: item.Descr and UnivCode: item.UnivCode. I donโ€™t quite understand what they are referencing or what they are doing, since the actual setting of the inputs is done in the select event, where I indicate the actual identifier of the inputs ($ ('# university'). Val (ui.item.Descr);), but this was necessary to make the code work.

Here's a working jquery without any changes to the html or .net code.

 <script language="javascript" type="text/javascript"> $(function () { $("#university").autocomplete({ source: function (request, response) { $.ajax({ type: "POST", url: "AutoComplete.asmx/GetUniversities", dataType: "json", data: "{ 'data': '" + request.term + "' }", contentType: "application/json; charset=utf-8", success: function (data) { response($.map(data, function (item) { return { value: item.Descr, Descr: item.Descr, UnivCode: item.UnivCode } })); } }); }, select: function (event, ui) { $('#university').val(ui.item.Descr); $('#universityID').val(ui.item.UnivCode); return false; } }); }); 
+7
source share
4 answers

I managed to get it working by adding a select event. In my previous testing, I had it there, but in the wrong place (originally nested in a success event). It was also necessary to add three lines in the success event that set the value: item.Descr, Descr: item.Descr and UnivCode: item.UnivCode. I donโ€™t quite understand what they are referencing or what they are doing, since the actual setting of the inputs is done in the select event, where I indicate the actual identifier of the inputs ($ ('# university'). Val (ui.item.Descr);), but this was necessary to make the code work.

Here's a working jquery without any changes to the html or .net code.

 $(function () { $("#university").autocomplete({ source: function (request, response) { $.ajax({ type: "POST", url: "AutoComplete.asmx/GetUniversities", dataType: "json", data: "{ 'data': '" + request.term + "' }", contentType: "application/json; charset=utf-8", success: function (data) { response($.map(data, function (item) { return { value: item.Descr, Descr: item.Descr, UnivCode: item.UnivCode } })); } }); }, select: function (event, ui) { $('#university').val(ui.item.Descr); $('#universityID').val(ui.item.UnivCode); return false; } }); }); 
+9
source

I survived this pain using MVC, and the returned object should have a label property (displayed in the drop-down list) and value property (the actual choice value is UnivCode).

The key to it is the selection method defined in your autocomplete field that takes 2 arguments (for example, select: function (e, ui) {... do stuff ...; return false;}). The trick here is to return false to prevent the default event handler from running jQuery.

Then you can use ui.item.label to get the displayed value and ui.item.value to get the code.

I used a separate method that took ui.item and then wrote the values โ€‹โ€‹for hidden inputs.

If I can get the code together, I'll post an example.

Example: - This example uses the Autocomp1_display text field, to which autocomplete is attached. The displayItem method then writes the displayed value of the selected item to this text box and puts the selected value in a hidden range.

 $j("#Autocomp1_display").autocomplete({ source: function(request, response){ $j.ajaxSetup({cache: false}); $j.ajax({ url: "AutoComplete.asmx/GetUniversities" type: "GET", data: request, dataType: "json", success: function (data) { request.term=""; response(data); } }); }, cache: false, select: function(e, ui){ displayItem("Autocomp1", ui.item); Autocomp1_HasSelections = true; setAutocompleteState("Autocomp1_display", Autocomp1_IsMultiSelect, Autocomp1_HasSelections); $j('#Autocomp1').change(); return false; }, focus: function(event, ui){ if (ui.item.label){ $j(this).val(ui.item.label); } else { $j(this).val(ui.item.value); } return false; } }); 

The select event uses the displayItem method as shown below

 //Function to write the entries into the text box function displayItem(target, dataObject) { var displayValue = dataObject.label.replace('\n',''); var existingSpan = false; existingSpan = document.getElementById("span_" + displayValue); if (!existingSpan) { var span = $j("<span>").text(displayValue); //Create a new span tag to display the selected value span.attr({ id: "span_" + dataObject.value }); var hiddenFld = $j("<input>").attr({ type: "hidden" }).val(dataObject.value); //Create a div object to store the code value hiddenFld.addClass(target + "IdField").css("visibility", "hidden").css("height", 0).attr({ id: target, name: target }); //Format the div var a = $j("<a>").addClass(target + "remove").attr({ href: "javascript:", title: "Remove " + displayValue }).text("x").appendTo(span); //Define the "x" to remove the span hiddenFld.appendTo(span); //Append the div to the span span.insertBefore("#" + target + "_display"); //Insert span before the concealed text box $j("#" + target).attr({ value: dataObject.value }); //Store the ID value related to the selected item $j("#" + target + "_display").val("").css("top", 2); //Store the ID value related to the selected item //$j("#" + target + "_display").flushCache(); //Flush the cache for the autocomplete control } else { alert("This item has already been selected"); } } 

SetAutocompleteState method: -

 function setAutocompleteState(targetName, IsMultiSelect, HasSelections) { if (!IsMultiSelect && HasSelections) { $j("#" + targetName).autocomplete("option", "disabled", true); } else { $j("#" + targetName).autocomplete("option", "disabled", false); } } 

The definitions of isMultiSelect and HasSelections determine whether to enable autocomplete or not, and targetName is just the identifier of the text field that was "autocomplete"

+1
source

Styles Used With Autocomplete Control

 .acarea { padding:3px 3px 0; margin:0 auto; background-color:#fff; cursor:text; } .acarea div {border:1px solid #aaa; } .acarea input {border:0px; display:inline;} .acarea span { display:block; width:auto; margin:0 3px 3px 0; padding:3px 20px 4px 8px; position:relative; float:left; text-indent:0; background-color:#eee; border:1px solid #333; -moz-border-radius:7px; -webkit-border-radius:7px; border-radius:7px; color:#333; font:normal 11px Verdana, Sans-serif; } .acarea span a { position:absolute; right:8px; top:2px; color:#666; font:bold 12px Verdana, Sans-serif; text-decoration:none; } .acarea span a:hover { color:#ff0000; } .ui-menu .ui-menu-item { white-space:nowrap; padding:0 10px 0 0; } 

Library Functions for Autofill Management

 //Function to write the entries into the text box function displayItem(target, dataObject) { var displayValue = dataObject.label.replace('\n',''); var existingSpan = false; existingSpan = document.getElementById("span_" + displayValue); if (!existingSpan) { var span = $j("<span>").text(displayValue); //Create a new span tag to display the selected value span.attr({ id: "span_" + dataObject.value }); var hiddenFld = $j("<input>").attr({ type: "hidden" }).val(dataObject.value); //Create a div object to store the code value hiddenFld.addClass(target + "IdField").css("visibility", "hidden").css("height", 0).attr({ id: target, name: target }); //Format the div var a = $j("<a>").addClass(target + "remove").attr({ href: "javascript:", title: "Remove " + displayValue }).text("x").appendTo(span); //Define the "x" to remove the span hiddenFld.appendTo(span); //Append the div to the span span.insertBefore("#" + target + "_display"); //Insert span before the concealed text box $j("#" + target).attr({ value: dataObject.value }); //Store the ID value related to the selected item $j("#" + target + "_display").val("").css("top", 2); //Store the ID value related to the selected item //$j("#" + target + "_display").flushCache(); //Flush the cache for the autocomplete control } else { alert("This item has already been selected"); } } //function to load the existing data as entries //targetName is the id of the control being rendered //existingEntries is an array of objects that contain a label and value property (at least!!) function loadItems(targetName, existingEntries){ for (i=0;i<existingEntries.length;i++) { displayItem(targetName, existingEntries[i]); } //End of for loop } //End of function function setAutocompleteState(targetName, IsMultiSelect, HasSelections) { if (!IsMultiSelect && HasSelections) { $j("#" + targetName).autocomplete("option", "disabled", true); } else { $j("#" + targetName).autocomplete("option", "disabled", false); } } 

Code displayed by the MVC extension method

 <script language="javascript"> var Autocomp1_existingEntries = null; var Autocomp1_IsMultiSelect = false; var Autocomp1_HasSelections = false; </script> <div class="acarea" id="Autocomp1_acarea"><div class="ui-helper-clearfix"><input id="Autocomp1_display" type="text" /></div></div> <script type="text/javascript" language="javascript"> $j(document).ready(function () { $j("#Autocomp1_display").autocomplete({ source: function(request, response){ $j.ajaxSetup({cache: false}); $j.ajax({ url: "AutoComplete.asmx/GetUniversities", type: "GET", data: request, dataType: "json", success: function (data) { request.term=""; response(data); } }); }, cache: false, select: function(e, ui){ displayItem("Autocomp1", ui.item); Autocomp1_HasSelections = true; setAutocompleteState("Autocomp1_display", Autocomp1_IsMultiSelect, Autocomp1_HasSelections); $j('#Autocomp1').change(); return false; }, focus: function(event, ui){ if (ui.item.label){ $j(this).val(ui.item.label); } else { $j(this).val(ui.item.value); } return false; }}); }) if (Autocomp1_existingEntries != null){ loadItems("Autocomp1", Autocomp1_existingEntries); Autocomp1_HasSelections = true; setAutocompleteState("Autocomp1_display", Autocomp1_IsMultiSelect, Autocomp1_HasSelections); } $j("#Autocomp1_acarea").click(function() { $j("#Autocomp1_display").focus(); }); $j(".Autocomp1remove", document.getElementById("Autocomp1_acarea")).live("click", function() { var spanDiv = $j(this).parent().parent(); $j(this).parent().remove(); Autocomp1_HasSelections = false; var Autocomp1_nodeCounter = 0; for (Autocomp1_nodeCounter = 0;Autocomp1_nodeCounter < spanDiv[0].childNodes.length; Autocomp1_nodeCounter++){ if (spanDiv[0].childNodes[Autocomp1_nodeCounter].nodeName.toLowerCase()=="span"){ Autocomp1_HasSelections = true; break; } } setAutocompleteState("Autocomp1_display", Autocomp1_IsMultiSelect, Autocomp1_HasSelections); if ($j("#Autocomp1_acarea span").length === 0) { $j("#Autocomp1_display").css("top", 0).val(""); } $j('#Autocomp1').change(); }); 

This is a property of the code that I use to render the autocomplete control and get it to store the selected values โ€‹โ€‹inside the div. Feel free to massage it to make it work for you.

0
source

I wrote an Asp.Net WebControl wrapping a jQuery UI autocomplete widget. WebControl provides a property: OnClientSelection, which can be set for the javascript function name. Under the hood, what it does is exactly what you specified for the "select" action. I wrote documentation on how to use the control.

You can find it at:

http://autocompletedotnet.codeplex.com/

Hope this helps

0
source

All Articles