在 Rails 中使用 jquery 自动完成时搜索并显示多列?

Search and display multiple columns when using jquery autocomplete in Rails?

我已成功将 Jquery-Autocomplete 集成到我的 rails 应用程序中,目前用户可以搜索 5000 多个机场,到目前为止,集成工作完全符合预期,但是...

任何机场都有多个列,目前我正在返回机场名称,但想改为显示

**

airport_name - airport_city - airport_iata - airport_icao

**

到目前为止,我已经使用 Ryan Bates Railscast 开始了 Episode #102

但由于自他的视频以来的其他资源而进行了修改和调整。抱歉,我现在无法引用它们,但一旦找到指向它们说明的链接,我会更新我的问题。

无论哪种方式,自动完成都按设计工作,我已经设法填充了一个隐藏字段,但我真的希望在搜索时显示的不仅仅是机场名称。我将继续只保存机场 ID。

感谢任何帮助,这是我的代码。

_form.html.erb

<div class="field">
  <%= f.label :departure_airport %><br>
  <%= text_field_tag nil, nil, :id => 'claim_departure_airport_name', data: {autocomplete_source: Airport.order(:name).map { |t| { :label => t.name, :value => t.id } } }, class: "form-control" %>
</div>

<%= f.hidden_field :d_airport_id, id: 'd_airport_id' %>

<%= f.hidden_field :a_airport_id, id: 'a_airport_id' %>

claims.coffee

jQuery ->

$('#claim_departure_airport_name').autocomplete
    source: $('#claim_departure_airport_name').data('autocomplete-source')
    select: (event, ui) ->

        # necessary to prevent autocomplete from filling in
        # with the value instead of the label
        event.preventDefault()

        $(this).val ui.item.label
        $('#d_airport_id').val ui.item.value

$('#claim_arrival_airport_name').autocomplete
    source: $('#claim_arrival_airport_name').data('autocomplete-source')
    select: (event, ui) ->

        # necessary to prevent autocomplete from filling in
        # with the value instead of the label
        event.preventDefault()

        $(this).val ui.item.label
        $('#a_airport_id').val ui.item.value

如您所见,我无需专用控制器即可直接访问模型数据,尽管我意识到这比我当前的解决方案智能得多,因为我希望将其推广到平台的其他区域。

我不完全理解我的咖啡文件中 jquery 代码中发生的一切,这是从另一个来源获得的,尽管我忘记了归功于谁。据我所知,它正在获取机场的 ID 并填充隐藏字段?

如果您能发现如何向用户显示其他机场数据库列,那就太好了。

谢谢

编辑

由于页面加载时间非常长,还希望限制自动完成将数据源加载到 html。下面是我的意思的屏幕截图。

screenshot of data loading

重点来了data: {autocomplete_source: Airport.order(:name).map { |t| { :label => t.name, :value => t.id } } }

它构建了一个对象数组,例如[{'label': 'BKK', value: 1}, {'label': 'HAM', value: 2}]

所以您要么需要向标签键添加一些内容,要么添加一个不同的键并稍后在 select 回调中使用它。

您可以将自动完成源修改为

<%= text_field_tag nil, nil, id: 'claim_departure_airport_name', data: { autocomplete_source: Airport.select(:id, :name, :city, :iata, :icao).order(:name).map { |t| { label: "#{t.name}-#{t.city}-#{t.iata}-#{t.icao}", value: t.id } } }, class: "form-control" %>

要稍微重构一下,您可以将活动记录查询移动到帮助程序中

def airport_autocomplete_data
  Airport.select(:id, :name, :city, :iata, :icao).order(:name).map { |t| { label: "#{t.name}-#{t.city}-#{t.iata}-#{t.icao}", value: t.id } }
end

您的文本字段变为

<%= text_field_tag nil, nil, id: 'claim_departure_airport_name', data: { autocomplete_source: airport_autocomplete_data }, class: "form-control" %>

如果您使用的是 rails 4-autocomplete Gem。您可以轻松地从控制器覆盖。

def autocomplete_profile
      term = params[:term]
      profiles = Profile.where(
        'LOWER(profiles.first_name) LIKE ? OR LOWER(profiles.last_name) LIKE ?',
        "%#{term}%", "%#{term}%"
        ).order(:id).all
      render :json => profiles.map { |profile| {:id => profile.id, :label => profile.id, :value => profile.id} }
    end