Reputation: 5971
The Source callback of the autocomplete function takes an request and a response object as parameters. I couldn't find any useful information for what these object excatly are and what properties and methods they define.
Upvotes: 1
Views: 773
Reputation: 30666
I think the best way to understand what is function(request, response) {...}
is to go through the source code of the plugin itself.
I'll try to be as clear as possible, tell me if you need more details or explanations.
When you enter some value in the input, the plugin executes a "search" through the private method "_search"
_search: function(value) {
this.pending++;
this.element.addClass("ui-autocomplete-loading");
this.source({ term: value }, this.response);
}
Reading the last line, you can see the plugin expects the "source" property to be a function that it executes passing as
request: an object-literal with one property term
which will contain what was entered in the input
response: the plugin property response
. This property is a function that by default calls the private method "_response" which is responsible for showing the menu, filtering the list, closing the menu etc.
But reading the documentation, the source
option accepts an array or an url for remotely getting the values... so how does this work ?
The plugin initialize this.source
through the private method _initSource
:
_initSource: function() {
var self = this,
array, url;
if ($.isArray(this.options.source)) {
array = this.options.source;
this.source = function(request, response) {
response($.ui.autocomplete.filter(array, request.term));
};
} else if (typeof this.options.source === "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([]);
}
}
});
};
} else {
this.source = this.options.source;
}
},
You can see that in both cases the plugin ends up defining this.source
as function(request, response) {...}
if you provide an array, it executes the response
method to display the menu passing a filtered array using request.term
:
this.source = function(request, response) {
response($.ui.autocomplete.filter(array, request.term));
}
if you provide an url, it makes the ajax request and upon success, executes the response
method to display the returned data
:
success: function(data, status) {
if (this.autocompleteRequest === requestIndex) {
response(data);
}
},
otherwise, it uses the provided option value as it is
So when you call the plugin this way:
$(...).autocomplete({
source: function(request, response) { ... }
});
You're actually not providing the plugin with any data !
But you have the opportunity to gather the data the way you want (other that an array or an url), and still have access to the plugin functionnality through the parameters. You have the input content through request.term
and you can execute the response
callback to display the results.
Example ? The Autocomplete demo pages...
If you go to the Autocomplete Multiple values demo page, the jquery ui team uses this functionnality.
The data is stored in a javascript array var availableTags = [...];
And they define the source
option this way:
source: function(request, response) {
// delegate back to autocomplete, but extract the last term
response($.ui.autocomplete.filter(availableTags, extractLast(request.term)));
}
Filter the availableTags
array with a special treatment for handling multiple values in input
call the response
function to display the filtered array
Upvotes: 4