Rails 4表单:根据单选按钮选择条件显示字段

3

首先,如果这个问题很愚蠢,请原谅我,我刚开始了解Rails,而JavaScript和jQuery是一个全新的世界。

我找到了下面类似的问题,但是我不明白它们如何适用于我的情况:

话虽如此,这是我的问题。

在我的Rails 4应用程序中,我有以下Rails表单(我使用Simple Form):

<div class="calendar_details">
  <%= f.label :target_relationship %>
  <%= radio_button_tag(:target_relationship, "B2C", :checked => true, :onclick=>"showMe('calendar_details_b2c')", {:class => "radio_button_target_relationship_b2C"}) %>
  <%= label_tag(:target_relationship, "B2C") %>
  <%= radio_button_tag(:target_relationship, "B2B", :onclick=>"showMe('calendar_details_b2b')", {:class => "radio_button_target_relationship_b2b"}) %>
  <%= label_tag(:target_relationship, "B2B") %>
</div>

<div class="calendar_details">
  <%= f.label :target_country %><%= f.country_select :target_country, ["United States"] %>
</div>

<div id="calendar_details_b2c">

  <div class="calendar_details">
  <%= f.label :target_gender %><%= radio_button_tag(:target_gender, "Female") %><%= label_tag(:target_relationship, "Female") %><%= radio_button_tag(:target_gender, "Male") %><%= label_tag(:target_relationship, "Male") %><%= radio_button_tag(:target_gender, "Both", :checked => true) %><%= label_tag(:target_relationship, "Both") %>
  </div>
  <div class="calendar_details">
    <%= f.label :target_age_lower_limit %><%= f.select :target_age_lower_limit, (0..99) %>
  </div>
  <div class="calendar_details">
    <%= f.label :target_age_upper_limit %><%= f.select :target_age_upper_limit, (0..99) %>
  </div>
  <div class="calendar_details">
    <%= f.label :target_household_income_lower_limit %><%= f.select :target_household_income_lower_limit, ['Less than $10,000', '$10,000', '$20,000', '$30,000', '$40,000', '$50,000', '$60,000', '$70,000', '$80,000', '$90,000', '$100,000', '$110,000', '$120,000', '$130,000', '$140,000', '$150,000', '$160,000', '$170,000', '$180,000', '$190,000', '$190,000', '$200,000', 'More than $200,000'] %>
  </div>
  <div class="calendar_details">
    <%= f.label :target_household_income_upper_limit %><%= f.select :target_household_income_upper_limit, ['Less than $10,000', '$10,000', '$20,000', '$30,000', '$40,000', '$50,000', '$60,000', '$70,000', '$80,000', '$90,000', '$100,000', '$110,000', '$120,000', '$130,000', '$140,000', '$150,000', '$160,000', '$170,000', '$180,000', '$190,000', '$190,000', '$200,000', 'More than $200,000'] %>
  </div>

</div>

<div id="calendar_details_b2b">

  <div class="calendar_details">
    <%= f.label :target_company_size %><%= f.select :target_company_size, ['Self-employed', '1-10 employees', '11-50 employees', '51-200 employees', '201-500 employees', '501-1,000 employees', '1,001-5,000 employees', '5,001-10,000 employees', 'More than 10,000 employees'] %>
  </div>
  <div class="calendar_details">
    <%= f.label :target_industry %><%= f.select :target_industry, ['Art & Entertainment', 'Autos & Vehicles', 'Beauty & Fitness', 'Books & Litterature', 'Business & Industrial', 'Computer & Electronics', 'Finance', 'Food & Drinks', 'Games', 'Hobbies & Leisure', 'Home & Garden', 'Internet & Telecom', 'Jobs & Education', 'Law & Government', 'News', 'Online Communities', 'People & Society', 'Pets & Animals', 'Real Estate', 'Science', 'Shopping', 'Sports', 'Travel']  %>
  </div>

</div>

根据用户在第一个单选按钮上选择的内容(“B2C”或“B2B”),我想要显示calendar_details_b2c divcalendar_details_b2b div
我理解我需要隐藏两个div,然后实现某种形式的条件检查,检查哪个单选按钮被选中,最后显示正确的div
正如您所看到的,我尝试添加了一个onclick选项和一些特定的类到我的单选按钮中,但是我卡住了:我不知道如何构建正确的js函数,也不知道在哪里包含它(在表单的.html.erb文件中,在应用程序的头部,在application.js文件中?)。

—————

更新: 根据Ziv Galili的回答,这是我现在拥有的内容:

app/assets/javascript/custom/calendars.js中:

$(document).ready(function() {
    $('input[type=radio][name=calendar').change(function () {
      // first: hide all the divs
      $('#calendar_details_b2c').css("display","none");
      $('#calendar_details_b2b').css("display","none");

      // then get the div ID to show (I stored it in the "value" of the radio button)
      var fieldToShow = $(this).val();
      // now use jQuery selector and change the display setting of that field
      $("#" + fieldToShow).css("display","block");
    });
});

在`application.js`中,我添加了`//= require_tree ./custom`,以便在我的应用程序中考虑上述代码。
在我的表单所在的视图(`Calendars#New`)中,现在有:
<div class="calendar_details">
    <%= f.label :target_relationship, "Business relationship" %>
    <%= f.radio_button :target_relationship, "calendar_details_b2c", :checked => true %>
    <%= f.label(:target_relationship, "B2C") %>
    <%= f.radio_button :target_relationship, "calendar_details_b2b", :checked => false %>
    <%= f.label(:target_relationship, "B2B") %>
  </div>

  <div class="calendar_details">
    <%= f.label :target_country, "Country" %><%= f.country_select :target_country, ["United States"] %>
  </div>

  <div id="calendar_details_b2c">

    <div class="calendar_details">
    <%= f.label :target_gender, "Gender" %><%= radio_button_tag(:target_gender, "Female") %><%= label_tag(:target_relationship, "Female") %><%= radio_button_tag(:target_gender, "Male") %><%= label_tag(:target_relationship, "Male") %><%= radio_button_tag(:target_gender, "Both", :checked => true) %><%= label_tag(:target_relationship, "Both") %>
    </div>
    <div class="calendar_details">
      <%= f.label :target_age_lower_limit, "Age / Lower limit" %><%= f.select :target_age_lower_limit, (0..99) %>
    </div>
    <div class="calendar_details">
      <%= f.label :target_age_upper_limit, "Age / Upper limit" %><%= f.select :target_age_upper_limit, (0..99) %>
    </div>
    <div class="calendar_details">
      <%= f.label :target_household_income_lower_limit, "Household income / Lower limit" %><%= f.select :target_household_income_lower_limit, ['Less than $10,000', '$10,000', '$20,000', '$30,000', '$40,000', '$50,000', '$60,000', '$70,000', '$80,000', '$90,000', '$100,000', '$110,000', '$120,000', '$130,000', '$140,000', '$150,000', '$160,000', '$170,000', '$180,000', '$190,000', '$190,000', '$200,000', 'More than $200,000'] %>
    </div>
    <div class="calendar_details">
      <%= f.label :target_household_income_upper_limit, "Household income / Upper limit" %><%= f.select :target_household_income_upper_limit, ['Less than $10,000', '$10,000', '$20,000', '$30,000', '$40,000', '$50,000', '$60,000', '$70,000', '$80,000', '$90,000', '$100,000', '$110,000', '$120,000', '$130,000', '$140,000', '$150,000', '$160,000', '$170,000', '$180,000', '$190,000', '$190,000', '$200,000', 'More than $200,000'] %>
    </div>

  </div>

  <div id="calendar_details_b2b">

    <div class="calendar_details">
      <%= f.label :target_company_size, "Company size" %><%= f.select :target_company_size, ['Self-employed', '1-10 employees', '11-50 employees', '51-200 employees', '201-500 employees', '501-1,000 employees', '1,001-5,000 employees', '5,001-10,000 employees', 'More than 10,000 employees'] %>
    </div>
    <div class="calendar_details">
      <%= f.label :target_industry, "Industry" %><%= f.select :target_industry, ['Art & Entertainment', 'Autos & Vehicles', 'Beauty & Fitness', 'Books & Litterature', 'Business & Industrial', 'Computer & Electronics', 'Finance', 'Food & Drinks', 'Games', 'Hobbies & Leisure', 'Home & Garden', 'Internet & Telecom', 'Jobs & Education', 'Law & Government', 'News', 'Online Communities', 'People & Society', 'Pets & Animals', 'Real Estate', 'Science', 'Shopping', 'Sports', 'Travel']  %>
    </div>

  </div>

然而,我似乎无法使其工作:当我访问Calendars#New视图时,我确实看到了单选按钮以选择B2C或B2B,但是无论我选择哪个按钮,下面都没有显示任何内容(既不是B2C部分也不是B2B部分)。
我错过了什么?

—————

更新2:因此,我按照Ziv Galili的新评论更新了我的代码,即关注按钮组的名称,实际上是calendar[target_relationship]

当我这样做并尝试查看时,我得到了一个execJS::RuntimeError,这让我意识到我们正在使用纯JavaScript,而我的Rails应用程序似乎在使用CoffeeScript。

所以,我删除了app/assets/javascript/custom/calendars.js,将Ziv Galili的代码转换为CoffeeScript并将其添加到app/assets/javascript/calendars.coffee中:

$('input[type=radio][name=calendar[target_relationship]]').change ->
  # first: hide all the divs
  $('#calendar_details_b2c').css 'display', 'none'
  $('#calendar_details_b2b').css 'display', 'none'
  # then get the div ID to show (i stored it in the "value" of the radio button
  fieldToShow = $(this).val()
  # now use jQuery selector and change the display setting of that field
  $('#' + fieldToShow).css 'display', 'block'
  return

我还将//= require_tree ./custom替换为//= require_tree .,以确保我的所有.coffee文件都通过application.js加载。

尽管进行了所有这些代码更新,但我仍然没有得到我期望的结果:我的视图中没有任何div被显示出来。

enter image description here

我一定是漏掉了非常非常明显的东西,但我想不出来是什么。

有任何想法吗?

—————

任何形式的帮助都将不胜感激。
3个回答

4
我会这样做: jsFiddle 解释:
假设HTML代码如下:
<form action="">
  <input type="radio" name="calendars" value="calendar_details_b2b">B2B
  <br>
  <input type="radio" name="calendars" value="calendar_details_b2c">B2C
</form>
<div id="calendar_details_b2c" style=>
  content of B2C
</div>
<div id="calendar_details_b2b">
  content of B2B
</div>

添加 CSS 代码,使 div 在页面加载时不会显示:
#calendar_details_b2c,
#calendar_details_b2b
{
  display: none;
}

JS代码将会是:

$('input[type=radio][name=calendars]').change(function () {
  // first: hide all the divs
  $('#calendar_details_b2c').css("display","none");
  $('#calendar_details_b2b').css("display","none");

  // then get the div ID to show (i stored it in the "value" of the radio button
  var fieldToShow = $(this).val();
  // now use jQuery selector and change the display setting of that field
  $("#" + fieldToShow).css("display","block");
});

更新:

关于您的更新,请注意在JS部分,按钮组的名称与HTML文件中的名称匹配:

js:

$('input[type=radio][name=NAME_OF_BUTTON_GROUP]')

要在HTML中查找名称,您可以(在Chrome中):

  1. 右键单击其中一个单选按钮
  2. 按下检查元素
  3. 在元素检查器中查找输入的名称属性

<input checked="checked" id="something_calendar_details_b2c" name="这是名称" type="radio" value="calendar_details_b2c">

注意:如果名称中有方括号(或任何其他特殊字符),则应用撇号将其包裹起来。

$('input[type=radio][name="calendar[target_relationship]"]')

非常感谢您详细的回答。只有一个快速的问题:我应该把JS代码放在Rails的哪里?在我的application.js文件中吗? - Thibaud Clement
我在app/assets/javascript文件夹中创建了一个名为custom.js的文件,然后我在application.js文件中添加了//= require custom.js以确保它在页面加载时被包含。在custom.js文件中,我粘贴了你的代码。但是它似乎在我的端上无法工作。你有什么想法我可能做错了什么吗? - Thibaud Clement
JS代码应该放在对应的控制器js文件中(如果您在项目控制器中,则文件应该被称为projects.js)(这是我的意见,不一定适用于任何情况的正确解决方案)。关于您的问题:尝试在JS文件中在您的代码周围添加$( document ).ready(function() { CODE }); - Ziv Galili
谢谢。我在更新2部分添加了一些新信息。我真的不明白我做错了什么... - Thibaud Clement
只需将名称用单引号括起来: $('input[type=radio][name="calendar[target_relationship]"]'),它就应该正常工作。 - Ziv Galili
显示剩余3条评论

1
您可以在js文件中轻松使用jQuery函数。
只需使用:
```javascript $(selector).function() ```
$('input[type=radio][name=abc]').change(function() {
    // check radio button value by this.value
    // hide div blocks by $('div#id').hide();
});

谢谢,非常有帮助。 - Thibaud Clement

-1

<script src="//code.jquery.com/jquery-1.11.1.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js"></script>
<script>

 $(function() {
            var $divs = $('#divs > div');
            $divs.first().show();
            $('input[type=radio]').on('change',function() {
                 $divs.hide();
                 $divs.eq( $('input[type=radio]').index( this ) ).show();
             });
   });
 
</script>
  #divs div {
      display:none;
  }
<div class="container">
 <div class="form-container">
  <form class="registerform" action="register.php" method="post" id="registerform">
   <h3 class="title">Register</h3>
   <div class="cdiv">User Name:</div>
   <div class="cdiv"><input class="ipcontact" name="username" type="text" id="username"></div>
   <div class="cdiv">Password:</div>
   <div class="cdiv"><input class="ipcontact" name="password" type="password" id="password"></div>
   <div class="cdiv">Name:</div>
   <div class="cdiv"><input class="ipcontact" name="name" type="text" id="name"></div>
   <div class="cdiv">E-mail:</div>
   <div class="cdiv"><input class="ipcontact" name="email" type="email" id="email"></div>
   <div class="cdiv">Phone Number:</div>
   <div class="cdiv"><input class="ipcontact" name="phonenumber" type="number" id="phonenumber"></div>
   <div class="cdiv">Student<input type="radio" name="check" checked value="1">Teacher<input type="radio" name="check" value="2"></div>


   <div id = "divs">
    <div class="form-group" id = "div2">
     Student Class:<br/>
     <input class="ipcontact" name="studentclass" type="text" id="studentclass"><br/>
     Student Roll Number:<br/>
     <input class="ipcontact" name="studentrollnumber" type="text" id="studentrollnumber"> 
    </div>
    <div class="form-group" id = "div1" >
     Teacher type:<br/>
     <input class="ipcontact" name="teachertype" type="text" id="teachertype">
    </div>
   </div>
   <div class="form-group"> <input class="login-button" type="submit" name="submit" value="Register"></div>
  </form>
 </div>
</div>

<!DOCTYPE html>
<html>

<head>
<script src="//code.jquery.com/jquery-1.11.1.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js">                                    </script>
</head>

<body>
<script>


$(function() {
            var $divs = $('#divs > div');
            $divs.first().show();
            $('input[type=radio]').on('change',function() {
                $divs.hide();
                $divs.eq( $('input[type=radio]').index( this ) ).show();
            });
        });

</script>

<div class="container">
<div class="form-container">
    <form class="registerform" action="register.php" method="post" id="registerform">
        <h3 class="title">Register</h3>
        <div class="cdiv">User Name:</div>
        <div class="cdiv"><input class="ipcontact" name="username" type="text" id="username"></div>
        <div class="cdiv">Password:</div>
        <div class="cdiv"><input class="ipcontact" name="password" type="password" id="password"></div>
        <div class="cdiv">Name:</div>
        <div class="cdiv"><input class="ipcontact" name="name" type="text" id="name"></div>
        <div class="cdiv">E-mail:</div>
        <div class="cdiv"><input class="ipcontact" name="email" type="email" id="email"></div>
        <div class="cdiv">Phone Number:</div>
        <div class="cdiv"><input class="ipcontact" name="phonenumber" type="number" id="phonenumber"></div>
        <div class="cdiv">Student<input type="radio" name="check" checked value="1">Teacher<input type="radio" name="check" value="2"></div>


        <div id = "divs">
            <div class="form-group" id = "div2">
                Student Class:<br/>
                <input class="ipcontact" name="studentclass" type="text" id="studentclass"><br/>
                Student Roll Number:<br/>
                <input class="ipcontact" name="studentrollnumber" type="text" id="studentrollnumber"> 
            </div>
            <div class="form-group" id = "div1" >
                Teacher type:<br/>
                <input class="ipcontact" name="teachertype" type="text" id="teachertype">
            </div>
        </div>
        <div class="form-group"> <input class="login-button" type="submit" name="submit" value="Register"></div>
    </form>
</div>
</div>

</body>
</html>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接