3

我有一个表格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} %>

我怎样才能做到这一点?

4

2 回答 2

2

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

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

静态检测

您已经在 initial 中指定了所选项目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选项collection_select是您提供最初选择的选项的位置。由于此值通常取自模型值,因此它在与实际集合值不同的参数中提供。因此,只需遵守 Rails 约定,它就已经排好队并为您准备好了。

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

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

动态检测

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

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

然后,编辑与您的视图关联的 Javascript 源代码(我们称之为Product)。打开app/assets/javascripts/product.js(如果您使用 CoffeeScript,它是product.coffee同一目录中的文件)。

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

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();
}

这会识别集合的 HTML 元素并安装change事件处理程序。您需要id根据代码注释验证集合元素的 ,其余的从那里发生。当集合被更改(选择了一个新值)时,事件处理程序将隐藏或显示第三个选择<option>(指定为find("option")[2]),以适合#product_bmp选择。

接下来,在 app/views/products/_form.html.erb 中,在文件末尾包含以下内容:

<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>

这将在页面加载时自动加载该OnProductEditForm方法,并导致安装上述事件处理程序。请注意,如果您启用了 TurboLinks,则最后两行是必需的,因为 TurboLinks 会独立于标准启动页面加载事件$(document).ready

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

于 2016-07-01T08:54:32.283 回答
0

你将不得不使用一些javascript(我建议jquery和ajax)。当第一个选择的值改变 (jquery) 时,它请求 (ajax) 集合(传递当前选择的值)到一个控制器操作,该操作返回应该使用的集合。随着集合返回,您为第二个选择填充选项 (jquery)。这不是很简单,但如果你曾经做过类似的事情,你不应该有问题。如果从未这样做过,请对其进行一些研究......它非常有用并且可以大大改善用户体验!

于 2016-06-30T20:25:20.357 回答