jQuery UI autocomplete with item and id - javascript

I have the following script which works with a 1 dimensional array. Is it possible to get this to work with a 2 dimensional array? Then whichever item is selected, by clicking on a second button on the page, should display the id of whichever item is selected.
This is the script with the 1 dimensional array:
var $local_source = ["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby"];
$("#txtAllowSearch").autocomplete({
source: $local_source
});
This is the script for the button to check the id, which is incomplete:
$('#button').click(function() {
// alert($("#txtAllowSearch").someone_get_id_of_selected_item);
});

You need to use the ui.item.label (the text) and ui.item.value (the id) properties
$('#selector').autocomplete({
source: url,
select: function (event, ui) {
$("#txtAllowSearch").val(ui.item.label); // display the selected text
$("#txtAllowSearchID").val(ui.item.value); // save selected id to hidden input
}
});
$('#button').click(function() {
alert($("#txtAllowSearchID").val()); // get the id from the hidden input
});
[Edit] You also asked how to create the multi-dimensional array...
You should be able create the array like so:
var $local_source = [[0,"c++"], [1,"java"], [2,"php"], [3,"coldfusion"],
[4,"javascript"], [5,"asp"], [6,"ruby"]];
Read more about how to work with multi-dimensional arrays here: http://www.javascriptkit.com/javatutors/literal-notation2.shtml

From the Overview tab of jQuery autocomplete plugin:
The local data can be a simple Array
of Strings, or it contains Objects for
each item in the array, with either a
label or value property or both. The
label property is displayed in the
suggestion menu. The value will be
inserted into the input element after
the user selected something from the
menu. If just one property is
specified, it will be used for both,
eg. if you provide only
value-properties, the value will also
be used as the label.
So your "two-dimensional" array could look like:
var $local_source = [{
value: 1,
label: "c++"
}, {
value: 2,
label: "java"
}, {
value: 3,
label: "php"
}, {
value: 4,
label: "coldfusion"
}, {
value: 5,
label: "javascript"
}, {
value: 6,
label: "asp"
}, {
value: 7,
label: "ruby"
}];
You can access the label and value properties inside focus and select event through the ui argument using ui.item.label and ui.item.value.
Edit
Seems like you have to "cancel" the focus and select events so that it does not place the id numbers inside the text boxes. While doing so you can copy the value in a hidden variable instead. Here is an example.

My code only worked when I added 'return false' to the select function. Without this, the input was set with the right value inside the select function and then it was set to the id value after the select function was over. The return false solved this problem.
$('#sistema_select').autocomplete({
minLength: 3,
source: <?php echo $lista_sistemas;?> ,
select: function (event, ui) {
$('#sistema_select').val(ui.item.label); // display the selected text
$('#sistema_select_id').val(ui.item.value); // save selected id to hidden input
return false;
},
change: function( event, ui ) {
$( "#sistema_select_id" ).val( ui.item? ui.item.value : 0 );
}
});
In addition, I added a function to the change event because, if the user writes something in the input or erases a part of the item label after one item was selected, I need to update the hidden field so that I don´t get the wrong (outdated) id. For example, if my source is:
var $local_source = [
{value: 1, label: "c++"},
{value: 2, label: "java"}]
and the user type ja and select the 'java' option with the autocomplete, I store the value 2 in the hidden field. If the user erase a letter from 'java', por exemple ending up with 'jva' in the input field, I can´t pass to my code the id 2, because the user changed the value. In this case I set the id to 0.

Just want to share what worked on my end, in case it would be able to help someone else too. Alternatively based on Paty Lustosa's answer above, please allow me to add another approach derived from this site where he used an ajax approach for the source method
http://salman-w.blogspot.ca/2013/12/jquery-ui-autocomplete-examples.html#example-3
The kicker is the resulting "string" or json format from your php script (listing.php below) that derives the result set to be shown in the autocomplete field should follow something like this:
{"list":[
{"value": 1, "label": "abc"},
{"value": 2, "label": "def"},
{"value": 3, "label": "ghi"}
]}
Then on the source portion of the autocomplete method:
source: function(request, response) {
$.getJSON("listing.php", {
term: request.term
}, function(data) {
var array = data.error ? [] : $.map(data.list, function(m) {
return {
label: m.label,
value: m.value
};
});
response(array);
});
},
select: function (event, ui) {
$("#autocomplete_field").val(ui.item.label); // display the selected text
$("#field_id").val(ui.item.value); // save selected id to hidden input
return false;
}
Hope this helps... all the best!

Assuming the objects in your source array have an id property...
var $local_source = [
{ id: 1, value: "c++" },
{ id: 2, value: "java" },
{ id: 3, value: "php" },
{ id: 4, value: "coldfusion" },
{ id: 5, value: "javascript" },
{ id: 6, value: "asp" },
{ id: 7, value: "ruby" }];
Getting hold of the current instance and inspecting its selectedItem property will allow you to retrieve the properties of the currently selceted item. In this case alerting the id of the selected item.
$('#button').click(function() {
alert($("#txtAllowSearch").autocomplete("instance").selectedItem.id;
});

<script type="text/javascript">
$(function () {
$("#MyTextBox").autocomplete({
source: "MyDataFactory.ashx",
minLength: 2,
select: function (event, ui) {
$('#MyIdTextBox').val(ui.item.id);
return ui.item.label;
}
});
});
The above responses helped but, did not work in my implementation.
The instead of using setting the value using jQuery, I am returning the value from the function to the select option.
The MyDataFactory.ashx page has a class with three properties Id, Label, Value.
Pass the List into the JavaScript serializer, and return the response.

I do not think that there is need to hack around the value and label properties, use hidden input fields or to suppress events. You may add your own custom property to each Autocomplete object and then read that property value later.
Here is an example.
$(#yourInputTextBox).autocomplete({
source: function(request, response) {
// Do something with request.term (what was keyed in by the user).
// It could be an AJAX call or some search from local data.
// To keep this part short, I will do some search from local data.
// Let's assume we get some results immediately, where
// results is an array containing objects with some id and name.
var results = yourSearchClass.search(request.term);
// Populate the array that will be passed to the response callback.
var autocompleteObjects = [];
for (var i = 0; i < results.length; i++) {
var object = {
// Used by jQuery Autocomplete to show
// autocomplete suggestions as well as
// the text in yourInputTextBox upon selection.
// Assign them to a value that you want the user to see.
value: results[i].name;
label: results[i].name;
// Put our own custom id here.
// If you want to, you can even put the result object.
id: results[i].id;
};
autocompleteObjects.push(object);
}
// Invoke the response callback.
response(autocompleteObjects);
},
select: function(event, ui) {
// Retrieve your id here and do something with it.
console.log(ui.item.id);
}
});
The documentation mentions you have to pass in an array of objects with label and value properties. However, you may certainly pass in objects with more than these two properties and read them later.
Here is the relevant part I am referring to.
Array: An array can be used for local data. There are two supported
formats: An array of strings: [ "Choice1", "Choice2" ] An array of
objects with label and value properties: [ { label: "Choice1", value:
"value1" }, ... ] The label property is displayed in the suggestion
menu. The value will be inserted into the input element when a user
selects an item. If just one property is specified, it will be used
for both, e.g., if you provide only value properties, the value will
also be used as the label.

At last i did it Thanks alot friends, and a special thanks to Mr https://stackoverflow.com/users/87015/salman-a because of his code i was able to solve it properly. finally my code is looking like this as i am using groovy grails i hope this will help somebody there.. Thanks alot
html code looks like this in my gsp page
<input id="populate-dropdown" name="nameofClient" type="text">
<input id="wilhaveid" name="idofclient" type="text">
script Function is like this in my gsp page
<script>
$( "#populate-dropdown").on('input', function() {
$.ajax({
url:'autoCOmp',
data: {inputField: $("#populate-dropdown").val()},
success: function(resp){
$('#populate-dropdown').autocomplete({
source:resp,
select: function (event, ui) {
$("#populate-dropdown").val(ui.item.label);
$("#wilhaveid").val(ui.item.value);
return false;
}
})
}
});
});
</script>
And my controller code is like this
def autoCOmp(){
println(params)
def c = Client.createCriteria()
def results = c.list {
like("nameOfClient", params.inputField+"%")
}
def itemList = []
results.each{
itemList << [value:it.id,label:it.nameOfClient]
}
println(itemList)
render itemList as JSON
}
One more thing i have not set id field hidden because at first i was checking that i am getting the exact id , you can keep it hidden just put type=hidden instead of text for second input item in html
Thanks !

I've tried above code displaying (value or ID) in text-box insted of Label text. After that I've tried event.preventDefault() it's working perfectly...
var e = [{"label":"PHP","value":"1"},{"label":"Java","value":"2"}]
$(".jquery-autocomplete").autocomplete({
source: e,select: function( event, ui ) {
event.preventDefault();
$('.jquery-autocomplete').val(ui.item.label);
console.log(ui.item.label);
console.log(ui.item.value);
}
});

This can be done without the use of hidden field. You have to take benefit of the JQuerys ability to make custom attributes on run time.
('#selector').autocomplete({
source: url,
select: function (event, ui) {
$("#txtAllowSearch").val(ui.item.label); // display the selected text
$("#txtAllowSearch").attr('item_id',ui.item.value); // save selected id to hidden input
}
});
$('#button').click(function() {
alert($("#txtAllowSearch").attr('item_id')); // get the id from the hidden input
});

Auto Complete Text box binding using Jquery
## HTML Code For Text Box and For Handling UserID use Hidden value ##
<div class="ui-widget">
#Html.TextBox("userName")
#Html.Hidden("userId")
</div>
Below Library's is Required
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
Jquery Script
$("#userName").autocomplete(
{
source: function (request,responce)
{
debugger
var Name = $("#userName").val();
$.ajax({
url: "/Dashboard/UserNames",
method: "POST",
contentType: "application/json",
data: JSON.stringify({
Name: Name
}),
dataType: 'json',
success: function (data) {
debugger
responce(data);
},
error: function (err) {
alert(err);
}
});
},
select: function (event, ui) {
$("#userName").val(ui.item.label); // display the selected text
$("#userId").val(ui.item.value); // save selected id to hidden input
return false;
}
})
Return data Should be below format
label = u.person_full_name,
value = u.user_id

Related

JQuery .change() how to get value

I am implementing dynamic drop-down selectors using JQuery. I am new to frontend in general. I am struggling to access the value that a dropdown has changed to when I use JQuery.
The user journey is (1) pick a 'collection' and then (2) from within that collection, pick a 'unit'.
I implemented the 'collection' dropdown onchange attribute in HTML like this:
<select name="collection" id="collection" onchange="collectionChanged(this.value)">
With this method, the collectionChanged function gets the value that the dropdown selected has changed to. I then tried to implement the 'unit' onchange behaviour with JQuery. But I get an object that doesn't have a value attribute or anything that looks comparable. I looked at the documentation at the JQuery Website and also at W3CSchools. In both cases, the functions they use do not take any arguments, so I have nothing to compare to. What am I missing?
function getOrCreateUnitSelect() {
let unitSelect;
if ( ! unitSelectExists() ) {
unitSelect = $('<select />', {"id": "unit-select"});
// This is where I add the 'on change' function
unitSelect.change(unitChanged);
unitSelect.insertAfter($('#collection'));
}
else {
unitSelect = $('#unit-select');
}
return unitSelect;
}
function unitSelectExists() {
return $('#unit-select').length;
}
function collectionChanged(value) {
let processFilterResponse = function(serverResponseData, textStatusIgnored, jqXHRIgnored) {
let serverDataObject = JSON.parse(serverResponseData);
let unitSelect = getOrCreateUnitSelect();
serverDataObject['content']['units'].forEach(
function(unit){
$(
"<option />",
{value: unit, text: unit}
).appendTo($("#unit-select"));
}
);
}
let config = {
type: "GET",
url: filterUrl,
data: {'collection': value},
dataType: 'html',
success: processFilterResponse
}
$.ajax(config);
}
function unitChanged(e) {
console.log("unit has been changed");
// Here I get some object that doesn't have a 'value' attribute
console.log(e);
}
When .change calls a handler, the this keyword is a reference to the element where the event is being delivered, so in unitChanged(e) you can just do console.log(this.value).
Note: .change(handler) is just shorthand for .on("change", handler)

Dynamically populating ACF field works with select - but not with select2

I have a select field $("#country") in a ACF form on Wordpress backend which triggers the values for a second select field $("#city"). It's a typical Country/City relationship with custom values.
The script is enqueued, the change event is triggered and the second select gets populated with success using this code:
var cities = {
"Spain": [
"Madrid",
"Barcelona"
],
"Portugal": [
"Lisboa",
"Oporto"
]
}
jQuery(document).ready(function($) {
$('#country').change(function () {
loadCities($(this).find("option:selected").val());
}).change();
});
function loadCities(country) {
$('#city').empty();
cities[country].forEach(function(city) {
$('#city').append("<option value='"+city+"'>"+city+"</option>");
});
}
As the list of cities is quite long, I want to use select2 instead of select. Here the changed loadCities function:
function loadCities(country) {
$('#city').empty();
var data = [{id: "", text: ""}];
cities[country].forEach(function(city) {
data.push({id: city, text: city});
});
$('#city').select2({
data: data,
placeholder: "Select a city"
}).trigger('change');
}
The problem is that the options (=cities) don't show up as expected in the select2 list. But they seem to be appended, checking their existence with jquery shows them.
First thing you can dynamically append options using the data attribute even for a multi dimensional json array of objects. But do not initialize the select box twice!
$("#country").select2({ data: data.keys });
Instead destroy it and init with your values, you can also try with change event.
$("#country").select2('destroy').empty().select2({ data: data.keys });
Let me know if this helps.

Jquery autocomplete dropdown not working in dynamic build textbox

I have build a search textbox dynamically and i want to do autocomplete search . Below is my code,
function getEmp(){
$('#itemSearch').autocomplete({
"source":function(request, response) {
var textInput = document.getElementById('a');
textInput.value = textInput.value.replace(/^\s+/,"");
var jqxhr = $.getJSON( baseurl +'test/search-emp', {
cName :$("#a").val(),
},response);
jqxhr.success(function() {
});
},
"select":function(e, ui){
},
"minLength":1,"autoFill":true,"showHeader":true});
}
I got the ajax result,but dropdown is not visible in autocomplete search.Please provide a solution
according to document ; http://api.jqueryui.com/autocomplete/#option-source
Your ajax must return an array or like ...
[ { label: "Choice1", value: "value1" }, ... ]
Prepare an api or something return documented kind a data vie Get
this source must use 'term' parameter
then put this to page YOUR_AJAX_URL must point your api...
$( function() {
$("#itemSearch" ).autocomplete({
source: "YOUR_AJAX_URL",
minLength: 2,
select: function( event, ui ) {
alert(ui.item.value);
}
});
} );
ps. https://jqueryui.com/autocomplete/#remote at here you can investigate developer tools in chrome (or similar)

jquery validate input array and passing dynamic values

I'm trying to validate a group of input arrays using jquery validator plugin. I'm having problems understanding how to pass another element into the validation.
My code so far:
$('#edit-fixtures').validate({
rules: {
"player_a[]": {
required: true,
uniqueMatch: function () {
return $(this).next('.player').val();
},
},
"player_b[]": {
required: true,
uniqueMatch: function () {
$(this).closest('.player').val();
},
},
}
});
My input elements are a series of paired select boxes named player_a[] player_b[] There are about 40 pairs. Each pair should be unique and that's what i'll be validating.
I'm trying to pass the value of the nearest player_b to the changed player_a and vice versa.
I have a change method to validate on each change:
$(".player").change(function () {
var check = $(this).valid();
console.log("validation:", check);
});
I'm still working on the validation method but cant seem to get the parameters to the method correctly.
Is there a way of doing this?
uniqueMatch: [$item1, $item2, ....]
$.validator.addMethod('uniqueMatch', function(value, element, parameterValue) {
var item1Value = $(parameterValue[0]).val();
//and so on...
//Based on values, you return true or false;
//Voila!
}

Force a user to select from JQuery UI Autocomplete and populate a hidden field after selecting

I have a large HTML form that contains many fields that need an autocomplete for accounts. I tag these fields with the class AccountLookup and jQuery does the dirty work for the autocomplete:
$(".AccountLookup").autocomplete({
source: function (request, response) {
$.ajax({
url: "Lookup.asmx/GetAccounts",
data: "{ 'Search': '" + request.term + "' }",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
dataFilter: function (data) { return data; },
success: function (data) {
response($.map(data.d, function (item) {
return {
value: item.Value
}
}))
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
},
minLength: 3
});
Now, when a user selects something from the autocomplete I need it to populate a hidden field just BEFORE the tagged input field; probably using something like:
$(this).prev().val(item.Key);
How do I incorporate this functionality? Also, how do I force a user to select from the auto complete? (All the values are pre-defined, the user cannot add new ones.)
EDIT:
As far as I understand from inspecting the DOM, the select option is currently filling in the hidden form field.
select: function (event, ui) {
$(this).prev().val(ui.item.key);
}
I know this is an old post--- but I ran into it in trying to solve a similar problem (forcing the user to select an item from the list)...
$("#ac").autocomplete({
source: function (req, resp) {
//add code here...
},
select: function (e, ui) {
$(this).next().val(ui.item.id);
},
change: function (ev, ui) {
if (!ui.item)
$(this).val("");
}
});
$(".AccountLookup").autocomplete({
/*...*/
}).result(function(event, item) {
$(this).prev().val(item.Key);
});
You could also use a jQuery validate to ensure that the field is populated.
for force selection, you can use "change" event of Autocomplete
var availableTags = [
"ActionScript",
"AppleScript"
];
$("#tags").autocomplete({
source: availableTags,
change: function (event, ui) {
if(!ui.item){
//http://api.jqueryui.com/autocomplete/#event-change -
// The item selected from the menu, if any. Otherwise the property is null
//so clear the item for force selection
$("#tags").val("");
}
}
});
For the selection action, try using the formatItem option. You can format each result to have an onclick event that will populate the other textbox.
For the forcing to select from autocomplete, you need to use the mustMatch option.
http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions
I ran into this same problem quite awhile ago and some post helped me along with it. I have since modified the code as I found that there were cases I wanted one or more fields to fill in from the information returned. In the select option of the autocomplete I added a function.
select: function (e, ui) {ReSetField({'txtID':'id','txtPrice':'price' [,etc...]}, ui) }
The function "ResetFields" then takes in a JSON list of element names paired with fieldnames and uses the fieldnames to match the elements in the ui object. The value can then be pulled from the ui item and put into the html element.
function ReSetField(_flds, _vals) {
//Set up the flds to be reset with values passed in.
try {
if (_flds != undefined) {
if ($.type(_flds) == 'string') {
_flds = JSON.parse(_flds);
};
var _fld = null;
var _val = '';
$.each(_flds, function (index) {
if (index.length > 0) {
_fld = '#' + index; //Set the forms field name to set
_val = _flds[index]; //Pick up the field name to set the fields value
$fld = $(_fld);
$fld.val(_vals.item[_val]); //Set the fields value to the returned value
}
}
})
};
}
catch (e) {
alert('Cannot set field ' + _fld + '.');
}
}
By sticking the "fieldlist" into the HTML element as an attribute like "fieldlist" and using a class like "comboBox" I can then use a single function to find all ComboBox elements and set up the autocomplete on a form reducing the amount of code required to handle 2 or more lookups on a form.

Categories