Building data sources using select options
Sometimes, using an array as the source of data for autocomplete widgets isn't the best option. For example, if we already have a select
element in our user interface, it would make sense to reuse the options in that element to make an autocomplete. Otherwise, we would have to not only design some new code to build the array data source, but we would also have to remove the existing select
element.
Getting ready
Let's put together some basic markup for this example. Typically, the autocomplete widget expects an input
as its element. Instead, we're going to give it a select
element with some simple options.
<div> <label for="autocomplete">Items: </label> <select id="autocomplete"> <option>First Item</option> <option>Second Item</option> <option>Third Item</option> <option>Fourth Item</option> </select> </div>
How to do it...
We'll go ahead and extend the capabilities of the autocomplete widget so that it knows how to handle the select
elements. After which, we're able to target our select
element with the autocomplete widget.
( function( $, undefined ) { $.widget( "ab.autocomplete", $.ui.autocomplete, { inputClasses: "ui-widget ui-widget-content ui-corner-all", _create: function() { if ( this.element.is( "select" ) ) { var self = this; this.original = this.element.hide(); this.element = $( "<input/>" ).insertAfter( this.original ); this.options.source = function( request, response ) { var filter = $.ui.autocomplete.filter, options = self.original.find( "option" ), result = options.map( function() { return $( this ).val(); }); response( filter( result, request.term ) ); }; } this._super( "_create" ); }, _destroy: function() { this._super( "_destroy" ); this.element.remove(); this.original.show(); } }); })( jQuery ); $( function() { $( "#autocomplete" ).autocomplete(); });
Now you should see something that looks like a plain old autocomplete—no select
element in sight. Further, if you try using the autocomplete, you'll see that the options presented are the same as those in the select
element's options.
How it works...
Here, we need to add support to the autocomplete widget for select
elements; we do this at the beginning of our custom _create()
implementation. If we're dealing with a select
element, the first thing we do is hide it and store a reference to it in the original
attribute. Remember, we're only interested in the data source the select
element has to offer by means of its options
—we don't want to actually display the select
. Instead, we're replacing the select
with an input
element since this is how the user types and the widget completes.
The source
option of the autocomplete widget is how we're able to specify a custom function that returns the source data to be used. In our case, we're providing a function that grabs the values from each select option
. Recall that the select
element was stored in the original
attribute earlier. We're using the jQuery map()
utility function here to turn the select
options into an array that autocomplete can use. The filter()
function gets applied, and the response()
function is sent to the drop-down menu.
When the widget is destroyed, we'd like to restore the original select
element, since this is what we replaced. The original element gets displayed once again in our customized implementation of _delete()
—this happens after calling the original _delete()
method to perform routine cleanup tasks. The input
element we created is also destroyed here.