Rails 4 - 根据嵌套表单中第一个选择菜单中的选项动态填充第二个选择菜单

时间:2016-08-13 08:01:31

标签: jquery ruby-on-rails forms select drop-down-menu

我的Rails 4应用程序中有Project和Ethic模型。

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

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

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

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

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]);
   //  }


});

我无法弄清楚我做错了什么。无论我在第一个选项中做出的选择如何,第二个选择菜单都会填充属于最后一个类别的选项。

我的项目表格有:

 <%= 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,因为表单字段包含在ethic视图partial(在项目表单中呈现)中。

MIXAN's SEGGESTION

我的表单现在有:

<%= 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' %>

我不得不稍微更改表单,因为我使用带有rails的简单表单。我不确定是否已将“禁用选定值”和“禁用”选项正确添加到表单输入中。

目前,表单呈现 - 但第二个菜单没有填充任何内容。我想知道这是否与在js文件中使用选项标签有关?

ethics.js有:

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时的功能相同。第二个菜单不会填充任何选项。

2 个答案:

答案 0 :(得分:0)

使用此代码,为#idurls

编辑代码
// Dynamic Search Model Loader
$(function(){
    var saved = {};
    var options, value;
    $("#selectOne").change(function(){
        options = '<option value="" selected="selected">Loading...</option>';
        $("#selectTwo").html(options);
        value = $(this).val();

        if (saved[value].length > 0) {
           $("#selectTwo").html(saved[value]);
        } else {
          $.ajax({
            url: '/api/get-json-values/?category=' + value, // Set the category as the value or whatever you want it to be
            type: 'GET',
            dataType: 'json',
            async: true
        }).done(function(data){
            options = '<option value="" selected="selected">Please Pick...</option>';
            // Parse through the values
            $.each(data, function(text){
                options += '<option value="' + text + '">' + text + '</option>';
            });
            // Populate the second select menu
            $("#selectTwo").html(options);
            saved[value] = options;
          }).fail(function(data){
            options = '<option value="" selected="selected">Empty...</option>';
            $("#selectTwo").html(options);
          }); // End Ajax
         };
    }); // End Change
});

根据需要对其他选择菜单重复

要求您在控制器中创建一个操作,该操作将返回包含所需值的JSON。

** Routes.rb **

namespace :api do
    get 'get-json-values', to: 'queries#category_search'
end

控制器代码:

class API::Queries < ApplicationController

  def category_search
    category = params[:category]

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

    if @json
      render json: @json.to_json, status: 200
    else
      render json: {message: 'Not Found'}, status: 404
    end
  end
end

然后它将通过它们并将它们作为选项添加到 slave 选择菜单

答案 1 :(得分:0)

在提供的示例中,您似乎选择了错误的DOM元素。只需通过id引用它们,它就会更清晰,并且不会与属性命名相结合。 我建议你的下一个方法来完成你的任务。 首先在客户端构建选择映射:

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

这是一个用普通html表单看起来如何的例子

&#13;
&#13;
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));
    });
  })
});
&#13;
<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>
&#13;
&#13;
&#13;