如何将 select2-rails 与 simple_form 一起使用?
Posted
技术标签:
【中文标题】如何将 select2-rails 与 simple_form 一起使用?【英文标题】:How do I use select2-rails with simple_form? 【发布时间】:2013-02-15 06:39:40 【问题描述】:Thisselect2
jquery 库看起来很棒。有一个Rails gem,但它在文档上非常简单。
我想使用自动完成生成一个简单的多重下拉菜单。我该怎么做?
这是我的 simple_form_for 调用:
<%= f.input_field :neighborhood_names, url: autocomplete_neighborhood_name_searches_path, as: :autocomplete, data: delimiter: ',', placeholder: "Where do you want to live?", multiple: true, id: "selectWhereToLive", class: "span8" %>
我已经成功安装了select2-rails
gem,但不太确定如何让它工作。
我将此添加到我的home.js.coffee
file:
jQuery ->
$('#selectWhereToLive').select2()
我得到了这个错误:
Uncaught query function not defined for Select2 selectWhereToLive
想法?
编辑 1:
上面的 simple_form_for
调用正在生成这个 html:
<input class="autocomplete optional span8" data-autocomplete="/searches/autocomplete_neighborhood_name" data-delimiter="," data-placeholder="Where do you want to live?" id="selectWhereToLive" multiple="multiple" name="search[neighborhood_names][]" size="30" type="text" url="/searches/autocomplete_neighborhood_name" value="" />
表示id
属性设置正确。
编辑 2 - 更新
正如@moonfly 建议的那样,我尝试将as: :select
添加到f.input_field
- 包括as: :autocomplete
和不包括在内。
没有as: :autocomplete
的HTML 是这样的:
<input name="search[neighborhood_names][]" type="hidden" value="" /><select class="select optional span8" data-delimiter="," data-placeholder="Where do you want to live?" id="selectWhereToLive" multiple="multiple" name="search[neighborhood_names][]" url="/searches/autocomplete_neighborhood_name"><option value="true">Yes</option>
<option value="false">No</option></select>
它预填充了 2 个选项值“是”和“否”。不太清楚为什么,但这就是它的作用。
更新
所以我更改了 jquery 选择器以查找 input#ID
,然后忘记了。所以我将其设置回来,现在它正在生成选择框 - 但它给了我这两个是和否选项。不太清楚它为什么这样做。它没有从我的 url
属性中返回值。
编辑 3
@harish-shetty 的建议似乎奏效了。但是现在,在它通过自动完成并使用 select2 菜单成功找到记录后,它绕过了我在 search.rb
模型上的 setter 方法。
基本上,我想要发生的是,一旦用户完成填写表格 - 我拥有他们想要的社区的所有 ID/名称,我想在 search_neighborhoods
中为这些 ID 创建一条新记录.
所以这些是我有的方法:
Search.rb
def neighborhood_names
neighborhoods.map(&:name).join(',')
end
# we need to put [0] because it returns an array with a single element containing
# the string of comma separated neighborhoods
def neighborhood_names=(names)
names[0].split(',').each do |name|
next if name.blank?
if neighborhood = Neighborhood.find_by_name(name)
search_neighborhoods.build neighborhood_id: neighborhood.id
end
end
end
我的SearchController.rb
def autocomplete_neighborhood_name
@neighborhood = Neighborhood.select("id, name").where("name LIKE ?", "#params[:name]%").order(:name).limit(10)
respond_to do |format|
format.json render json: @neighborhood , :only => [:id, :name]
end
end
这是请求现在的样子 - 这表明没有创建 search_neighborhood
记录:
Started POST "/searches" for 127.0.0.1 at 2013-03-06 04:09:55 -0500
Processing by SearchesController#create as HTML
Parameters: "utf8"=>"✓", "authenticity_token"=>"7SeA=", "search"=>"boro_id"=>"", "neighborhood_names"=>"1416,1394", "property_type_id"=>"", "min_price"=>"", "max_price"=>"", "num_bedrooms"=>"", "num_bathrooms"=>""
Neighborhood Load (0.5ms) SELECT "neighborhoods".* FROM "neighborhoods" WHERE "neighborhoods"."name" = '1' LIMIT 1
(0.3ms) BEGIN
SQL (0.8ms) INSERT INTO "searches" ("amenity_id", "boro_id", "created_at", "keywords", "listing_type_id", "max_price", "min_price", "neighborhood_id", "num_bathrooms", "num_bedrooms", "property_type_id", "square_footage", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) RETURNING "id" [["amenity_id", nil], ["boro_id", nil], ["created_at", Wed, 06 Mar 2013 09:09:55 UTC +00:00], ["keywords", nil], ["listing_type_id", nil], ["max_price", nil], ["min_price", nil], ["neighborhood_id", nil], ["num_bathrooms", nil], ["num_bedrooms", nil], ["property_type_id", nil], ["square_footage", nil], ["updated_at", Wed, 06 Mar 2013 09:09:55 UTC +00:00]]
(32.2ms) COMMIT
Redirected to http://localhost:3000/searches/29
【问题讨论】:
毕竟Edit3完全是另外一个问题。我建议你发布另一个问题。我猜你需要在控制器上允许邻居名称。 【参考方案1】:select2 插件支持自动完成。您可以按如下方式使用本机自动完成:
<%= f.input_field :ac_neighborhood_ids,
data:
placeholder: "Where do you want to live?",
saved: @search.neighborhoods.to_json,
url: autocomplete_neighborhood_name_searches_path
,
input_html: class: "span8 ac-select2"
%>
$(document).ready(function()
$('.ac-select2').each(function()
var url = $(this).data('url');
var placeholder = $(this).data('placeholder');
var saved = jQuery.parseJSON($(this).data('saved'));
$(this).select2(
minimumInputLength: 2,
multiple: true,
placeholder : placeholder,
allowClear: true,
ajax:
url: url,
dataType: 'json',
quietMillis: 500,
data: function (term)
return
name: term
;
,
results: function (data)
return results: data;
,
formatResult: function (item, page)
return item.name;
,
formatSelection: function (item, page)
return item.name;
,
initSelection : function (element, callback)
if (saved)
callback(saved);
);
);
);
确保autocomplete_neighborhood_name_searches_path
处的操作返回一个 json 哈希数组。每个散列应该包含id
和name
字段。自动补全术语通过查询参数name
传递。
def autocomplete_neighborhood_name
@neighborhood = Neighborhood.select("id, name").where("name LIKE ?", "#params[:name]%").order(:name).limit(10)
respond_to do |format|
format.json render json: @neighborhood , :only => [:id, :name]
end
end
您的搜索模型:
class Search
attr_accessor :ac_neighborhood_ids
has_many :search_neighborhoods
has_many :neighborhoods, through: :search_neighborhoods
def ac_neighborhood_ids
neighborhood_ids.join(",")
end
def ac_neighborhoods
neighborhoods.map|n| :id => n.id, :name => n.name
end
def ac_neighborhood_ids=(ids)
search_neighborhoods.clear # remove the old values
ids.split(',').select(&:present?).map do |neighborhood_id|
search_neighborhoods.build neighborhood_id: neighborhood_id
end
end
end
【讨论】:
Hrmm....我正在使用rails3-jquery-autocomplete
gem - github.com/crowdint/rails3-jquery-autocomplete - 所以根据我放在控制器顶部的声明生成了 autocomplete_neighborhood_name_searches_path
。我应该摆脱该声明并手动创建操作吗?如果是这样,我应该在哪个控制器上创建操作?我的Search
控制器?这就是现在声明自动完成的地方。
我过去就是这样做的。您应该在search
控制器中添加操作并将其注册为您的路由文件中的collection
操作。当一切正常时,您应该会看到像以下示例一样的自动完成工作:ivaynberg.github.com/select2/#ajax
所以这是拼图的最后一个缺失部分......现在我终于让它工作了 - 但是当它执行搜索时,它绕过了我的 search.rb
模型中的 setter 方法。我将用更多代码更新问题。
我还添加了一个请求的日志输出,这表明它正在跳过我的 setter 方法。
很高兴你让它工作。我会在创建 gem 时通知您。顺便说一句,我更新了ac_neighborhood_ids=
方法来清除旧的旧社区。否则你会积累邻域。【参考方案2】:
我相信您需要附加选择以选择标签(然后它从中读取数据)或输入隐藏标签,然后您需要提供“查询”功能。在您的情况下,它附加到输入标签,因此寻找查询功能。尝试在您的 f.input_field
通话中设置 as: :select
。
【讨论】:
我可以打两个as:
电话吗?目前一个是as: :autocomplete
。
我根据您的建议使用 HTML 输出更新了问题。简而言之,它不起作用:(
不,只有一个。如果您需要将其保留为::自动完成,则必须定义“查询”功能。
是的......即使只是 as: :select
也不起作用......它会产生那些 Yes/No
选项值字段,原因是 w/e。这很奇怪,因为从 URL 调用返回的数据不应该是 yes/no
。它应该是一个名字。
对于选择,您需要提供包含所有值的集合。例如,检查github.com/plataformatec/simple_form#collections。在您的情况下,您似乎别无他法,只能创建一个“查询”函数,该函数将从 /searches/autocomplete_neighbourhood_names 中检索值。所以,忘了我建议做as: :select
,专注于写'查询'【参考方案3】:
用作: :select with collection 是 select2 的常规方式。 在 select2 上绑定自动完成是一个 javascript 问题。
这是我的代码示例。但没有自动完成功能。 https://gist.github.com/kuboon/f692d9a844c0ff5877c8
【讨论】:
以上是关于如何将 select2-rails 与 simple_form 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Vue Webpack-simple 应用程序部署到 Netlify?
将 f.collection_check_boxes 的复选框与 Simple_Form 对齐
如何使用 Vuetify.js 的 v-simple-table 将标题放在第一列?