Rails 4 - 基于嵌套形式的第一个选择菜单中的选择动态填充第二个选择菜单 [英] Rails 4 - dynamically populate 2nd select menu based on choice in first select menu in a nested form

查看:13
本文介绍了Rails 4 - 基于嵌套形式的第一个选择菜单中的选择动态填充第二个选择菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Rails 4 应用中有 Project 和 Ethic 模型.

I have models for Project and Ethic in my Rails 4 app.

道德视图中包含一个嵌套字段表单(使用简单表单简单字段).道德表单字段嵌套在项目表单中.

The ethics view has a nested fields form (using simple form simple fields for) contained in it. The ethic form fields are nested in the projects form.

道德表单字段有 2 个选择菜单.第一个菜单为一个类别提供了一组选项.第二个选择选项是子类别列表.

The ethic form fields has 2 select menus. The first menu offers a set of options for a category. The 2nd select option is a list of subcategories.

我正在尝试根据在第一个选择菜单中所做的选择,弄清楚如何使用正确的选项填充第二个选择菜单.

I'm trying to figure out how to populate the 2nd select menu with the right options, based on the choice made in the 1st select menu.

在我的 project.js 文件中,我有:

In my project.js file, I have:

jQuery(document).ready(function() {

   jQuery("#project_ethic_attributes.main_category").change(function() {
      var category = $("#project_ethic_attributes.main_category").val(),
        sub_category = $("#project_ethic_attributes.sub_category"),
        options = [],
        str = "";
      sub_category.find('option').remove();
      if(category == 'Risk of harm'){
      options = ["Physical Harm", "Psychological distress or discomfort", "Social disadvantage", "Harm to participants", "Financial status", "Privacy"]
    }

   });

   // jQuery(".main_category").change(function() {
   //  var category = $(".main_category").val(),
   //      sub_category = $(".sub_category"),
   //      options = [],
   //      str = "";
   //  sub_category.find('option').remove();

   //  if(category == 'Risk of harm'){
   //    options = ["Physical Harm", "Psychological distress or discomfort", "Social disadvantage", "Harm to participants", "Financial status", "Privacy"]
   //  }
   //  else if(category == 'Informed consent'){
   //    options = ["Explanation of research", "Explanation of participant's role in research"]   
   //  }
   //  else if(category == 'Anonymity and Confidentiality'){
   //    options = ["Remove identifiers", "Use proxies", "Disclosure for limited purposes"]
   //  }
   //  else if(category == 'Deceptive practices'){
   //    options = ["Feasibility"]
   //  }
   //  else if(category == 'Right to withdraw'){
   //    options = ["Right to withdraw from participation in the project"]  
   //  }
   //  if(options.length > 0){
   //    for(i=0;i<options.length;i++){
   //      str = '<option value="' + options[i] + '">' + options[i] + '</option>'
   //      sub_category.append(str);
   //    }
   //    sub_category.val(options[0]);
   //  }


});

我不知道我做错了什么.无论我在第一个选项中做出何种选择,第二个选择菜单都会填充属于最后一个类别的选项.

I can't figure out what Im doing wrong. Regardless of the choice I make in the 1st option, the 2nd select menu is populated with options that belong to the last category.

我的项目表单有:

 <%= f.simple_fields_for :ethics do |f| %>
        <%= render 'ethics/ethic_fields', f: f %>
 <% end %>
 <%= link_to_add_association 'Add an ethics consideration', f, :ethics, partial: 'ethics/ethic_fields' %>

我的道德表单字段有:

<%= f.input :category, collection: [ "Risk of harm", "Informed consent", "Anonymity and Confidentiality", "Deceptive practices", "Right to withdraw"], :label => "Principle",  prompt: 'select', id: "main_category" %>


            <%= f.input :subcategory,  collection: text_for_subcategory(@category), :label => "Subcategory", prompt: 'select', id: "sub_category" %>

我的道德观助手有:

def text_for_subcategory(category)
      if category == 'Risk of harm'
            [ "Physical Harm", "Psychological distress or discomfort", "Social disadvantage", "Harm to participants", "Financial status", "Privacy"]
        elsif category == 'Informed consent'
            ["Explanation of research", "Explanation of participant's role in research"]
        elsif category == 'Anonymity and Confidentiality'
            ["Remove identifiers", "Use proxies", "Disclosure for limited purposes"]
        elsif category == 'Deceptive practices' 
            ["Feasibility"] 
        else category == 'Right to withdraw'    
            ["Right to withdraw from participation in the project"] 
       end
    end  

任何人都可以看到我需要做什么才能根据第一个选择菜单中的选择使用正确的选项填充第二个选择菜单.我想知道我是否不应该在 project.js 文件中编写 jQuery,因为表单字段包含在道德视图部分中(在项目表单中呈现).

Can anyone see what i need to do to populate the second select menu with the right options based on the choice made in the 1st select menu. I'm wondering if I'm not supposed to write the jQuery in the project.js file, given the form fields are contained within an ethic view partial (rendered in the projects form).

MIXAN 的建议

我的表单现在有:

<%= f.input :category, collection: [ "Risk of harm", "Informed consent", "Anonymity and Confidentiality", "Deceptive practices", "Right to withdraw"], option:'disabled selected value', :label => "Principle",  prompt: 'select', id: "main_category" %>


        <%= f.input :subcategory,  :label => "Subcategory", prompt: 'select', id: "sub_category", option:'disabled' %>

我不得不稍微改变一下表格,因为我使用了带导轨的简单表格.我不确定我是否已将禁用选定值"和禁用"选项正确添加到表单输入中.

I had to change the form a bit because I use simple form with rails. I'm not sure if I have added the 'disabled selected value' and 'disabled' options to the form inputs correctly.

目前,表单呈现 - 但第二个菜单未填充任何内容.不知道是不是和js文件中使用option标签有关?

At the moment, the form renders- but the second menu is not populated with any content. I wonder if that has something to do with the use of the option tags in the js file?

ethics.js 有:

ethics.js has:

jQuery(document).ready(function() {
  var optionsMap = {
      'Risk of harm': [
        'Physical Harm', 
        'Psychological distress or discomfort', 
        'Social disadvantage', 
        'Harm to participants', 
        'Financial status', 
        'Privacy'
      ],
      'Informed consent': [
        'Explanation of research', 
        "Explanation of participant's role in research"
      ],
      'Anonymity and Confidentiality': [
        'Remove identifiers', 'Use proxies', 'Disclosure for limited purposes'
      ],
      'Deceptive practices': [
        'Feasibility'
      ],
      'Right to withdraw': [
        'Right to withdraw from participation in the project'
      ]
    };

  jQuery('#main_category').change(function() {
    var category = jQuery(this).val(),
        $subCategory = jQuery('#sub_category'),
        newOptions = optionsMap[category];
    $subCategory.attr('disabled', false)
    $subCategory.empty();
    $.each(newOptions, function() {
      $subCategory.append(jQuery("<option></option>").text(this));
    });
  })
});

MIXAN 的修正建议

<%= f.select :category, collection: [ "Risk of harm", "Informed consent", "Anonymity and Confidentiality", "Deceptive practices", "Right to withdraw"], option:'disabled selected value', :label => "Principle", prompt: 'select', html: { id: "main_category" } %>


<%= f.select :subcategory, [], {}, id: "sub_category", disabled: true %>

当我尝试这个时,第一类菜单下拉菜单的格式发生了变化,但功能与我使用 f.input 时相同.不过,第二个菜单没有填充任何选项.

When I try this, the formatting of the menu drop down for the first category is changed, but the functionality is the same as when I use f.input. The second menu does not populate with any options though.

推荐答案

在提供的示例中,您似乎选择了错误的 DOM 元素.直接用id来引用就更清楚了,不会和属性命名那么耦合.我建议您的任务的下一个方法.首先在客户端构建选择映射:

In provided example seems that you selecting wrong DOM elements. Just reference them by id, it will be more clear and it will be not so coupled with attributes naming. I suggesting the next approach for your task. First build the map of selects on client side:

var optionsMap = {
    'Risk of harm': [
      'Physical Harm', 
      'Psychological distress or discomfort', 
      'Social disadvantage', 
      'Harm to participants', 
      'Financial status', 
      'Privacy'
    ],
    'Informed consent': [
      'Explanation of research', 
      "Explanation of participant's role in research"
    ],
    'Anonymity and Confidentiality': [
      'Remove identifiers', 'Use proxies', 'Disclosure for limited purposes'
    ],
    'Deceptive practices': [
      'Feasibility'
    ],
    'Right to withdraw': [
      'Right to withdraw from participation in the project'
    ]
  };

然后只监听主选择和子选择重建选项的变化.

Then just listen for changes of main select and rebuild options for sub select.

jQuery('#main_category').change(function() {
  var category = jQuery(this).val(),
      $subCategory = jQuery('#sub_category'),
      newOptions = optionsMap[category];

  $subCategory.empty();
  $.each(newOptions, function(key,value) {
    $subCategory.append(jQuery("<option></option>").attr("value", value).text(key));
  });
})

这是一个简单的 html 表单的示例

Here an example how it looks like with plain html form

jQuery(document).ready(function() {
  var optionsMap = {
      'Risk of harm': [
        'Physical Harm', 
        'Psychological distress or discomfort', 
        'Social disadvantage', 
        'Harm to participants', 
        'Financial status', 
        'Privacy'
      ],
      'Informed consent': [
        'Explanation of research', 
        "Explanation of participant's role in research"
      ],
      'Anonymity and Confidentiality': [
        'Remove identifiers', 'Use proxies', 'Disclosure for limited purposes'
      ],
      'Deceptive practices': [
        'Feasibility'
      ],
      'Right to withdraw': [
        'Right to withdraw from participation in the project'
      ]
    };

  jQuery('#main_category').change(function() {
    var category = jQuery(this).val(),
        $subCategory = jQuery('#sub_category'),
        newOptions = optionsMap[category];
    $subCategory.attr('disabled', false)
    $subCategory.empty();
    $.each(newOptions, function() {
      $subCategory.append(jQuery("<option></option>").text(this));
    });
  })
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <select id='main_category'>
    <option disabled selected value> -- select an option -- </option>
    <option>Risk of harm</option>
    <option>Informed consent</option>
    <option>Anonymity and Confidentiality</option>
    <option>Deceptive practices</option>
    <option>Right to withdraw</option>
  </select>
  <select id='sub_category' disabled>
  </select>
</form>

这篇关于Rails 4 - 基于嵌套形式的第一个选择菜单中的选择动态填充第二个选择菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆