Skip to content

Instantly share code, notes, and snippets.

@mnishiguchi
Last active August 29, 2015 14:26
Show Gist options
  • Select an option

  • Save mnishiguchi/d831bb63ed4245467962 to your computer and use it in GitHub Desktop.

Select an option

Save mnishiguchi/d831bb63ed4245467962 to your computer and use it in GitHub Desktop.
Rails, jQuery-ui, Autocompleteで語句候補ドロップダウン ref: http://qiita.com/mnishiguchi/items/c3aab56e089071ac8d5c
ul.ui-autocomplete {
position: absolute;
list-style: none;
margin: 0;
padding: 0;
border: solid 1px #999;
cursor: default;
li {
background-color: #FFF;
border-top: solid 1px #DDD;
margin: 0;
padding: 2px 15px;
a {
color: #000;
display: block;
padding: 3px;
}
a.ui-state-hover, a.ui-state-active {
background-color: #FFFCB2;
}
}
}
require 'rails_helper'
feature "Autocomplete interface", type: :feature, js: true, driver: :poltergeist do
let(:user) { create(:user) }
before do
log_in_as user
visit root_path
end
describe "movings/new" do
before do
first(:link, "New moving").click
select "United States", from: "moving_country_to"
end
it "has US states suggestion data" do
expect(page).to have_css("div#moving_suggestions")
expect(page.find('div#moving_suggestions')["data-us-states"]).to have_content("Alabama")
end
it "shows autocomplete with a correct suggestion" do
fill_autocomplete("moving_state_to", with: "New")
expect(page).to have_content("New Mexico")
expect(page).to have_content("New York")
expect(page).not_to have_content("Alabama")
end
end
end
def fill_autocomplete(field, options = {})
fill_in field, with: options[:with]
page.execute_script %Q{ $('##{field}').trigger('focus') }
page.execute_script %Q{ $('##{field}').trigger('keydown') }
selector = %Q{ ul.ui-autocomplete li.ui-menu-item a:contains("#{options[:select]}") }
expect(page).to have_selector('ul.ui-autocomplete')
page.execute_script %Q{ $('#{selector}').trigger('mouseenter').click() }
end
jQuery -> # DOMが読み込まれたのを確認
$('#moving_state_from').autocomplete # 対象となるinputタグのID
source: #{us_states} # 語句候補の配列(Rubyコードから渡す場合)
jQuery -> # DOMが読み込まれたのを確認
$('#moving_state_from').autocomplete # 対象となるinputタグのID
source: ["breakfast", "lunch", "dinner"] # 語句候補の配列(直接記述場合)
# 選択された国名に応じて県名データを差し替える。
jQuery ->
$from = $('#moving_country_from')
$from.change ->
switch $from.children("option").filter(":selected").text()
when "United States" then params = { source: #{us_states} }
when "Japan" then params = { source: #{jp_prefectures} }
else params = { source: [] }
$('#moving_state_from').autocomplete(params)
:coffee
# 選択された国名に応じて県名データを差し替える。
jQuery ->
$from = $('#moving_country_from')
$from.change ->
switch $from.children("option").filter(":selected").text()
when "United States" then params = { source: #{us_states} }
when "Japan" then params = { source: #{jp_prefectures} }
else params = { source: [] }
$('#moving_state_from').autocomplete(params)
# 選択された国名に応じて県名データを差し替える。
jQuery ->
$from = $('#moving_country_from')
$from.change ->
switch $from.children("option").filter(":selected").text()
when "United States" then params = { source: #{us_states} }
when "Japan" then params = { source: #{jp_prefectures} }
else params = { source: [] }
$('#moving_state_from').autocomplete(params)
# 選択された国名に応じて県名データを差し替える。
jQuery ->
$from = $('#moving_country_from')
$from.change ->
switch $from.children("option").filter(":selected").text()
when "United States" then params = { source: #{us_states} }
when "Japan" then params = { source: #{jp_prefectures} }
else params = { source: [] }
$('#moving_state_from').autocomplete(params)
group :test do
gem 'rspec-rails'
gem 'capybara'
gem "poltergeist"
end
class Moving < ActiveRecord::Base
#...
# データをまとめて準備するメソッド
def autocomplete_suggestions
{
items: Hash[Ingredient.pluck(:name, :volume)],
rooms: Room.select(:name).pluck(:name),
categories: self.moving_items.select(:category).distinct.pluck(:category)
}
end
#...
end
# IDでタグを探し、dataメソッドでデータを取り出す。
jQuery ->
setVolume = (volume)->
$("#moving_item_volume").val(volume)
setSlider = (volume)->
$("#volume_slider").val(volume)
# Slider
document.getElementById('volume_slider').addEventListener 'change', ->
setVolume(document.getElementById('volume_slider').value)
# AutoComplete
$('#moving_item_name').autocomplete
source: Object.keys( $('#suggestions').data('items') )
select: (e, ui) =>
itemVolume = $('#suggestions').data('items')[ui.item.value]
setVolume(itemVolume)
setSlider(itemVolume)
$('#moving_item_room').autocomplete
source: $('#suggestions').data('rooms')
$('#moving_item_category').autocomplete
source: $('#suggestions').data('categories')
#...
def new
@moving_item = MovingItem.new
set_autocomplete_suggestions_and_render(:new)
end
def create
@moving_item = MovingItem.new(moving_item_params.merge(moving_id: current_moving))
if @moving_item.save
flash[:success] = "Created #{@moving_item.name}"
redirect_to @moving
else
set_autocomplete_suggestions_and_render(:new)
end
end
#...
private
#...
def set_autocomplete_suggestions_and_render(template)
@suggestions = @moving.autocomplete_suggestions
render template
end
#...
end
jQuery ->
setVolume = (volume)->
$("#moving_item_volume").val(volume)
setSlider = (volume)->
$("#volume_slider").val(volume)
# Slider
document.getElementById('volume_slider').addEventListener 'change', ->
setVolume(document.getElementById('volume_slider').value)
# AutoComplete
$('#moving_item_name').autocomplete
# IDでタグを探し、dataメソッドでデータを取り出す。
source: Object.keys( $('#suggestions').data('items') )
select: (e, ui) =>
itemVolume = $('#suggestions').data('items')[ui.item.value]
setVolume(itemVolume)
setSlider(itemVolume)
$('#moving_item_room').autocomplete
# IDでタグを探し、dataメソッドでデータを取り出す。
source: $('#suggestions').data('rooms')
$('#moving_item_category').autocomplete
# IDでタグを探し、dataメソッドでデータを取り出す。
source: $('#suggestions').data('categories')
#...
def show
#データを準備する
@itemNameSuggestions = Hash[ Ingredient.pluck(:name, :volume) ],
@roomSuggestions = Room.select(:name).pluck(:name),
@categorySuggestions = @moving.moving_items.select(:category).distinct.pluck(:category)
end
#...
module MovingsHelper
def us_states
["Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado",
"Connecticut", "Delaware", "District of Columbia", "Florida", "Georgia",
"Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky",
"Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota",
"Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire",
"New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota",
"Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina",
"South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia",
"Washington", "West Virginia", "Wisconsin", "Wyoming"]
end
end
-# ID付きの空タグにデータをdata属性に書き込む
= content_tag :div, "", id: "suggestions", data: @suggestions
= render 'add_form'
# ...
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
options = { js_errors: false }
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(app, options)
end
# ...
-# ID付きの空タグにデータをdata属性に書き込む
= content_tag :div, "", id: "suggestions", data: { items: @itemNameSuggestions,
rooms: @roomSuggestions, categories: @categorySuggestions }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment