Ruby on Rails - 简单表单自动完成关联搜索
Ruby on Rails - Simple Form autocomplete association search
我在基本任务管理应用程序中有一个表单,允许将任务分配给用户(任务 belongs_to 用户)。我为此使用简单表格。
目前,关联以典型方式填充,用户下拉列表如下:<%= f.association :user, label_method: :name, value_method: :id, include_blank: false %>
。
但是,随着用户数量的增加,我希望将其更改为自动完成表单字段以查找用户。我已经尝试遵循 Railscast on the subject,尽管它不使用简单形式并且在我的实现中不起作用。
这是我的表格、模型和 .coffee 代码:
表格
<%= simple_form_for @task do |f| %>
...
<%= f.input :user_name, as: :search, data:
{autocomplete_source: User.pluck(:name)} %>
...
<%= f.button :submit %>
<% end %>
型号
# 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')
这会生成以下 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">
尽管在开发工具控制台中出现以下错误:
Uncaught TypeError: this.source is not a function
担心 HTML 中的 autocomplete="off"
,无法想象 TypeError 有多大帮助!
我很困惑,所以非常感谢任何关于如何让它工作的建议!提前致谢,让我知道你的想法,史蒂夫。
autocomplete_source 需要一个数组或 URL,当调用 returns JSON 时,结果与查询匹配。 http://api.jqueryui.com/autocomplete/#option-source
现在你有
<%= f.input :user_name, as: :search, data:
{autocomplete_source: User.pluck(:name)} %>
那可能是 return javascript 的字符串。所以您可以将其更改为:
<%= f.input :user_name, as: :search, data:
{autocomplete_source: User.pluck(:name).to_json} %>
然后在设置自动完成时解析 JSON:
jQuery ->
$('#task_user_name').autocomplete
source: JSON.parse($('#task_user_name').data('autocomplete-source'))
但在较长的 运行 中(当您有很多用户时)这将显着影响页面的加载时间。您实际上应该遵循那个 railscast 并将 URL 作为自动完成源:
<%= f.input :user_name, as: :search, data:
{autocomplete_source: users_path} %>
确保将 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
除了 Oliver 的回答,我还必须:
<%= f.input :user_name, as: :search, input_html: {class: 'ui-autocomplete-input', data: {autocomplete_source: users_path} }%>
使其与 Simple_Form 一起使用。
我在基本任务管理应用程序中有一个表单,允许将任务分配给用户(任务 belongs_to 用户)。我为此使用简单表格。
目前,关联以典型方式填充,用户下拉列表如下:<%= f.association :user, label_method: :name, value_method: :id, include_blank: false %>
。
但是,随着用户数量的增加,我希望将其更改为自动完成表单字段以查找用户。我已经尝试遵循 Railscast on the subject,尽管它不使用简单形式并且在我的实现中不起作用。
这是我的表格、模型和 .coffee 代码:
表格
<%= simple_form_for @task do |f| %>
...
<%= f.input :user_name, as: :search, data:
{autocomplete_source: User.pluck(:name)} %>
...
<%= f.button :submit %>
<% end %>
型号
# 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')
这会生成以下 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">
尽管在开发工具控制台中出现以下错误:
Uncaught TypeError: this.source is not a function
担心 HTML 中的 autocomplete="off"
,无法想象 TypeError 有多大帮助!
我很困惑,所以非常感谢任何关于如何让它工作的建议!提前致谢,让我知道你的想法,史蒂夫。
autocomplete_source 需要一个数组或 URL,当调用 returns JSON 时,结果与查询匹配。 http://api.jqueryui.com/autocomplete/#option-source
现在你有
<%= f.input :user_name, as: :search, data:
{autocomplete_source: User.pluck(:name)} %>
那可能是 return javascript 的字符串。所以您可以将其更改为:
<%= f.input :user_name, as: :search, data:
{autocomplete_source: User.pluck(:name).to_json} %>
然后在设置自动完成时解析 JSON:
jQuery ->
$('#task_user_name').autocomplete
source: JSON.parse($('#task_user_name').data('autocomplete-source'))
但在较长的 运行 中(当您有很多用户时)这将显着影响页面的加载时间。您实际上应该遵循那个 railscast 并将 URL 作为自动完成源:
<%= f.input :user_name, as: :search, data:
{autocomplete_source: users_path} %>
确保将 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
除了 Oliver 的回答,我还必须:
<%= f.input :user_name, as: :search, input_html: {class: 'ui-autocomplete-input', data: {autocomplete_source: users_path} }%>
使其与 Simple_Form 一起使用。