【问题标题】:How can I dynamically update search results based on form input in Rails?如何根据 Rails 中的表单输入动态更新搜索结果?
【发布时间】:2015-07-21 00:50:59
【问题描述】:

我希望网站访问者能够在可以通过下拉表单输入的范围内查看附近的节目。我有一个使用 Geocoder gem 显示附近节目的视图:

<h3> Shows near <%= request.location.city %> </h3>
<%= form_for @nearby_shows.first do |f| %>
<p> Radius (in miles): <%= f.select(:radii, [10,20,30,40,50], {},
   :style => "width:50px", :selected => f.object.radii, :onchange =>
   "location.href = '#{shows_path}'") %> </p>
<% end %>
<ul class="users">
  <% @nearby_shows.each do |nearby_show| %>
    <li>
      <%= link_to nearby_show.show_name, nearby_show %>
    </li>
  <% end %>
</ul>

目前选择不会影响任何内容,并且当页面刷新时不会在表单中记住选择。

模型,show.rb 包含:

attr_accessor :radii

节目控制器包含:

def index
    @shows = Show.all
    @radii = 50
    @nearby_venues = Venue.near("Boulder, CO",@radii,:select =>
    "id").to_a
    @nearby_shows = Show.where(show_venue: @nearby_venues)
end

在生产中,我将使用 request.location.city,但在开发中,我只是使用“Boulder, CO”作为示例。

如何使用输入选择表单设置@radii?我担心 form_for 不允许我更改实体列表的变量@nearby_shows。

【问题讨论】:

  • 我不确定我是否真的理解...你想要 AJAX 解决方案吗?
  • 是的,那太好了。

标签: ruby-on-rails


【解决方案1】:

如果您想要一个快速的 AJAX 解决方案,我会这样做

首先,在您的列表中添加一个 ID,以便于操作

<ul id="my_id" class="users"></ul>

我真的不明白你为什么需要&lt;%= form_for @nearby_shows.first %&gt; ?如果我理解得很好,您只想显示一个选择,并根据用户选择的内容更新附近的节目列表?

routes.rb

resource :shows do
  get 'update_nearby', on: :collection, constraints: { format: 'js' }
end
# GET /shows/update_nearby, meant to be used only with AJAX

your_view.html.erb

<%= form_tag update_nearby_shows_path, remote: :true do |f| %>
<p> Radius (in miles): <%= select_tag(:radii, [10,20,30,40,50], {},
   :style => "width:50px", :selected => @radii, :onchange =>
   "location.href = '#{shows_path}'") %> </p>
<% end %>

<!-- On Submit, it will request a JS response 
     You can add some JS to submit the form everytime the select changes -->

添加一些 JS 特定的响应

your_controller.rb

def update_nearby
  find_nearby_shows
end

private
def find_nearby_shows
  @radii = params[:radii] ? params[:radii] : 50
  @nearby_venues = Venue.near("Boulder, CO",@radii,:select =>
    "id").to_a
  @nearby_shows = Show.where(show_venue: @nearby_venues)
end

update_nearby.js.erb

<% if @nearby_shows %>
  // Empty the list
  var id = $("#my_id").empty()
  <% @nearby_shows.each do %>
    // Add one <li> per show
    $("<li>", { 'html': "<%= escape_javascript(link_to(nearby_show.show_name, nearby_show)) %>"}).appendTo(id)
  <% end %>
<% end %>

奖励:你说你想保存半径?您实际上可以尝试将其添加到用户会话中

def index
  ...
  @radii = session[:saved_radii] ? session[:saved_radii] : DEFAULT_RADIUS
  ...
end

def update_nearby
   find_nearby_shows
   session[:saved_radii] = @radii
end

但如果你真的想为用户保存它,你应该在你的用户模型中有一个preferred_radii 字段

【讨论】:

  • 谢谢你!我在尝试实现它时遇到错误,但这个想法正是我想要的。 select_tag 的语法似乎有问题。 Rails 给出“参数过多”错误。
  • 如果我将语法更改为:select_tag(:radii, options_for_select( [10,20,30,40,50] ), :style => "width:50px", :selected => @半径,:onchange => "location.href = '#{shows_path}'"),然后视图加载,但选择似乎不起作用。我可以更改选择,但它会刷新回默认值 (10),结果未使用 10 英里半径,它们似乎仍在使用 50 英里半径。
  • 另外,如果我从控制器的索引部分删除@nearby_shows、@nearby_venues 和@radii 定义,我会收到“nil:NilClass 的未定义方法‘每个’”错误。跨度>
  • 是的,抱歉,我的 select_tag 语法完全关闭,因为我正在使用一些覆盖它的 gem ^^"。我相信 selected 半径应该作为 options_for_select 的参数。我可以在 12 小时内为您提供更多帮助,但如果您同时需要一些潜在客户:您需要更改 onchange 回调,以便在您选择其他选项时实际提交表单。在您的索引中,“奖金” session 的东西只是为了改进你当前的@radii 初始化,你仍然需要像你已经做的那样初始化其他变量..
  • 奖励部分的更改应该放在shows_controller 或其他地方吗?我对“options_for_select”中的默认半径进行了更改,以及您建议的所有其他更改,页面仍然没有使用新的选定值刷新,它在刷新时恢复为默认值。 “@radii”中的值似乎可以对结果进行排序,但据我所知,表单中的选择不会影响“@radii”。
猜你喜欢
  • 2015-06-21
  • 1970-01-01
  • 2013-07-11
  • 2017-10-11
  • 2019-01-05
  • 1970-01-01
  • 2019-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多