Luke
Luke

Reputation: 5971

What is the request object exactly of the source callback?

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

Answers (1)

Didier Ghys
Didier Ghys

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.

1. What is "source"

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.


2. Using the "source" option

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




3. When passing a function(request, response) as "source" option value

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)));
}
  1. Filter the availableTags array with a special treatment for handling multiple values in input

  2. call the response function to display the filtered array

Upvotes: 4

Related Questions