【问题标题】:How get the value of a collection_select within the same html.erb form itself如何在同一个 html.erb 表单本身中获取 collection_select 的值
【发布时间】:2016-11-03 00:48:19
【问题描述】:

我有这个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} %>

我该怎么做?

【问题讨论】:

  • 如果你想要顺利,你需要通过一些远程按钮来做JS或UJS。

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    静态发生在呈现 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 } %>
    

    为什么会这样?初始collection_select:selected 选项是您提供最初选择的选项的位置。由于此值通常取自模型值,因此它在与实际集合值不同的参数中提供。因此,只需遵守 Rails 约定,它就已排好队并为您准备好了。

    随后的 select 构建 HTML &lt;select&gt; 元素并使用 options_for_select 将选项数组转换为 HTML &lt;option&gt; 元素。这样一来,您就可以根据选择了原始collection_select 中的哪个元素,使用变量列表进行选择。

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

    动态检测

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

    <%= 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,其余的从那里发生。当集合发生变化(选择了新值)时,事件处理程序将隐藏或显示第三个选择 &lt;option&gt;(指定为 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 启动页面加载事件。

    仅此而已。添加动态行为就是这么简单!

    【讨论】:

    • 我一直在关注你,直到 use_this_list();use_this_other_list(); 方法。我会说在这些方法中创建两个不同的数组吗?我也可以在表单中访问它们,还是必须以某种方式通过它们?抱歉,如果我遗漏了一些明显的东西,我对这些东西有点陌生
    • 恐怕我不知道你应该在那里做什么;您没有在问题中包含该信息。我所知道的是你说你想确定“当显示另一个collection_select时我应该使用哪个列表”,然后你使用了伪代码“使用这个列表”和“使用这个另一个列表”。这就是我掌握的所有信息。我什至不知道这些列表是什么,或者你打算用它们做什么。如果您更新您的问题以包含所有详细信息,我可以更新我的答案。
    • 我已经更新了我的问题。基本上,如果选择的 bmp 是 2,我只想排除其中一个选项
    • 好的,我已经更新了我的答案以包含这些详细信息。
    • 列表一定要这样吗? ["Sprinkle", "Furrow/Flood", "Drip", "Furrow Diking", "Pads and Pipes - Tailwater Irrigation"] 因为这给了我一个错误undefined method 'name' for "Sprinkle":String。同样在 var drip_option = drip_collection.find("option")[2]; 上是 option 一个 id,2 是要删除的值的 id 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多