Theopap
Theopap

Reputation: 755

Rails: jquery autocomplete in a search form

I'm trying to implement jquery autocomplete in a search, but the autocomplete dropdown suggestion doesn't appear.

This is the basic search I have inside the item.rb:

def self.search(term)
  return where("0=1") if term !~ /\w{4}/
  where("lower(title) LIKE lower(:term)", term: "%#{term}%")
end

and inside the application.html.erb I have <%= javascript_include_tag 'application' %>

Now this is the setup I have regarding the autocomplete.... I have a sass bootstrap setup on my app and this is what I have done thus far:

Installed the gem 'jquery-ui-sass-rails'.

Added //= require jquery.ui.all in my application.js file.

Added the following jQuery inside the items.cooffee file

jQuery ->
  $('#search').autocomplete
    source: "/search_suggestions"

Created the controller and model:

rails g resource search_suggestion term popularity:integer
rails db:migrate

class SearchSuggestionsController < ApplicationController
  def index
    render json: SearchSuggestion.terms_for(params[:term])
  end
end

class SearchSuggestion < ApplicationRecord

  def self.terms_for(prefix)
    suggestions = where("term like ?", "#{prefix}_%")
    suggestions.order("popularity desc").limit(10).pluck(:term)
  end

  def self.index_items
    Item.find_each do |item|
      index_term(item.title)
      item.title.split.each { |t| index_term(t) }
      index_term(item.category)
    end
  end

  def self.index_term(term)
    where(term: term.to_s.downcase.gsub(/\s+/, '')).first_or_initialize.tap do |suggestion|
      suggestion.increment! :popularity
    end
  end
end

created and tested the following rake task

search_suggestions.rake

namespace :search_suggestions do
  desc "Generate search suggestions from items"
  task :index => :environment do
    SearchSuggestion.index_items
  end
end

and finally the search form looks like this:

<%= form_tag items_path, method: :get do %>
   <%= text_field_tag :search, params[:search], autofocus: true, placeholder: 'Enter keyword', data: {autocomplete_source: items_path} , :class=> "search-query search_size" %>
      <%= submit_tag 'Search', :style => "display: none;" %>

Any ideas what I might be missing here?

Update 1

I changed the gem to gem 'jquery-ui-rails'

and have this inside the application.js file:

//= require rails-ujs
//= require jquery-ui/widgets/autocomplete
//= require bootstrap-sprockets
//= require_tree

and if I load the page and inspect the source the jQuery's are loaded it seems, so I have no idea what wrong!!

<script src="/assets/rails-ujs.self-817d9a8cb641f7125060cb18fefada3f35339170767c4e003105f92d4c204e39.js?body=1"></script>
<script src="/assets/jquery-ui/version.self-c8e3d1203da26ea7efdf83c1eabb3f0ba55cb68e463f5ccf0d77bd15ce6a8e61.js?body=1"></script>
<script src="/assets/jquery-ui/keycode.self-ad63cd20acf49dd333bbbc537454d7d475bd610eb5b88de0dca009f0c3d314b1.js?body=1"></script>
<script src="/assets/jquery-ui/position.self-1b49c8c521e67a4a88bfdad6b4d944d33686d25009a0e40a1e170acdd7b6962a.js?body=1"></script>
<script src="/assets/jquery-ui/safe-active-element.self-a1f1a1a7dae3269ce03f6fffb2dcc9b4a7490f5d546c65d54417bec3be24b668.js?body=1"></script>
<script src="/assets/jquery-ui/unique-id.self-66e85ac85cd0b6b8b1bb89369fc65f608f716869dc0930862a8d421a57a9580a.js?body=1"></script>
<script src="/assets/jquery-ui/widget.self-fca20bcec06d192f97cffa6e734e24360e227237b8ae7d7e7e60754df7d5444f.js?body=1"></script>
<script src="/assets/jquery-ui/widgets/menu.self-0730fe713007bd93e6db569352a20ed92448299505ff6f525bc0dc6dd488254e.js?body=1"></script>
<script src="/assets/jquery-ui/widgets/autocomplete.self-6a89d7a43741ec810ef95de143a7c0297e2e4368ebecff64493ebb7a9ac3a524.js?body=1"></script

Upvotes: 0

Views: 1276

Answers (1)

fabOnReact
fabOnReact

Reputation: 5942

This is the form erb code

<%= form_tag products_path, method: :get do %> 
    <%= text_field_tag :search, params[:search], size: 30 %> 
<%= submit_tag "Search", name: nil %>

for this element

enter image description here

Inspect that element with your developer tolls and check the id generated from the erb code <%= text_field_tag :search, params[:search], size: 30 %>

This is just an example, I don't have your app. On chrome you simply use the shortcut CTRL + SHIFT + c and then click with the mouse on the element you want to inspect (in this case that input form)

The developer toolbar pops up already selecting that div, you can also do right click and then inspect, with the mouse

enter image description here

I believe text_field_tag :search should have id: 'search', but you are getting error in the console about the variable.

Test this on your chrome developer toolbar console $('#search') and see if it return an error or the Javascript object associated to the <input id='search'>

Maybe there is another reason. You are wondering if this is connected to jquery-ui, then check if you have the jquery-ui assets in the asset pipeline in the sources of your chrome developer tools

enter image description here

Or go in your console, test the jquery-ui effect in your page

$( "div" ).effect( "bounce", "slow" );

Debug this,

first. find out if you can trigger a breakpoint in this code

$('#search').autocomplete 

second. test if you can trigger a breakpoint in this code

class SearchSuggestionsController < ApplicationController
  def index
    binding.pry
    render json: %w[foo bar]
  end
end

Also you need to understand that to achieve this, your app is using AJAX asynchronous request, so that your page without refreshing calls the server and gets the response json: %w[foo bar] with the element to display in the search suggestions

This is why you are calling source: "/search_suggestions" in your jquery-ui effect, because that is where you client/jquery is expecting to retrieve the search results

Jquery will hit your server at the url source: "/search_suggestions" and your server will return foo bar in json format, without reloading the webbrowser, jquery will display it

This is explained well on the ruby on rails documentation and in several videos

https://www.youtube.com/watch?v=I0crKwijP0Q

https://www.youtube.com/watch?v=FBxVN7U1Qsk

https://www.youtube.com/watch?v=fEYx8dQr_cQ&t=4s

I could keep writing and write you the code to fix quickly your problem, the reality is that you will never become auto-sufficient if you do not do the required training and understand the concepts and architecture behind this functionality

AJAX is supercool and I really wish you to enjoy those vides

Good luck Bye Fabrizio

Upvotes: 1

Related Questions