Ruby on Rails - 简单表单自动完成关联搜索

SRa*_*ack 3 forms jquery autocomplete ruby-on-rails simple-form

我在基本任务管理应用程序中有一个表单,允许将任务分配给用户(任务belongs_to用户).我正在使用Simple Form.

目前,该关联以典型方式填充,其中包含用户下拉列表:<%= f.association :user, label_method: :name, value_method: :id, include_blank: false %>.

但是,随着用户数量的增长,我希望将其更改为自动填充表单字段以查找用户.我已经尝试过关于这个主题Railscast,虽然它没有使用Simple Form而且没有在我的实现上工作.

这是我的表单,模型和.coffee代码:

形成

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

模型

# 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
Run Code Online (Sandbox Code Playgroud)

tasks.coffee

jQuery ->
  $('#task_user_name').autocomplete
    source: $('#task_user_name').data('autocomplete-source')
Run Code Online (Sandbox Code Playgroud)

这会生成以下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">
Run Code Online (Sandbox Code Playgroud)

虽然dev工具控制台中出现以下错误:

Uncaught TypeError: this.source is not a function
Run Code Online (Sandbox Code Playgroud)

关注autocomplete="off"HTML内部并无法想象TypeError有多大帮助!

我很难过,所以非常感谢任何关于让这个工作的建议!先谢谢你,让我知道你的想法,史蒂夫.

Oli*_*der 10

autocomplete_source期望一个数组或URL在被调用时返回JSON,其结果与查询匹配.http://api.jqueryui.com/autocomplete/#option-source

现在你有

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

多数民众赞成可能会为javascript返回一个字符串.所以你可以改成它:

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

然后在设置自动完成时解析该JSON:

jQuery ->
  $('#task_user_name').autocomplete
    source: JSON.parse($('#task_user_name').data('autocomplete-source'))
Run Code Online (Sandbox Code Playgroud)

从长远来看(当你有很多用户时),这将显着影响页面的加载时间.您应该真正关注该railscast并将URL作为自动完成源:

  <%= f.input :user_name, as: :search, data: 
  {autocomplete_source: users_path} %>
Run Code Online (Sandbox Code Playgroud)

确保将json渲染路径添加到用户控制器上的索引操作.

如果您的索引操作也用于其他事情,您可以使用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
Run Code Online (Sandbox Code Playgroud)