How to add dynamic select menu in search form

2019-08-29 12:21发布

I followed this railscast and successfully able to display countries and cities as dynamic select menu to choose the country and city on adding new profile. I have created a controller "search_controller.rb" with index action and a view "index.html.erb" in app/views/search. Now i want to create a search form in app/views/search/index.html.erb which have

  1. Autocomplete text field to search by profile's subjects (almost 400 subjects in this table)
  2. Country and city dynamic select menu to search by profile's country and city.

app/model/profile.rb

has_many :categorizations
has_many :subjects, through: :categorizations

belongs_to :country
belongs_to :city

app/model/subject.rb

has_many :categorizations
has_many :profiles, through: :categorizations

app/model/categorization.rb

belongs_to :profile
belongs_to :subject

app/model/country.rb

has_many :cities
has_many :profiles

app/model/city.rb

belongs_to :country
has_many :profiles

app/views/profiles/_form.html.erb

<div class="field">
  <%= f.label :country_id %><br />
  <%= f.collection_select :country_id, Country.order(:name), :id, :name, include_blank: true %>
</div>

app/assets/javascripts/profiles.js.coffee

$('#profile_city_id').parent().hide()
cities = $('#profile_city_id').html()
$('#profile_country_id').change ->
country = $('#profile_country_id :selected').text()
escaped_country = country.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1')
options = $(cities).filter("optgroup[label='#{escaped_country}']").html()
if options
  $('#profile_city_id').html(options)
  $('#profile_city_id').parent().show()
else
  $('#profile_city_id').empty()
  $('#profile_city_id').parent().hide()

1条回答
不美不萌又怎样
2楼-- · 2019-08-29 13:19

Here is my solution with sunspot-solr for search and twitter-typeahead-rails for autocomplete. after adding searchable block in model i used following code for my app. I loaded my subjects list in local storage by twitter typeahead because it will not change but you can use json if you need.

app/controller/search_controller.rb

def index
  @search = Profile.search do
    fulltext params[:search]
    with(:city_id, params[:city]) if params[:city].present?
  end
  @profiles = @search.results
end

app/views/search/index.html.erb

<%= text_field_tag :search, params[:search], :class => 'typeahead' %>
<div class="field">
  <%= select_tag :country, options_from_collection_for_select(Country.all, :id, :name, params[:country]), include_blank: true %>
</div>
<div class="field">
  <%= select_tag :city, option_groups_from_collection_for_select(Country.order(:name), :cities, :name, :id, :name, params[:city]), include_blank: true %>
</div>
<%= submit_tag "search", :name => nil, :class => 'btn btn-default' %>

app/assets/javascripts/profiles.js.coffee

$('#city').parent().hide()
cities = $('#city').html()
$('#country').change ->
  country = $('#country :selected').text()
  escaped_country = country.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g, '\\$1')
  options = $(cities).filter("optgroup[label='#{escaped_country}']").html()
  if options
    $('#city').html(options)
    $('#city').parent().show()
  else
    $('#city').empty()
    $('#city').parent().hide()

$('.typeahead').typeahead({                                
  local: ["3D Design", "Architecture", "Chemical engineering", ...]
  limit: 10                                                                   
});
查看更多
登录 后发表回答