15

Thisselect2 jquery library выглядит потрясающе. Существует Rails gem, но он очень прост в документации. Я хотел бы создать простое раскрывающееся меню, используя автозаполнение. Как мне это сделать?Как использовать select2-rails с simple_form?

Это мой 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 драгоценный камень, но не совсем уверен, как заставить его работать.

добавить это к моему home.js.coffee файла:

jQuery -> 
    $('#selectWhereToLive').select2() 

И я получаю эту ошибку:

Uncaught query function not defined for Select2 selectWhereToLive 

Мысли?

Edit 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 будет должным образом установлен.

Edit 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 Вариант значений 'Да' и 'Нет'. Не совсем понятно, почему, но это то, что он делает.

Update

Так что я изменил селектор JQuery искать input#ID и забыл. Поэтому я установил это, и теперь он генерирует поле выбора - но он дает мне те 2 Да & Нет параметров. Не совсем уверен, почему он это делает. Он не возвращает значения из моего атрибута url.

Редактировать 3

@ предложение Хариш-Шетти, кажется, работает. Но теперь, после того, как он успешно нашел записи через автозаполнение и используя меню select2, он обходит метод настройки, который у меня есть на моей модели 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 

Это то, что запрос выглядит прямо сейчас - который показывает, что никакие записи не создается:

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 
+0

В конце концов, Edit3 - это еще одна проблема. Предлагаю вам задать еще один вопрос. Думаю, вам нужно разрешить local_names на контроллере. – kuboon

ответ

24

Плагин 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  
+0

Hrmm .... Я использовал «rails3-jquery-autocomplete' gem - https://github.com/crowdint/rails3-jquery-autocomplete - чтобы сгенерировал это' autocomplete_neighborhood_name_searches_path' на основе объявления, которое я положил на сверху моих контроллеров. Должен ли я избавиться от этой декларации и создать действия вручную? Если да, на каком контроллере я должен создать действие? Мой контроллер 'Поиск'? Здесь объявляется автозаполнение. – marcamillion

+0

Так я и делал это в прошлом. Вы должны добавить действие в контроллер 'search' и зарегистрировать его как действие' collection' в файле маршрута. Когда все работает, вы должны увидеть работу автозаполнения, как в этом примере: http://ivaynberg.github.com/select2/#ajax –

+0

Итак, вот последний недостающий фрагмент головоломки .... теперь, наконец, я получил он работает, но когда он выполняет поиск, он обходит мой метод setter в моей модели 'search.rb'. Я уточню вопрос с большим количеством кода. – marcamillion

1

Я считаю, что вам нужно приложить выбор либо к sel ect (затем он считывает данные из него) или вводит скрытый тег, тогда вам нужно предоставить функцию «запрос». В вашем случае он привязан к входному тегу и, таким образом, ищет функцию запроса. Попробуйте установить as: :select на ваш вызов f.input_field.

+0

Могу ли я иметь два вызова 'as:'? Один из них в настоящее время 'as:: autocomplete'. – marcamillion

+0

Я обновил вопрос с помощью HTML-вывода на основе вашего предложения. Короче говоря, это не работает :( – marcamillion

+0

нет, только один, если вам нужно сохранить его как:: автозаполнение, вам нужно будет определить функцию запроса. – moonfly

0

Использование в качестве:: выберите с помощью коллекции является регулярным способом для выбор2. Привязка автозаполнения на select2 является вопросом javascript.

Это мой образец кода. но не имеет автозаполнения. https://gist.github.com/kuboon/f692d9a844c0ff5877c8