Ruby on Rails - Simple Form autocomplete association search

和自甴很熟 提交于 2021-01-27 07:35:40

问题


I've a form in a basic task management app which allows Tasks to be assigned to Users (task belongs_to user). I'm using Simple Form for this.

Currently, the association is populated in the typical manner, with a dropdown list of users as such: <%= f.association :user, label_method: :name, value_method: :id, include_blank: false %>.

However, as the number of Users grows, I'm looking to change this to an autocomplete form field to find users. I've tried following the Railscast on the subject, though it doesn't use Simple Form and isn't working on my implementation.

Here's my form, model and .coffee code:

Form

<%= simple_form_for @task do |f| %>
  ...
  <%= f.input :user_name, as: :search, data: 
      {autocomplete_source: User.pluck(:name)} %>
  ...
  <%= f.button :submit %>
<% end %>

Model

# Virtual attribute for autocomplete form field
  def user_name
    user.try(:name)
  end

  def user_name=(name)
    self.user = User.find_by_name(name) if name.present?
  end

tasks.coffee

jQuery ->
  $('#task_user_name').autocomplete
    source: $('#task_user_name').data('autocomplete-source')

This generates the following HTML:

<input class="string search optional form-control 
ui-autocomplete-input ui-autocomplete-loading" type="search" 
value="Robert Strong" name="task[user_name]" id="task_user_name" 
autocomplete="off">

Though the following error in the dev tools console:

Uncaught TypeError: this.source is not a function

Concerned about the autocomplete="off" within the HTML and can't imagine the TypeError helps much!

I'm stumped, so would greatly appreciate any advice on getting this working! Thanks in advance, let me know what you think, Steve.


回答1:


autocomplete_source is expecting an array or a URL that when called returns JSON with the results that match the query. http://api.jqueryui.com/autocomplete/#option-source

Right now you have

  <%= f.input :user_name, as: :search, data: 
  {autocomplete_source: User.pluck(:name)} %>

Thats probably going to return a string for javascript. So you could change it to something like:

  <%= f.input :user_name, as: :search, data: 
  {autocomplete_source: User.pluck(:name).to_json} %>

And then parse that JSON when setting up your autocomplete:

jQuery ->
  $('#task_user_name').autocomplete
    source: JSON.parse($('#task_user_name').data('autocomplete-source'))

In the long run though (when you have a lot of users) this will impact the load time of your page significantly. You should really instead follow that railscast and put a URL as the autocomplete source:

  <%= f.input :user_name, as: :search, data: 
  {autocomplete_source: users_path} %>

Make sure to add the json render path to the index action on your users controller.

If your index action is used for other things too you can use respond_to:

# users_controller
def index
  @users = User.order(:name)
  @users = @users.where("name like ?", "%#{params[:term]}%") if params[:term]

  respond_to do |format|
    format.html  # index.html.erb
    format.json  { render :json => @users.map(&:name) }
  end
end



回答2:


In addition to Oliver's answer I had to:

<%= f.input :user_name, as: :search, input_html: {class: 'ui-autocomplete-input', data: {autocomplete_source: users_path} }%>

To make it work with Simple_Form.



来源:https://stackoverflow.com/questions/29779009/ruby-on-rails-simple-form-autocomplete-association-search

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!