-
Notifications
You must be signed in to change notification settings - Fork 78
Autocompletion
scoped_search can autocomplete a search query, returning lists of fields and possible values to the user for selection in a search UI.
Every scoped_search-enabled model has a .complete_for
method that takes the partial search string and returns an array of possible searches.
At first it returns a list of possible field names and prefix operators:
> User.complete_for('')
=> [" first_name ", " last_name ", " not", " has"]
Then with the field name supplied, it can supply operators:
> User.complete_for('first_name ')
=> ["first_name = ", "first_name != ", "first_name ~ ", "first_name !~ ", "first_name ^ ", "first_name !^ "]
And with an operator, it can supply values:
> User.complete_for('first_name =')
=> ["first_name = John", "first_name = Jane"]
Customize search filter, in this example all returned values will be filtered by current user:
> model.complete_for(params[:search], value_filter: { user_id: current_user.id })
A scopedSearch
function is added via the asset pipeline to jQuery to add autocompletion support to text inputs using a categorized autocomplete.
To use the auto completer JavaScript-based UI you'll need to include jquery-ui. There are several ways to include jquery-ui, for example, add to the Gemfile:
gem 'jquery-rails'
gem 'jquery-ui-rails'
To activate autocompletion on all elements with the autocomplete-input class, call:
$(".autocomplete-input").scopedSearch();
scopedSearch() takes an options hash with these options:
-
'delay'
- see jQuery option delay -
'minLength'
- see jQuery option minLength -
'source'
- see jQuery option source, defaults to an AJAX query to the data-url attribute of the element passing "search="
Unless source
is given, the element should have a data-url
attribute set to an AJAX-capable URL, that should return results using model.complete_for
.
In the view:
<%= text_field_tag("search", value,
:class => 'autocomplete-input form-control',
:autocomplete => 'off',
:placeholder => 'Search ..',
:'data-url' => autocomplete_user_path)
%>
On the page load in application JS:
//= require jquery-ui/completer
$(function() {
$(".autocomplete-input").scopedSearch();
});
In your application.css, require the corresponding CSS module:
*= require jquery-ui/completer
In the controller:
def autocomplete
begin
model = controller_name.classify.constantize
@items = model.complete_for(params[:search])
@items = @items.map do |item|
category = (['and','or','not','has'].include?(item.to_s.sub(/^.*\s+/,''))) ? _('Operators') : ''
part = item.to_s.sub(/^.*\b(and|or)\b/i) {|match| match.sub(/^.*\s+/,'')}
completed = item.to_s.chomp(part)
{:completed => CGI.escapeHTML(completed), :part => CGI.escapeHTML(part), :label => item, :category => category}
end
rescue ScopedSearch::QueryNotSupported => e
@items = [{:error => e.to_s}]
end
render :json => @items
end