jQuery自动完成:以不同方式显示某些对象?

时间:2011-08-11 10:40:37

标签: javascript jquery ruby-on-rails ruby-on-rails-3 autocomplete

我正在rails应用程序上运行ruby,我正在使用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获得的结果,结果中不会出现从另一个获得。

现在,我看到here可以通过修改.renderItem函数来添加一个额外的类,但是如何将它应用于某个JSON对象中的每个元素(js方法),或者事先(通过rails)将它应用于ruby数组中的每个元素?

1 个答案:

答案 0 :(得分:1)

你必须使用_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/