Twitter-Typeahead isn't offering suggestions

2019-07-04 08:00发布

问题:

I'm trying to use twitter-typeahead-rails. My intention is for instances of the model "User" to be suggested via a drop-down box as I type into the "#Typeahead" input box. However, nothing happens when I type.

Does anyone see anything that could be wrong with my code?

Gemfile:

gem 'twitter-typeahead-rails'

layouts/application.js:

//= require twitter/typeahead
//= require twitter/typeahead/bloodhound

config/routes.rb:

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

controllers/users_controller.rb:

def typeahead
  render json: User.where(name: params[:query])
end    

views/users/show.html.erb:

<input type="text" id="typeahead">
<script type="text/javascript">
  var bloodhound = new Bloodhound({
    datumTokenizer: function (d) {
      return Bloodhound.tokenizers.whitespace(d.value);
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,

    remote: '/typeahead/%QUERY', 
    limit: 50
  });
  bloodhound.initialize();

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

  $('#typeahead').bind('typeahead:selected', function(event, datum, name) {
    doSomething(datum.id);
  });
</script>

I'm not getting any errors in the web console, and all the necessary files are apparently being included:

Page source

<script data-turbolinks-track="true" src="/assets/twitter/typeahead.bundle.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/typeahead.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/twitter/typeahead/bloodhound.js?body=1"></script>

Network console:

回答1:

EDIT 1

Try wrapping the javascript code with this:

$(document).ready(function(){ 
  /* the bloodhound, typeahead and bind script */ 
})

There are probability that the element it was binding has not yet been initialized when the javascript code executed.

EDIT 2

Try changing from:

render json: User.where(name: params[:query])

Into:

q = params[:query]
render json: User.where('name LIKE ?', "%#{q}%")

# alternate syntax:
#render json: User.where('name LIKE :x', x: "%#{q}%")

# or when you want case-insensitive search:
#q = params[:query].to_s.downcase
#render json: User.where('LOWER(name) LIKE ?, "%#{q}%")

So the suggestion would give all with substring result, instead of exact match.

OLD ANSWER

This is not the correct answer, but it's worth to try. This works on debugging any web-app/ajax-app.

To debug, first, you'll need to use google-chrome, firefox or opera, right click on the window and do inspect element, now try to type on the typeahead input field. If there any red icon with number appearing? such as:

If there so, just visit the console tab:

and see, what part of the javascript that causing the error, fix it (or you could tell me in the comment).

Few possible errors are:

  • javascript syntax error
  • wrong ajax target

If there are no error, click on the network tab:

look up the ajax sent when typing the typeahead input field, first check the headers sub tab, make user that the Form Data are correct (you're sending the right message to the server).

Secondly check the response sub tab, is it correct or not? If it's incorrect (the server give wrong output/format), then the server side is at fault, check the source of controller/action that generates the response (see the rails log or headers sub tab). If its already correct, most likely the bug of the library.

We could not help you any more without specific error message, because I believe it'll took quite a time just to reproduce your code (installing ruby+rails+gems, setting up one table, create the model, and pasting stuff that you've wrote in the question).