I am trying to use jQuery UI Autocomplete feature in order to make a wrapper of Google Autocomplete Service(because I just want to restrict some of the results returned by Google in a manner that is not possible through Google API).
Suppose I have this code:
$("#address").autocomplete({
source: function(request, response){
autoCompleteService = new google.maps.places.AutocompleteService();
autoCompleteService.getQueryPredictions({input: request.term }, autocompleteCallback);
//I should somewhere call the "response" object with desired suggestions as arguments
},
minLength: 5,
});
The problem is that jQuery UI Autocomplete forces me to call the "response" object(which is actually a function) with the suggestions I would like to show to the user as parameters.
But, on the other hand, Google API forces me to define a callback function(in my case 'autocompleteCallback') to whom it gives the requested suggestions as parameters after it's done.
Of course, I can't call the 'response' object inside the 'autocompleteCallback' function, and I can't call the response object just after this line either:
autoCompleteService.getQueryPredictions({input: request.term }, autocompleteCallback);
Because JS is async and I couldn't be sure that I get something in let's say: a global variable that I use in order to pass the results.
What would be the solution for that?
Is there a well-known JS design pattern for a problem like this?
You, sir, are a genius to combine the two frameworks! So I'll share the solution that I have:
$("#search").autocomplete({
source: function (request, response) {
autoCompleteService.getQueryPredictions({ input: request.term }, function (predictions, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
response($.map(predictions, function (prediction, i) {
return {
label: prediction.description,
value: prediction.description
}
}));
});
},
select: function (event, ui) {
var value = ui.item.value;
searchMap(value);
}
});
Of course, I have an actual function that does the proper Place lookup (searchMap()) that takes in a term. The only realistic way to do this in order to have a proper autocompleteCallback AND response handler for jQuery UI autocomplete is to keep the callback implementation inline. It sucks if you want to do this in more than one place but I haven't thought of anything better. Yet...
Related
I finally managed to retrieve a list from the available options related to the name searched from a field. Now, my goal is to retrieve some extra info when the user selects a specific option from the list. The JSON returns only the last name of the person and the user id which is an auto-increment field in the database. So I thought that I could send another JSON request to the server to actually return all the information available from the person specified from the user id. Is this considered bad practice ? Is there something alternative I am maybe missing ?
All in all, my code is here:
<script>
$(function() {
$( "#search" ).autocomplete({
delay: 0,
minLength: 2,
source: function(request, response) {
$.ajax({
url: 'search.php',
data: { term: request.term },
success: function(data) {
data = JSON.parse(data);
response($.map(data, function(item) {
return {
label: item.firstName,
value: item.firstName};
}));
}
});
}
})
});
</script>
So, how am I supposed to achieve this ?
I searched similar threads and read the doc in the official site but couldn't find a way to start. I think that somehow the results returned from the first call should be appended to DOM with anchor links, this code should be placed to the select property if I am not mistaken. But, I am very new to jquery and these web stuff and can't figure out the way.
Any help will be much appreciated. Thank you in advance.
It all depends on how much extra data you need returned.
If it's not much, then it makes sense to return the data as extra properties in a list of objects you are returning for the autocomplete results.
If you think you need too much extra data to make that viable, then in the autocomplete's select callback, you can just use the ID value to fetch all the additional info in an additional AJAX call to a second web service that returns the persons details for the passed in ID value.
$("#textjawatan" + noid).autocomplete({
source: function( request, response ) {
$.ajax({
url: "pendaftar_table.php",
dataType: "json",
data: { term : "pe" } ,
success: function( data ) {
response( data );
}
});
},
minLength: 2,
select: function(event, ui) {
$("input#jawatan" + noid).val(ui.item.no);
}
});
when i use
data: { term : "pe" }
its work, but when i use
data: { term : "pe", id : "jawatan" }
its doesnt work, what is the problem ?
I actually had this problem not too long ago. Let me explain in quick words.
As jQuery Autocomplete explain in their site http://api.jqueryui.com/autocomplete/ jQuery Autocomplete only accepts TERM as output for server. Let me quote the page
Function: The third variation, a callback, provides the most
flexibility and can be used to connect any data source to
Autocomplete. The callback gets two arguments: A request object, with
a single term property, which refers to the value currently in the
text input. For example, if the user enters "new yo" in a city field,
the Autocomplete term will equal "new yo". A response callback, which
expects a single argument: the data to suggest to the user. This data
should be filtered based on the provided term, and can be in any of
the formats described above for simple local data. It's important when
providing a custom source callback to handle errors during the
request. You must always call the response callback even if you
encounter an error. This ensures that the widget always has the
correct state.
In other words, if you even add 250 extra hashes to the json dict, it will only work TERM to server side.
How did I fix this?
What I did was this. Based on jQuery docs, the source can also be an ARRAY, so i did an ajax call to my server BEFORE setting the jQuery autocomplete and then feed the autocomplete plugin.
Note: This is not a very good fix, and I'm aware of it. But I had to do it due to my work's details and is just an option.
What is the name of the technique where a form is autocompleted using the database without reloading the page?
For example, the technique used by Google or Facebook to guess the friends you're look for after typing few letters.
When you have a small list, you can also use html datalist.
It isn't the technique used by Google or Facebook, but a nice alternative!
W3Schools Datalist
W3C Documentation
MDN
Inside your ajax callback you need to call the response function; passing the array that contains items to display.
jQuery("input.suggest-user").autocomplete({
source: function (request, response) {
jQuery.get("usernames.action", {
query: request.term
}, function (data) {
// assuming data is a JavaScript array such as
// ["one#abc.de", "onf#abc.de","ong#abc.de"]
// and not a string
response(data);
});
},
minLength: 3
});
I'm trying to use a custom source (remote) with typeahead.js, and having a bit of trouble getting things to work correctly. If I hard code the data, things work fine, but when I try to implement a call to a remote service, that call is never invoked, and thus, never retrieves the data to populate the typeahead.
Here's the code:
var places = function(query, cb){
$.getJSON({
url: "https://api.foursquare.com/v2/venues/search?v=20120321&intent=global&query=%QUERY&client_id="+App.fs.client_id+"&client_secret="+App.fs.client_secret,
success: function(results){
cb(results.response.venues);
},
error: function(){
console.log("error");
}
});
};
$("#search").typeahead({
highlight: true
},
{
name: "Places",
displayKey: "name",
source: places
}
);
If I create an object called results and manually structure the data, and pass that to cb, things work fine. However, with this implementation, $.getJSON is never even called. What am I missing?
Thanks!
As it turns out, the problem was in how I implemented $.getJSON. I'd thought the signature for that function was a hash of options, but it's not, it's actually (url, [data], [success]). Changing that to the correct signature makes things work.
Thanks for all the quick responses!
I think you can do it in this way
var search = $("#search").typeahead({
highlight: true,
source: []
};
Now you can use asyncrouniuous request to fetch data from server
$.getJSON({
url: "https://api.foursquare.com/v2/venues/search?v=20120321&intent=global&query=%QUERY&client_id="+App.fs.client_id+"&client_secret="+App.fs.client_secret,
success: function(results){
// some logic to filter, process results from server
// now you can directly update typeahead source
search.data('typeahead').source = results;
},
error: function(){
console.log("error");
}
});
Also read this and this discussion
Also i love selectize.js library, which have rich api, try it
Note that with typeahead.js you don't have to manually load your data. Using a prefetch URL will grab data on pageload and then stored in localStorage
$('#input').typeahead([
{
name: 'places',
prefetch: four_square_url_query,
}
]);
Isn't "places" in your example a function? What about:
var places;
$.getJSON({
url: fsquare_query,
success: function(results){
places = results.response.venues;
},
error: function(){
console.log("error");
}
});
I believe the most recent typeahead does not have a "source" property, rather it has "local".
I saw this code in another SO post: jQuery UI Autocomplete with ASP MVC
$("#CustomerID").autocomplete({
source: function(request, response) {
$.ajax({
type: "POST",
url: "/customer/search",
dataType: "json",
data: {
term: request.term
},
error: function(xhr, textStatus, errorThrown) {
alert('Error: ' + xhr.responseText);
},
success: function(data) {
response($.map(data, function(c) {
return {
label: c.Company,
value: c.ID
}
}));
}
});
},
minLength: 2,
select: function(event, ui) {
alert('Select');
}
});
I understand everything except the success function. I know that map is taking an array and mapping each value to a new object that has a label and value property and returning the new array, but I am not sure what response() does.
This object called response is a call back function passed to the function labeled source by the autocomplete method.
see Jquery UI Autocompleate
The third variation, the callback, provides the most flexibility, and can be used to connect any data source to Autocomplete. The callback gets two arguments:
A request object, with a single property called "term", which refers to the value currently in the text input. For example, when the user entered "new yo" in a city field, the Autocomplete term will equal "new yo".
A response callback, which expects a single argument to contain the data to suggest to the user. This data should be filtered based on the provided term, and can be in any of the formats described above for simple local data (String-Array or Object-Array with label/value/both properties). It's important when providing a custom source callback to handle errors during the request. You must always call the response callback even if you encounter an error. This ensures that the widget always has the correct state.
It appears to be a custom function that the original coder's code has. To the best of my knowledge this is not an inherent jQuery function.