jQuery autocomplete: по-разному отображать определенные объекты? - PullRequest
3 голосов
/ 11 августа 2011

Я запускаю приложение ruby ​​on rails и использую jQuery для отображения некоторых предложений автозаполнения в форме. Предложения автозаполнения поступают из 2 разных массивов, которые я объединяю в один, а затем отображаю.

Теперь проблема в том, что мне нужно отображать результаты одного файла иначе, чем результаты другого. Как мне это сделать? То есть все они будут в одном окне автозаполнения, но результаты одного могут иметь другой шрифт, цвет и т. Д. (Отдельный хук CSS?)

autocomplete.js:

$(function() {
  $('.autocomplete_field').autocomplete({
  source: '/locations/autocomplete.js'
  });
});

locations_controller.rb:

  def autocomplete
    respond_to do |format|
      format.js do
        client = GooglePlacesAutocomplete::Client.new(:api_key => "mykey")
        locations = client.autocomplete(:input => params[:term], :lat => "x", :lng => "y", :radius => "25000")
        add = Location.all.map { |l| { :label => l.address, :value => l.address } }
        locations = locations.predictions.map { |l| {:label => l.description, :value => l.description} }
        final = add + locations
        render :json => final
      end
    end
  end

Как видите, locations_controller просто отображает объект JSON, который представляет собой два сцепленных массива, по URL-адресу /locations/autocomplete.js, который отображает autocomplete.js.

Я понимаю, что мне может понадобиться изменить мой контроллер, чтобы он возвращал 2 отдельных объекта JSON, один для add и один для location. Я могу это сделать, но я не знаю, как объединить их в окончательное автозаполнение и как по-разному форматировать запросы из них.

Я очень неопытен в javascript / jquery, поэтому я был бы признателен за ответ, который хорошо объясняет эти компоненты, даже если вы затушевываете необходимые изменения в приложении Rails.

Это то, что сводится к:

Когда я просматриваю HTML для поля автозаполнения, каждый элемент автозаполнения выглядит следующим образом:

<li class="ui-menu-item" role="menuitem">
<a class="ui-corner-all" tabindex="-1">(autocomplete suggestion)</a>
</li>

Мне просто нужно добавить дополнительный класс помимо "ui-menu-item" и "ui-corner-all" к результатам, полученным из одного JSON, который не будет присутствовать в полученных результатах от другого.

Теперь я вижу здесь , что можно добавить дополнительный класс, изменив функцию .renderItem, но как мне применить это к каждому элементу в определенном объекте JSON (подход js), или применить это к каждому элементу в массиве ruby ​​заранее (через рельсы)?

1 Ответ

1 голос
/ 11 августа 2011

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

Я бы просто отправил другую переменную из вашего кода ruby ​​(извините, вообще не разбираюсь в ruby), которая определяет, является ли это адрес или нет (или любым свойством, на которое вы хотите перейти для изменения форматирования). *

Тогда вы бы написали функцию _renderItem так:

$("#auto").autocomplete({
    source: source
}).data("autocomplete")._renderItem = function(ul, item) {
    var listItem = $("<li></li>")
        .data("item.autocomplete", item)
        .addClass(item.isAddress ? "address" : "landmark");

    if (item.isAddress) {
        listItem.html("<a>" + $.map(item.label.split(","), function(el) {
            return "<span class='addressline'>" + el + "</span>";
        }).join('') + "</a>");
    } else {
        listItem.html("<a>" + item.label + "</a>");
    }

    return listItem.appendTo(ul);

};

Предполагается, что вы передаете значение isAddress для тех объектов в вашем массиве, которые являются адресом. Помните, что вы можете передавать любые данные, которые хотите, если у виджета есть метка или поле значения (или оба).

Вот более полный пример с локальным источником данных: http://jsfiddle.net/andrewwhitaker/tW5zE/

...