Tuesday, February 4, 2014

Rendering Autocomplete Results In Another Div

The autocomplete widget uses the menu widget to display the filtered results. It does this by creating the markup necessary to render the menu, then creates the widget. It would be nice if we weren't limited to displaying the autocomplete results inside a drop-down menu. Thing about a list view — one where the list of items take up the majority of the space on the page. Just above this list, you have the autocomplete input. So instead of just displaying the drop-down menu, as the widget normally would, we would like the existing list to be filtered. It's easy enough to extend the autocomplete with this capability.

Here's one such example. It replaces the default implementation of the _suggest() method — called internally by the widget any time the user types. But we don't want to actually perform the rendering in our replacement method. That would localize the autocomplete widget for a specific use case, and we don't want that. Instead, we want to provide our own extension point. The _suggest() method with look for a suggest option, and if it's a callable function, it'll call it, passing in the items to render.

_suggest: function( items ) {
            
    if ( $.isFunction( this.options.suggest ) ) {
        return this.options.suggest( items );
    }
            
    this._super( items );
            
}

This works for filtering down our list view using the autocomplete, but what about when there are no longer any results to display? When that happens, the widget calls the _close() method internally. For our purposes, we can hijack this method to remove the rendered results.

_close: function( e ) {
        
    if ( $.isFunction( this.options.suggest ) ) {
        this.options.suggest( [] );
        return this._trigger( "close", e );
    }
            
    this._super( e )
            
}

This method is almost like _suggest() — we're checking for the existence of a suggest option, and we're calling it with an empty array. This will clear any results that were previously rendered.