Search code examples
ruby-on-railsruby-on-rails-4searchautocompletetypeahead.js

Getting typeahead to work with rails search


I had typeahead and search working in my rails 4 app with typeahead v0.10.5 but since updating to v0.11.1 it broke. I orginally got the code from various answers on this site without really understanding what is going on. I have it mostly working now but the dropdown is populating with text of all attributes from my model and not just names like I want it to. I want to make sure I am doing things correctly and hopefully gain a better understanding of what's going on.

item.rb

  def self.search(search)
    if search
      where(['lower(name) LIKE ?', "%#{search}%"])
    else
      Item.all
    end
  end

items_controller.rb

  def index
    @items= Item.search(params[:query])
  end

  def typeahead
    render json: Item.where('name ilike ?', "%#{params[:query]}%")
  end

_header.html.erb

<div role="search">
  <%= form_tag items_path, class: 'navbar-form', method: :get do %>
    <div class="form-group">
      <%= text_field_tag :query, params[:query], id: 'typeahead', class: 'search-input form-control',
                                        placeholder: 'Search items' %>
    </div>
    <span class="search-icon">
      <%= button_tag "<i class='fa-navbar fa fa-search'></i>".html_safe, name: nil, class: 'search-button' %>
    </span>
  <% end %>
</div>
.
.
.
<script>
$(document).ready(function(){
    var bloodhound = new Bloodhound({
      datumTokenizer: function (d) {
        return Bloodhound.tokenizers.whitespace(d.value);
        },
      queryTokenizer: Bloodhound.tokenizers.whitespace,
      limit: 10,  
      remote: {url: '/typeahead/%QUERY',
               wildcard: '%QUERY'}  
    });
    bloodhound.initialize();

    $('#typeahead').typeahead(null, {
      name: 'name',
      source: bloodhound.ttAdapter()
    });

    $('#typeahead').bind('typeahead:selected', function(event, datum, name) {
      window.location.href = '/items/' + datum.id;
    });
  });
</script>

config/routes.rb

get 'typeahead/:query', to: 'items#typeahead'
  1. The source of my data comes from my model based on the user input. Is there any place for prefetch in my example?

  2. In the remote I have the url set to '/typeahead/%QUERY'. In other examples I have seen something like '/typeahead?q=%QUERY'. What is the difference?

  3. What is the prepare and wildcard options in bloodhound? I have read the api explanation here but still don't understand.


Solution

  • The problem with the suggestions dropdown displaying properly was because I was missing displayKey: 'name' as a typeahead option. Adding this fixed my problem.

    $('#typeahead').typeahead(null, {
      name: 'name',
      displayKey: 'name',
      source: bloodhound.ttAdapter()
    });