在Rails中,如何为Rails设置Twitter Typeahead.js gem?

时间:2015-05-03 21:35:18

标签: ruby-on-rails twitter-typeahead

bootstrap-typeahead-rails gem's README将问题提交至Twitter's typeahead.js README。这还有很多不足之处。

Stack Overflow answer提供了twitter-typeahead-rails gem的详细说明。我希望看到Thing宝石的类似内容。

2 个答案:

答案 0 :(得分:13)

这是我的向导。它遵循@ihaztehcodez's example。此示例假定模型为things,并将表单添加到索引视图,以便按模型的name属性搜索# Gemfile # Typeahead gem gem 'bootstrap-typeahead-rails' # Optional gems gem 'searchlight' gem 'slim-rails'

一些注意事项:

  • 我正在使用Rails 4(4.2.1)。
  • 对于搜索查询,我使用的是Searchlight gem
  • 对于模板,我使用的是slim-rails gem
  • 样式留作开发人员的练习。

将gem添加到gemfile

# app/assets/stylesheets/application.scss

  *= require bootstrap-typeahead-rails

在资产清单

中包含预先输入文件

样式表(SASS)

# app/assets/javascripts/application.js

//= require bootstrap-typeahead-rails
//= require_tree .

的Javascript

# config/routes.rb

  get 'things/typeahead/:query' => 'things#typeahead'

将先行路线添加到路线文件

# app/assets/javascripts/things.js

var onReady = function() {

  // initialize bloodhound engine
  var searchSelector = 'input.typeahead';

  var bloodhound = new Bloodhound({
    datumTokenizer: function (d) {
      return Bloodhound.tokenizers.whitespace(d.value);
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,

    // sends ajax request to remote url where %QUERY is user input
    remote: '/things/typeahead/%QUERY',
    limit: 50
  });
  bloodhound.initialize();

  // initialize typeahead widget and hook it up to bloodhound engine
  // #typeahead is just a text input
  $(searchSelector).typeahead(null, {
    displayKey: 'name',
    source: bloodhound.ttAdapter()
  });

  // this is the event that is fired when a user clicks on a suggestion
  $(searchSelector).bind('typeahead:selected', function(event, datum, name) {
    //console.debug('Suggestion clicked:', event, datum, name);
    window.location.href = '/things/' + datum.id;
  });
};

添加typeahead javascript代码

# app/controllers/things_controller.rb

  # GET /things
  # GET /things.json
  def index
    @search = ThingSearch.new(search_params)
    @things = search_params.present? ? @search.results : Thing.all
  end

  # GET /things/typeahead/:query
  def typeahead
    @search  = ThingSearch.new(typeahead: params[:query])
    render json: @search.results
  end

  private

  def search_params
    params[:thing_search] || {}
  end

将相关方法/操作添加到控制器

# app/views/things/index.html.slim

div.search.things
  = form_for @search, url: things_path, method: :get do |f|
    div.form-group.row
      div.col-sm-3
      div.col-sm-6
        = f.text_field :name_like, {class: 'typeahead form-control',
            placeholder: "Search by name"}
        = f.submit 'Search', {class: 'btn btn-primary'}
      div.col-sm-3.count
        | Showing <strong>#{@things.length}</strong> Thing#{@things.length != 1 ? 's' : ''}

将搜索表单添加到索引视图(使用SLIM gem)

# app/searches/thing_search.rb

class ThingSearch < Searchlight::Search
  search_on Thing.all

  searches :name_like, :typeahead

  # Note: these two methods are identical but they could reasonably differ.
  def search_name_like
    search.where("name ILIKE ?", "%#{name_like}%")
  end

  def search_typeahead
    search.where("name ILIKE ?", "%#{typeahead}%")
  end
end

创建Searchlight搜索类

如果您不想使用Searchlight,请使用模型中的ActiveRecord查询界面。

PATH=C:\Ruby200\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem

答案 1 :(得分:3)

@ plenwell的回答已经过时了。以下是我如何使用它:

我正在使用:

  • Bootstrap v3.3.6
  • bloodhound 0.11.1
  • bootstrap3-typeahead 3.1.0
  • jQuery 2.2.0

我的模型名为Destination

应用程序/模型/ destination_search.rb:

class DestinationSearch < Searchlight::Search

  def base_query
    Destination.all
  end

  def search_typeahead
    query.where("name ILIKE", "%#{typeahead}%")
  end

end

控制器:

class DestinationsController < APIController

  def typeahead
    render json: DestinationSearch.new(typeahead: params[:query]).results
  end

end

JS:

var bloodhound = new Bloodhound({
  datumTokenizer: function (d) {
    return Bloodhound.tokenizers.whitespace(d.value);
  },
  queryTokenizer: Bloodhound.tokenizers.whitespace,

  remote: {
    url: '/api/destinations/typeahead?query=%QUERY',
    wildcard: "%QUERY",
  },
  limit: 10
});
bloodhound.initialize();

$(document).ready(function () {
  $(".destination-typeahead").typeahead({
    source: function (query, process) {
      return bloodhound.search(query, process, process);
    },
  });
});

并在视图中:

<%= text_field_tag :destination, class: "destination-typeahead" %>

感觉有点hacky我将process方法传递到bloodhound.search两次 - 这是因为猎犬#search takes two callbacks as arguments,一个处理缓存/预取的方法数据和处理通过AJAX动态提取的数据的数据。我可能没有正确使用#search 100%,但这种方法有效,而且这只是一个简单的开始。