如何在同一个html.erb表单中获取collection_select的值

时间:2016-06-30 19:02:33

标签: ruby-on-rails forms coffeescript erb collection-select

我有一个包含此collection_select

的表单
    <%= collection_select :bmp, :bmpsublist_id,
                          Bmpsublist.where(:bmplist_id => @bmp.bmp_id), :id,
                          :name,{ :required => false, 
                          :selected => @bmp.bmpsublist_id, } %>

我希望能够获得此collection_select的值以便以相同的形式降低,我可以查看在显示另一个collection_select时应该使用哪个列表

像这样的部分伪代码:

if earlier result == 2 then
  use this list: Irrigation.where(:id != 8)
else
  use this other list: Irrigation.all

他们将更新collection_select:

<%= collection_select :bmp, :irrigation_id, the_chosen_list_from_above, :id, :name, 
                            {:prompt => 'Select Irrigation Type'}, {:required => true} %>

我该怎么做?

2 个答案:

答案 0 :(得分:0)

你必须使用一些javascript(jquery和ajax,我建议)。当第一个选择的值更改(jquery)时,它请求(ajax)集合(将选定的当前值传递)到控制器操作,该操作返回应该使用的集合。返回集合后,将填充第二个选择的选项(jquery)。这不是很简单,但如果你做过类似的事情,你就不会有问题。如果从未做过,请做一些关于它的研究......它非常有用并且可以大大改善用户体验!

答案 1 :(得分:0)

根据您的要求,有两种方法可以查询和应用集合的值:静态和动态。

静态发生在呈现ERB视图时,这将在最初呈现和加载页面时应用逻辑。加载页面后,动态发生,并且当用户与页面上的元素交互时。您选择采用哪种方法完全取决于您的应用程序的设计以及与用户的预期交互级别。

静态检测

您已在初始collection_select中指定所选项目,因此您可以在以后的代码中重复使用该项目。试试这个,基于您的伪代码示例:

<% if @bmp.bmpsublist_id == 2 %>
  <% irrigation_list = ["Sprinkle", "Furrow/Flood", "Drip", "Furrow Diking"] %>
<% else %>
  <% irrigation_list = ["Sprinkle", "Furrow/Flood", "Drip", "Furrow Diking", "Pads and Pipes - Tailwater Irrigation"] %>
<% end %>
<%= select :bmp, :irrigation_id, options_for_select(irrigation_list),
           { :prompt => 'Select Irrigation Type'}, { :required => true } %>

为什么这会起作用?初始:selected的{​​{1}}选项是您提供最初选择的选项的位置。由于此值通常取自模型值,因此它在实际集合值的单独参数中提供。因此,它只是因为坚持Rails惯例而排队等待并为您做好准备。

后续select构建HTML collection_select元素,并使用options_for_select将选项数组转换为HTML <select>元素。这样,您可以根据选择原始<option>中的哪个元素,使用变量选项列表进行选择。

最棒的是:使用静态方法,您不必使用Javascript(或jQuery)来执行此操作;它会直接由ERB模板(或HAML模板,如果那是你的包)呈现。

动态检测

如果你真的想要动态行为,你可以放入Javascript / jQuery并完成它。您可以像使用静态方法(上面)一样创建“灌溉类型”collection_select,除非您使用所有选项对其进行初始化,例如:

select

然后,编辑与您的视图关联的Javascript源(让我们称之为<%= select :bmp, :irrigation_id, options_for_select(["Sprinkle", "Furrow/Flood", "Drip", "Furrow Diking", "Pads and Pipes - Tailwater Irrigation"]), { :prompt => 'Select Irrigation Type'}, { :required => true } %> )。打开Product(如果您使用CoffeeScript,它是同一目录中的app/assets/javascripts/product.js文件。)

编辑该Javascript文件以包含此代码:

product.coffee

这标识集合的HTML元素并安装function OnProductEditForm() { // Edit the selectors to match the actual generated "id" for the collections var bmp_collection = $("#product_bmp"); var drip_collection = $("#product_irrigation_type"); var drip_option = drip_collection.find("option")[2]; function select_available_drip_options() { var value = bmp_collection.val(); if (value == 2) { drip_option.attr("disabled", "disabled"); } else { drip_option.removeAttr("disabled"); } } bmp_collection.change(function() { select_available_drip_options(); }); select_available_drip_options(); } 事件处理程序。根据代码注释,您需要验证集合元素的change,其余部分从那里发生。更改集合(选择新值)后,事件处理程序将隐藏或显示第三个选择id(指定为<option>),以适合find("option")[2]选择。< / p>

接下来,在app / views / products / _form.html.erb中,将其包含在文件的末尾:

#product_bmp

这将在页面加载时自动加载<script> jQuery(document).ready(OnProductEditForm); // Uncomment the next 2 lines for TurboLinks page refreshing //jQuery(document).on('page:load', OnProductEditForm); //jQuery(document).on('page:restore', OnProductEditForm); </script> 方法,并将导致安装上述事件处理程序。请注意,如果启用了TurboLink,则最后2行是必需的,因为TurboLinks会独立于标准OnProductEditForm启动页面加载事件。

这就是它的全部内容。添加动态行为就是这么简单!