Search and Top Navigation
#8221 closed enhancement (notabug)
Opened March 26, 2012 10:48PM UTC
Closed March 27, 2012 02:46AM UTC
Last modified March 27, 2012 12:26PM UTC
Pass function for options.source
Reported by: | dcarbone | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | 1.9.0 |
Component: | ui.autocomplete | Version: | 1.8.18 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
Hey all,
I have a form that I wanted to have multiple autocomplete fields on thus necessitating $("#blah, #blah2").autocomplete();, etc.
The issue is the URL I wish to use in the ajax call is different depending on which input box the user inputs data into.
The current methods which need to be changed are as follows:
_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", context: { 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; } },
and
_search: function( value ) { this.pending++; this.element.addClass( "ui-autocomplete-loading" ); this.source( { term: value }, this.response ); },
I propose a change to below:
_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" || typeof this.options.source === "function" ) { if (typeof this.options.source === "string") { url = this.options.source; } this.source = function( request, response ) { if (typeof this.options.source === "function") { url = this.options.source(request); request = {term : request.term }; } if ( self.xhr ) { self.xhr.abort(); } self.xhr = $.ajax({ url: url, data: request, dataType: "json", context: { 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; } },
and
_search: function( value ) { this.pending++; this.element.addClass( "ui-autocomplete-loading" ); this.source( { term: value , currentTarget: this.element }, this.response ); },
The main differences being that in the event that this.options.source is a function, that function is called each time by this.search and the modified parameters it passes to allow an element-specific determination of the URL.
This is a very rough hack I have done, but I believe the logic is sound. There might be additional methods which need to be changed to accommodate it, as this is a very rough implementation.
Attachments (0)
Change History (4)
Changed March 26, 2012 10:53PM UTC by comment:1
Changed March 27, 2012 02:46AM UTC by comment:2
resolution: | → invalid |
---|---|
status: | new → closed |
First of all, you can pass a function as the source. Second of all, you should just initialize your instances properly. If you need different settings for different elements, then initialize them separately, each with the proper settings.
Changed March 27, 2012 03:13AM UTC by comment:3
Why? It makes no sense to have every autocomplete field initialized separately. There are even other jQuery UI plugins that take full advantage of passing in multiple elements and setting up different functionality between the two. The calendar is a prime example of this. Why should this plugin require you to have 90% redundant code when initiating more than 1 autocomplete field? Makes no sense to me.
Also, you can pass a function in but it is sort of pointless when using more than 1 autocomplete field as the object passed to that function would ONLY contain {term : "string"}, not the source element. Which, again, is fine if you only setup a single autocomplete field, but with multiple you need to know which element is triggering the method.
It seems very static to me.
Changed March 27, 2012 12:26PM UTC by comment:4
I'm sorry you feel that way, that's just how it is. You'll need to make a better case than "it makes no sense" when arguing against a design that's widely accepted and used pretty much everywhere.
a slight modification to _sourceInit:
Either way, the request variable will need to be redefined in this case.