Вопрос

Мне нужна помощь в том, как реализовать jquery-ui Автозаполнение в моем приложении Rails.

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

Основной момент, который я не понимаю, это то, как предоставить предложенные значения в текстовом поле автопроизводства. Я прочитал документы jquery-ui, но я, кажется, немного плотный в этом вопросе.

Так что я на самом деле после того, как я могу заставить это работать в приложении Rails, не обязательно полное описание того, как строится JavaScript (это то, что команда JQuery-UI сделала для меня =)).

Например, как мне подготовить данные для автозаполнения, и как мне прикрепить функциональность автозаполнения к текстовому поле.

Это было полезно?

Решение

Ну, я никогда не получил ответа на свой вопрос выше, поэтому мне пришлось выяснить это для себя. Я думал, что должен опубликовать решение, которое я придумал, если есть другие парни, которые задаются вопросом.

Первое, что вы должны знать, это то, что это мой первый опыт работы с JavaScript, и я просто получаю витрины рельсов. Так что во что бы то ни стало, не стесняйтесь редактировать, прокомментируйте, где вы чувствуете, что я ошибся с этим. Правильно или неправильно, по крайней мере, я знаю, что это функционирует так, как я хотел.

Я думаю, что лучший способ показать это примером. Итак, следующее - то, как я получил автоматический виджет для работы в моем приложении. Вы можете пойти дальше и поместить следующий код в своем приложении, даже если вы не понимаете, что происходит, тогда мы можем рассказать о том, как работает каждая часть. После этого вы должны понять, как изменить его для вашего использования или рефрактора.


Включите интерфейс jQuery в приложение Rails.

Скачать копию jQuery UI и место jquery-ui-1.8.2.custom.min.js внутри вашего /public/javascript каталог. Также убедитесь, что у вас есть копия самого jQuery, и что это также в той же папке.

Включите файл пользовательского интерфейса jQuery и файл jQuery в вашем Application.html.erb Файл такой.
(Вы можете назвать файлы так, как вам нравится, если они соответствуют)

<%= javascript_include_tag 'jquery.min', 'jquery-ui-1.8.2.custom.min.js' %>

При загрузке интерфейса jQuery у вас будет папка, которая содержит все ваши данные CSS. Имя будет варьироваться в зависимости от выбранной вами темы, например, я выбрал тему 'Купертино' Поместите всю папку, содержащую ваши данные CSS в '/public/styleships/' Затем включите файл CSS в ваше приложение.

<%= stylesheet_link_tag 'cupertino/jquery-ui-1.8.2.custom' %>


Пример автозаполнения JavaScript

Теперь возьмите следующий кусок кода и поместите его в одну из ваших 'новый' взгляды. Вы можете использовать это в любой точке зрения, но поймите, что я буквально взял его из существующего представления, принадлежащего контроллеру, называемому «links_controller», и он вытаскивает данные из «people_controller». Надеюсь, вы знаете достаточно о Rails, чтобы понять, что вам нужно изменить, так что это работает для вас.

-начать большую часть кода-

    <script type="text/javascript">
    $(function() {

 // Below is the name of the textfield that will be autocomplete    
    $('#select_origin').autocomplete({
 // This shows the min length of charcters that must be typed before the autocomplete looks for a match.
            minLength: 2,
 // This is the source of the auocomplete suggestions. In this case a list of names from the people controller, in JSON format.
            source: '<%= people_path(:json) %>',
  // This updates the textfield when you move the updown the suggestions list, with your keyboard. In our case it will reflect the same value that you see in the suggestions which is the person.given_name.
            focus: function(event, ui) {
                $('#select_origin').val(ui.item.person.given_name);
                return false;
            },
 // Once a value in the drop down list is selected, do the following:
            select: function(event, ui) {
 // place the person.given_name value into the textfield called 'select_origin'...
                $('#select_origin').val(ui.item.person.given_name);
 // and place the person.id into the hidden textfield called 'link_origin_id'. 
        $('#link_origin_id').val(ui.item.person.id);
                return false;
            }
        })
 // The below code is straight from the jQuery example. It formats what data is displayed in the dropdown box, and can be customized.
        .data( "autocomplete" )._renderItem = function( ul, item ) {
            return $( "<li></li>" )
                .data( "item.autocomplete", item )
 // For now which just want to show the person.given_name in the list.
                .append( "<a>" + item.person.given_name + "</a>" )
                .appendTo( ul );
        };
    });
    </script>



<h1>New link</h1>

<% form_for(@link) do |f| %>
  <%= f.error_messages %>

<!-- Place the following text fields in your form, the names are not important. What is important is that they match the names in your javascript above -->
  <p>
        Select which person you want to link:<br /> 
<!-- This is the textfield that will autocomplete. What is displayed here is for the user to see but the data will not go anywhere -->
        <input id="select_origin"/>
<!-- This is the hidden textfield that will be given the Persons ID based on who is selected. This value will be sent as a parameter -->
      <input id="link_origin_id" name="link[origin_id]" type="hidden"/>
  </p>
<!-- end of notes -->
  <p>
    <%= f.label :rcvd_id %><br />
    <%= f.text_field :rcvd_id %>
  </p>
  <p>
    <%= f.label :link_type %><br />
    <%= f.text_field :link_type %>
  </p>
  <p>
    <%= f.label :summary %><br />
    <%= f.text_area :summary %>
  </p>
  <p>
    <%= f.label :active %><br />
    <%= f.check_box :active %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

-Конец большой куски кода-

Хорошо, теперь, чтобы подключить точки.


Предоставить данные для автозаполнения для использования в качестве предложений

Давайте начнем с подключения некоторых данных, которые автозаполненное текстовое поле может отображать в раскрывающихся предложениях. Формат, который мы будем использовать, - это JSON, но не волнуйтесь, если вы не знакомы с ним ... ни я и =). Достаточно хорошо знать, что это способ форматировать текст, чтобы его могли использовать другие ваши части/другие приложения.

Данные, которые Textfield понадобится для автозаполнения, указаны в 'источник:' вариант. Поскольку мы хотим отправить список имен народов и их идентификатор на автозаполнение, мы поместим следующее в качестве источника.

source: '<%= people_path(:json) %>'  

Помощник Rails выше переведет в струну "/people.json". Вам не нужно создавать страницу в"/people.json". Что вам нужно сделать, так это сказать своему People_controller, что делать, когда он получает запрос /людей с форматом .json. Поместите следующее в свой народ_controller:

def index  
# I will explain this part in a moment.
  if params[:term]
    @people = Person.find(:all,:conditions => ['given_name LIKE ?', "#{params[:term]}%"])
  else
    @people = Person.all
  end

  respond_to do |format|  
    format.html # index.html.erb  
# Here is where you can specify how to handle the request for "/people.json"
    format.json { render :json => @people.to_json }
    end
end

Теперь у нас есть все люди в @people, которые отправляют на автозаполнение Textfield. Это поднимает следующий пункт.


Данные фильтра, используемые для предложения по автозаполнению, на основе ввода

Как автозаполнение Textfield узнает, как фильтровать результаты на основе того, что вы вводите?

Виджет автозаполнения, назначенный на Textfield, отправит все, что вы вводите в текстовое поле в качестве параметра на ваш источник:. Отправляется параметр "срок". Итак, если бы вы вводили« Джо »в текстовое поле, мы бы сделали следующее:

/people.json?term=joe

Вот почему у нас есть следующее в контроллере:

# If the autocomplete is used, it will send a parameter 'term', so we catch that here
    if params[:term]
# Then we limit the number of records assigned to @people, by using the term value as a filter.
      @people = Person.find(:all,:conditions => ['given_name LIKE ?', "#{params[:term]}%"])
# In my example, I still need to access all records when I first render the page, so for normal use I assign all. This has nothing to do with the autocomplete, just showing you how I used it in my situation.
    else
      @people = Person.all
    end

Теперь, когда мы ограничили количество записей, назначенных @people на основе того, что вводится в автозаполненное текстовое поле, теперь мы можем превратить это в формат JSON для предложений автозаполнения.

respond_to do |format|  
      format.html # index.html.erb  
      format.json { render :json => @people.to_json }
    end 

Теперь просто просмотрите комментарии внутри «Большой куски кода», которые должны объяснить остальную часть того, как это связывается вместе.

В конце у вас должно быть текстовое поле на вашей странице, которое выступает в качестве автозаполнения и скрытого поля, которое отправит идентификатор в параметре вашему контроллеру.


Настройте свой собственный автозаполнение

После того, как вы поймете приведенное выше и хотите изменить его для использования, вы должны знать, что формат JSON, возвращенный из вашего контроллера, выглядит так:

[{"person":{"id":1,"given_name":"joe","middle_name":"smith","family_name":"jones","nationality":"australian"}}]

Способ получить доступ к различным значениям от строки JSON в вашем JavaScript в этом случае будет:

ui.item.person.name_of_some_attribute_such_as_given_name

Довольно, просто. Очень похоже на доступ к атрибуту Activerecord в Rails.

Последнее примечание. Я потратил много времени в поисках другого способа предоставления скрытого значения, так как я думал, что эта функция должна была быть встроена в виджет jQuery. Однако, это не так. В официальном примере JQUERY ясно показан, что способ отправки другого значения, выбранного в качестве параметра, - это использование скрытого поля.

Ну, я надеюсь, что это кому -то поможет.

Дол

Другие советы

jquery 1.9/1.10 снял автозаполнение ключа и добавлено uiautocoplete

.data("uiAutocomplete") instead of .data("autocomplete")

После модификации выше, это сработало для меня.

Ответ Дейла это довольно учебник. Отнесее отметить, что использование вашего первого запроса, дат данных только вернет совпадения начало С помощью строки, которую вы вводите. Если вы хотите поиск в любом месте слова, вам нужно изменить:

@people = Person.find(:all,:conditions =>
    ['given_name LIKE ?', "#{params[:term]}%"])

к

@people = Person.find(:all,:conditions =>
    ['given_name LIKE ?', "%#{params[:term]}%"])

(добавил дополнительный % к запросу)

Я в основном последовал совету Дейла ниже, но мои файлы контроллера и JS были немного отличались. Его версия по какой-то причине дала мне проблемы (возможно, BC обновлений JQUERY)

Контекст: я пытаюсь автоматически заполнить имена диджеев, напечатанных пользователями - также новый

Диджеи контроллер

 class DjsController < ApplicationController
    def index
     if params[:term]
       @djs = Dj.is_dj.where('lower(name) LIKE ?', "%#{params[:term].downcase}%")
       respond_to do |format|  
          format.html
          format.json { render :json => @djs.map(&:name) }
       end
     end    
   end
 end

file html.erb

  <script type="text/javascript">

$(function() {  
    $('#select_origin').autocomplete({
        source: '<%= djs_path(:json) %>'
      })

    $('.submit-comment').click(function(){
      var dj_name = $('#select_origin').val();
      $('#link_origin_id').val(dj_name);
    })

})

</script>

Это отличная помощь.

В дополнение к этому, если вам нужно получить URL -адрес пользователя, это может быть невозможно с to_json. Анкет Для этого добавьте следующий код в модели.

def avatar_url
    avatar.url(:thumb)
end

А затем в контроллере вместо to_json использовать as_json

respond_to do |format|
    format.json {render :json => @users.as_json(:only => [:id,:name,:username], :methods => [:avatar_url]) }
end 

Важно отметить, что если ваш «источник» относительно невелик, например, 50 элементов, реализация должна быть другой (и намного проще). Это упоминается в четвертом абзаце официального документа:

https://api.jqueryui.com/autocomplete/

При использовании локальных данных все, что вам нужно сделать, это получить данные и передать их методу автозаполнения, и он будет выполнять фильтрацию для вас. Вам не нужно возвращаться к серверу каждый раз, когда вводится термин.

function filterByTags(tags) {
  $("#stories-filter").autocomplete({
     source: tags,
     autoFocus: true
  });
}

$("#stories-filter").click(function() {
  $.ajax({
    dataType: 'json',
    method: 'GET',
    url: 'tags/index',
    data: $(this).data('project-id'),
    success: function (response) {
      if(response.success) {
        var tags = response.data.tags;
        filterByTags(tags);
      }
    },
    error: function (response) {
      if(response.status === 422) {
        var $errors = 'There are no tags in this project',
            $errorsContainer = $('.error-container');
        $errorsContainer.append($errors);
        $errorsContainer.show();
      }
    }
  });
});
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top