Как использовать select2-rails с simple_form?
Эта библиотека select2
jquery выглядит потрясающе. Существует Rails gem, но он очень легк в документации.
Я хотел бы создать простое раскрывающееся меню, используя автозаполнение. Как это сделать?
Это мой simple_form_for call:
<%= 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
, но не совсем уверен, как заставить его работать.
Я добавляю это в мой файл home.js.coffee
:
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
включены и не включены.
Полученный HTML без as: :autocomplete
был следующим:
<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
, и забыл. Поэтому я установил это, и теперь он генерирует поле выбора - но он дает мне те 2 варианта Да и Нет. Не совсем уверен, почему он это делает. Он не возвращает значения из моего атрибута url
.
Изменить 3
Предложение
@harish-shetty, похоже, работает. Но теперь, после того, как он успешно нашел записи через автозаполнение и с помощью меню select2, он обходит метод setter, который у меня есть в моей модели search.rb
.
В принципе, я хочу, чтобы после того, как пользователь закончил заполнять форму - и у меня есть все ID/имена для их окрестностей, я хочу создать новую запись в search_neighborhoods
для этих идентификаторов.
Итак, это те методы, которые у меня есть:
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
Ответы
Ответ 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" }
%>
Javscript
$(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
Ответ 2
Я считаю, что вам нужно прикрепить выбор либо для выбора тега (затем он считывает данные из него), либо для ввода скрытого тега, тогда вам нужно предоставить функцию "запрос". В вашем случае он привязан к входному тегу и, таким образом, ищет функцию запроса. Попробуйте установить as: :select
на вызов f.input_field
.
Ответ 3
Использовать как:: выбор с коллекцией является обычным способом для select2.
Автообъект привязки на select2 является вопросом javascript.
Это мой пример кода. но не имеет автозаполнения.
https://gist.github.com/kuboon/f692d9a844c0ff5877c8