I'm adding autocomplete on several inputs at the same time, thus writing a single handling function as the source. I'd like to have the id attribute of the origin (the input that triggered the action) available in my handling function. But it seems there's no direct reference to it within autocomplete...
$('#inputForm #supplier, #inputForm #label').autocomplete({
source: function(request, response) {
$.post("autocomplete.php", {id: ???, term: request.term}, success);
}
});
Any clue?
Got it! Thanks to Richard ;)
$(this.element).attr('id')
Complete code, in case anyone would be interested:
$('input').autocomplete({
source: function(request, response) {
$.post("autocomplete.php", {origin: $(this.element).attr('id'), term: request.term}, success);
}
});
you could use
$(this).attr('id')
I suggest you also use a class for all your autocomplete like for example
.autocomplete
and add data- for your extra data like
data-id, data-url
you can get the value of data-xxx attributes by using
$(this).data('id') and $(this).data('url')
enter code here
$(".autocomplete")
.each(function () {
$(this).autocomplete({
source : function(request, response) {
$.post($(this).data('url'), {origin: $(this.).data('id'), term: request.term}, success);
}
});
});
Related
I am trying to use a JSON output from the server as the source for my autocomplete function. I read the Autocomplete documentation and it does say that Array of Objects is accepted as a source type. Can someone please let me know where am I going wrong with this?
jq( document ).ready(function() {
jq("body").css({overflow:'hidden'});
jq.getJSON("<?php echo Mage::getBaseUrl() . "setsession/index/getarea"; ?>",
function(data) {
jq( "#autocomplete-1" ).autocomplete({
source: data,
select: function(event, ui) {
alert(ui.item.area_id);
jq("#splash_area").val(ui.item.area_id);
return false;
}
});
}
);
});
This is what I am getting back from the server (JSON encoded):
[{"area_id":"1","area_name":"DLF Phase 1"},{"area_id":"2","area_name":"DLF Phase 2"}]
From the documentation it states an An array of objects with label and value properties: [ { label: "Choice1", value: "value1" }, ... ].
http://api.jqueryui.com/autocomplete/#option-source
Your objects are not defined this way. So for your example something like
[{value:"1",label:"DLF Phase 1"},{value:"2",label:"DLF Phase 2"}]
The below code having a selectbox with id='theservice' and a text field with id ='servicename'.This code autocompletes the servicename text field by checking which service is active in the service selectbox.But unfortunately the source string remains the same eventhought the selectbox is changed.
$( "#servicename" ).autocomplete({
source: "index.php?key="+($('#theservice').find('option:selected').val()),
minLength: 2,
});
Thanks a Lot
Probably a delegation issue.
Autocomplete propagation example added
//build the autocomplete function, sans source
$('#servicename').autocomplete({
minLength: 2
});
var theArray = [];
$('body').on('change', 'select', function(){
$.ajax({
url: 'index.php?key='+$(this).val(),
dataType: 'json/jsonp',
success: function(data){
//i don't know what the array you return looks like, but autocomplete expets a key:value relationship
$.each(data, function(key, value){
theArray.push({label: value, value: key});
});
//a custom function to pass the array into
startAutoComplete(theArray);
}
});
});
function startAutoComplete(array){
$('#servicename').autocomplete('option', 'source', array);
}
Using the above code, we instantiate the autocomplete instance, we only identify the parameters we need excluding the source.
We then define an empty array that we can push the data returned from our ajax request into.
In our select function, we pass the value over to the server to be parsed. I don't know if you are expecting JSON/JSONP formatting, so you'll have to change that yourself.
In the success:function(data) we're getting back the request from the server, it would be best if the response was json_encode'ed. Also, when we push the values into the array, it's best to use a key -> value relationship. Autocomplete allows for a label and a value to be accessed like function(event, ui){ //do stuff with ui.item.label / ui.item.value}'
We declare an uninitialized function outside of the scope of document.ready, and pass the array into the function. Within this function, we change the source of the autocomplete.
Hope this all makes sense.
Solved the issue by using the .autocomplete( "option" , optionName , [value] ) method
$( "#servicename" ).autocomplete({
source: "index.php?key="+($('#theservice').find('option:selected').val()),
minLength: 2,
search: function( event, ui ) {
$( "#servicename" ).autocomplete( "option" ,'source' ,'index.php?key="+($('#theservice').find('option:selected').val()));}
});
I'm using jQuery UI autocomplete with data from a remote datasource. My use case is really similar to the example here:
http://jqueryui.com/demos/autocomplete/#remote
The only difference is that I set my delay to 0. In between the keystrokes, the menu disappears for about 1/10th of a second ~100milli seconds prior to the updated autocomplete list being displayed.
Is there anyway I can prevent the menu from temporarily disappearing between keystrokes? A good use case is google's search, where between keystrokes, the suggestion box does not temporarily disappear.
IMO, it is not a good practice to set a delay of zero when using a remote datasource. It will send more requests than needed and surcharge the server with no benefit.
Anyway, I think you can achieve what you want by defining the source option as a callback yourself.
First a bit of explanaton. I suppose you are using the remote feature passing an url as the source for the plugin. The plugin actually wraps this into a callback implemented this way:
// in case the option "source" is a string
url = this.options.source;
this.source = function(request, response) {
if (self.xhr) {
self.xhr.abort();
}
self.xhr = $.ajax({
url: url,
data: request,
dataType: "json",
autocompleteRequest: ++requestIndex,
success: function(data, status) {
if (this.autocompleteRequest === requestIndex) {
response(data);
}
},
error: function() {
if (this.autocompleteRequest === requestIndex) {
response([]);
}
}
});
};
As you can see, if there is already an ajax request going on, it abords it. This happenning in your case as a request, as fast as your server can be, takes some time and your delay is zero.
if (self.xhr) {
self.xhr.abort();
}
This will actually execute the error callback of the aborted request that will execute itself the response callback with an empty dataset. If you look at the response callback, it closes the menu if data is empty:
_response: function(content) {
if (!this.options.disabled && content && content.length) {
...
} else {
this.close();
}
You can actually define your own source callback to make your ajax request yourself and change the default behavior by not aborting any pending request. Something like:
$('#autocomplete').autocomplete({
source: function(request, response) {
$.ajax({
url: url,
data: request,
dataType: "json",
success: function(data, status) {
// display menu with received dataset
response(data);
},
error: function() {
// close the menu on error by executing the response
// callback with an empty dataset
response([]);
}
});
}
});
I need to show user all autocomplete choices, no matter what text he already wrote in the field? Maybe i need some other plugin?
$('#addressSearch').autocomplete("search", "");
That doesn't work.
There are two scenarios:
You're using a local data source. This is easy to accomplish in that case:
var src = ['JavaScript', 'C++', 'C#', 'Java', 'COBOL'];
$("#auto").autocomplete({
source: function (request, response) {
response(src);
}
});
You're using a remote data source.
$("#auto").autocomplete({
source: function (request, response) {
// Make AJAX call, but don't filter the results on the server.
$.get("/foo", function (results) {
response(results);
});
}
});
Either way you need to pass a function to the source argument and avoid filtering the results.
Here's an example with a local data source: http://jsfiddle.net/andrewwhitaker/e9t5Y/
You can set the minLength option to 0, then it should work.
i would like to know if theres a way to count the number of results which are displayed when you type something in the textbox. Count the li-elements work, but i bet theres a smarter way. Thanks
I don't think this is possible directly using JQueryUI Events. I've looked for a way without success.
All the events associated only return the element clicked (after the list is displayed), or information about the event (not about the list).
You can see it here: http://jqueryui.com/demos/autocomplete/#event-focus
What you said is the closest solution:
$( "#tags" ).autocomplete({
source: availableTags,
open: function(event,ui){
var len = $('.ui-autocomplete > li').length;
$('#count').html('Found '+len+' results');
}
});
The solution above did not work for me when I was typing something that returns no results. It keeps showing the amount of results from the last matching string. Here's a solution that did work.
source: function (request, response) {
$.getJSON(
"/Ajax/GetSomeJson.ashx",
{ q: request.term },
function (data) {
console.log(data.length);
$('#count').html('Found '+ data.length +' results');
response($.map(data, function (item) {
return item;
}));
}
);
}
I found a way to count the matches found, based on Fran's answer, but I think it's not 100% reliable. Still, it works for me.
$('#autocompleteinput').autocomplete({
source: datasource,
search: function()
{
$(this).data('count',0);
},
open: function()
{
$(this).data('count',$('.ui-autocomplete > li').length);
},
delay: 0
}).keyup(function(){
$('#count').html('Found '+$(this).data('count')+' items');
});
The delay has to be 0, or often it will trigger the keyup before the search and it won't count well.
This is Working for me. My requirement is to auto select on on blur event if there is only one matching result. Previously I tried var len= $('.ui-autocomplete > li').length; but i did not work in all scenarios. Sometimes it adds up previous results to count/length.
Below code worked for me:
.on('autocompletechange', function() {
if ($(this).data('ui-autocomplete').selectedItem === null && ($(this).autocomplete("widget").find( "li" ).length == 1) ) {
//this will trigger your select automatically so it will handle other custom override you did for select
$(this).data('ui-autocomplete').menu.element.children('li:first').children('a').trigger('click');
}
})
Fran's answer is nice but it will count 'li' from from all '.ui-autocomplete' on the page.
This solution will count 'li' elements only from current auto-complete: http://www.jbmurphy.com/2012/04/27/how-to-get-the-count-of-items-returned-in-jquery-autocomplete/
open: function(event,ui){
var len = $(this).autocomplete("widget").find( "li" ).length;
},