What does this javascript response function do? - javascript

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.

Related

JQuery Autocomplete - multiple data post not working

$("#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.

jQuery autocomplete results box not displaying for JSON stream converted to `label` & `value`

I had jQuery autocomplete working with the autocomplete search results box showing at the appropriate location. That was for server side search support with the following client side js:
$("#someSearchTermInputBox").autocomplete(
{
minLength: 2,
source: "/searchThatReturnsStringListOfResults"
});
In this case, the server sends back to the client the following information (the following via Chrome debugger):
["Alice","Bob","Calvin","Dirk","Elvin","Fancy","Greg","Harry","Issey","Jack"]
The corresponding input text box is:
<input id="someSearchTermInputBox" name="someSearchTermInputBox" placeholder="Search for people, events and places" type="search"
Because I need more functionality, I changed my search to return a JSON that looks like this:
[{"firstname":"Alice","lastname":"Anonymous","dateOfBirth":"1980-01-01","phone":"001-100-200-3001","email":"alice.anonymous#gmail.com"},{"firstname":"Bob","lastname":"Anonymous","dateOfBirth":"1987-02-07","phone":"001-100-200-3002","email":"bob.anonymous#gmail.com"},{"firstname":"Calvin","lastname":"Anonymous","dateOfBirth":"1984-02-09","phone":"001-100-200-3003","email":"calvin.anonymous#gmail.com"},{"firstname":"Dirk","lastname":"Anonymous","dateOfBirth":"1982-05-01","phone":"001-100-200-3004","email":"dirk.anonymous#gmail.com"},{"firstname":"Elvin","lastname":"Anonymous","dateOfBirth":"1980-07-05","phone":"001-100-200-3005","email":"elvin.anonymous#gmail.com"},{"firstname":"Fancy","lastname":"Anonymous","dateOfBirth":"1990-02-01","phone":"001-100-200-3006","email":"fancy.anonymous#gmail.com"},{"firstname":"Greg","lastname":"Anonymous","dateOfBirth":"1984-01-09","phone":"001-100-200-3007","email":"greg.anonymous#gmail.com"},{"firstname":"Harry","lastname":"Anonymous","dateOfBirth":"1989-11-10","phone":"001-100-200-3008","email":"harry.anonymous#gmail.com"},{"firstname":"Issey","lastname":"Anonymous","dateOfBirth":"1950-01-01","phone":"001-100-200-3009","email":"issey.anonymous#gmail.com"},{"firstname":"Jack","lastname":"Anonymous","dateOfBirth":"1970-10-01","phone":"001-100-200-3010","email":"jack.anonymous#gmail.com"}]
And to split the results to be jQuery autocomplete compatible, I changed my client side js to this to map the incoming JSON to label and value or id (tried both id and label):
$("someSearchTermInputBox").autocomplete(
{
minLength: 2,
source: function (request, response)
{
$.ajax(
{
url: "/searchThatReturnsJSON",
data: {term: request.term},
dataType: "json",
success: function (data)
{
// alert (JSON.stringify (data)); <-- shows up correctly
// console.log (data);
response ($.map(data, function (item)
{
console.log (item.firstname);
return
{ id: item.firstname; value: item.lastname };
}));
}
});
},
});
My header is as follows (unchanged from the previous working version):
<script src="/js/jquery-ui-1.10.4/js/jquery-1.10.2.js" > </script>
<script src="/js/jquery-ui-1.10.4/js/jquery-ui-1.10.4.min.js" > </script>
<link rel="stylesheet" type="text/css" href="/js/jquery-ui-1.10.4/css/ui-lightness/jquery-ui-1.10.4.min.css" />
and now, my autocomplete box does not show up (it is not empty--it does not show up at all(I can see the Ajax interaction happening with the server on the debugger and on the server)). I am doing this in Chrome, so I fired up the debugger and I see the JSON correctly returned from the server. What HTML/CSS magic do I need to make sure my search results show up?
Where can I find the documentation on jQuery's web site (the jQuery autocomplete main website--the documentation does not talk about label or value, and certainly doesn't talk about the correct div elements to manipulate).
BTW, for the correct way to return a tuple into the response in the map call, is the delimiter a comma or a semicolon? Chrome gives me an error Uncaught SyntaxError: Unexpected token : which only went away when I changed the delimiter in the tuple returned to a semicolon.
Wow. I am just open mouthed in awe of the incredible syntax of JS. Anyway, the key issue was the use of the return statement {..} brackets. For a JS noob like me, this was countless hours down the drain trying to grasp any logic behind JS syntax and the use of K&R style brackets in a return statement (which I loathe as I am an Allman brackets guy).
Anyway, the code that got it to work finally was
$(document).ready (function ()
{
$("someSearchTermInputBox").autocomplete(
{
minLength: 2,
source: function (request, response)
{
$.ajax(
{
url: "/search",
data: {term: request.term},
dataType: "json",
success: function (jsonDataReceivedFromServer)
{
//alert (JSON.stringify (jsonDataReceivedFromServer));
// console.log (jsonDataReceivedFromServer);
response ($.map(jsonDataReceivedFromServer, function (item)
{
console.log (item.firstname);
// NOTE: BRACKET START IN THE SAME LINE AS RETURN IN
// THE FOLLOWING LINE
return {
id: item.firstname, value: item.lastname };
}));
}
});
},
});
});
Anyway, for folks who are Allman-indenters, I suggest using the following syntax which is Allman indentation friendly:
var someTuple =
{
value: item.firstname,
id: item.lastname
};
return someTuple;
A special shout out to the SO posts here and here. And a better post on the matter and curated (?) opinions here.
I hope this helps someone because I expect more people to run into this issue.

Trouble implementing a custom source with typeahead.js

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".

JS Post to Php Issue

I am stuck on this one. I think this should be simple but I am have no success. I am just trying to post a variable in a href tag over to a php function on a separate file. I am trying to test my JS with an alert box on success. I am getting no alert box, 'Success alert box test!'.
Any idea what I am doing wrong? I am guessing it is the problem is with my success function.
Thanks again! Much appreciated.
HTML:
Click here
JS:
$(document).ready(function() {
$( ".target" ).click(function(e) {
e.preventDefault();
var review_id = this.data('review');
$.ajax({
url : "vote_add.php",
type : "POST",
dataType: "json",
data : {
reviewId : review_id
},
success : function(data) {
if (data == 'success') {
alert('Success alert box test!');
} else {
alert(data);
}
}
});
});
});
Vote_add.php:
<?php
echo "success";
?>
$(document).ready(function() {
$( ".target" ).click(function(e) {
e.preventDefault();
var review_id = $(this).data('review');
$.ajax({
url : "/echo/json/",
type : "POST",
dataType: "json",
data : {
reviewId : review_id
},
success : function(data, status) {
if (status == 'success') {
alert('Success alert box test!');
} else {
alert(data);
}
}
});
});
});
You have error on line 5th this should be $(this) - the jQuery object and also you should use 2nd parameter for success which is status.
For easier debug just use FireBug or DevTools.
A couple things to improve your code and to my experience, what I believe you should change:
$(this).data('review') should work.
The .data() method allows us to attach data of any type to DOM elements in a way that is safe from circular references and therefore from memory leaks.
As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.
Your callback functions on the $.ajax() options you provide should be like .done(), .fail(), .always() and .then()
The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise.
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8.
Depending on the way your web service was setup, you should be able to set a breakpoint in your server code (I assume you have access to it or built it yourself?). If not possible, check the data object returned by .fail() with Firebug or any other developer toolbar and look for xhr.statusText or xhr[0].statusText (again, depending on how your web service returns it.)
Success: Type: Function( PlainObject data, String textStatus, jqXHR jqXHR )
A function to be called if the request succeeds. The function gets passed three arguments: The data returned from the server, formatted according to the dataType parameter; a string describing the status; and the jqXHR (in jQuery 1.4.x, XMLHttpRequest) object.
jqXHR.done(function( data, textStatus, jqXHR ) {});
An alternative construct to the success callback option, the .done() method replaces the deprecated jqXHR.success() method.
If you are using "POST" to the web service you might want to send it as a JSON string.
JSON.stringify() can assist with that. Some browser support is lacking but you can fix this with a polyfill
Last but not least, if you are sending json you want to expect json back. <? echo "success" ?> isn't going to cut it I'm afraid. Check out this post to see what I mean.
The json type parses the fetched data file as a JavaScript object and returns the constructed object as the result data. To do so, it uses jQuery.parseJSON() when the browser supports it; otherwise it uses a Function constructor. Malformed JSON data will throw a parse error (see json.org for more information). JSON data is convenient for communicating structured data in a way that is concise and easy for JavaScript to parse. If the fetched data file exists on a remote server, specify the jsonp type instead.
.
$(function () {
var ajaxOptions = {
url: "vote_add.php",
type: "POST",
dataType: "json"
};
$(".target").click(function (e) {
var options,
optionsData = {
reviewId: $(this).data('review')
};
e.preventDefault();
//options = $.extend({}, ajaxOptions, { data: optionsData });
options = $.extend({}, ajaxOptions, { data: JSON.stringify(optionsData) });
$.ajax(options).done(function (data) {
// success so use your data object
// are you looking for a property?
var myProperty = 'myProperty';
if (data.hasOwnProperty(myProperty)){
var myValue = data[myProperty];
}
}).fail(function (xhr) {
// do something on error
console.warn("myscript.js > " + xhr.statusText + ' ' + xhr.status);
}).always(function() {
// do something no matter what happens
});
});
});

Wrap Google Places Autocomplete Service through jQuery UI Autocomplete feature

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...

Categories

Resources