Episodes

Resources

Summary

# Gemfile
source 'https://rails-assets.org' do
  gem 'rails-assets-jquery'
  gem 'rails-assets-jquery-ui'
end

# application.js
//= require jquery
//= require jquery-ui

# application.css
 /*
 *= require jquery-ui
 *= require_tree .
 *= require_self
 */

.product .description {
  color: #b0bec5;
  font-size: 80%;
  font-weight: normal;
}

.ui-widget-content.ui-autocomplete{
  max-width: 350px;
}

input {
  height: 30px;
  width: 300px;
  padding-left: 15px;
}

# autocomplete.coffee
@autoComplete = ->
  $('.autocomplete').each ->
    $(this).autocomplete
      source: $(this).data('source')
      minLength: 2
    $(this).autocomplete('instance')._renderItem = (ul, item) ->
      $('<li>').append(item.label).appendTo ul

$(document).on('turbolinks:load', @autoComplete);

# app/services/autocomplete/application_autocomplete.rb
module Autocomplete
  class ApplicationAutocomplete
    delegate :params, to: :@view

    def initialize(view)
      @view = view
    end

    def as_json(options = {})
      [].tap do |column|
        results.each do |result|
          json = {}
          json[:label] = result_partial(result)
          json[:value] = result_value(result)
          column << json
        end
      end
    end

  end
end

# app/services/autocomplete/product.rb
module Autocomplete
  class Products < ApplicationAutocomplete

    private 

    def result_partial(product)
      ApplicationController.new.render_to_string(partial: 'products/autocomplete', 
                                                 locals: { product: product }).html_safe
    end

    def result_value(product)
      product.name
    end

    def results
      @results ||= Product.where('NAME LIKE :query', query: "%#{params[:term]}%").limit(5)
    end

  end
end

# routes.rb
Rails.application.routes.draw do
  resources :products do
    collection do
      get :autocomplete
    end
  end
  root to: 'welcome#index'
end

# welcome/index.html.erb
<%= text_field_tag :product, "", class: 'autocomplete', data: { source: autocomplete_products_path } %>

# products/_autocomplete.rb
<%= content_tag :div, class: 'product' do %>
  <%= product.name %>
  <% product.rating.times do |rate| %>
    <%= image_tag('star.png') %>
  <% end %>
  <%= content_tag :div, class: 'description' do %>
    <%= product.description %>
  <% end %>
<% end %>

# products_controller.rb
  def autocomplete
    render json: Autocomplete::Products.new(view_context)
  end