3

First, please excuse me if this question is dumb, I am just starting to wrap my head around Rails, and Javascript & jQuery are a whole new world for me.

I have found the following, similar questions, but simply don't understand how they could apply to my situation:

That being said, here is my question.

In my Rails 4 app, I have the following Rails form (I am NOT using 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>

Based on what users check on the first radio button (either "B2C" or "B2B"), I would like to either display the calendar_details_b2c div, or the calendar_details_b2b div.

I understand I am going to need to hide both divs, then to implement some form of condition, checking which radio button is checked, and finally display the right div.

As you can see, I tried to add an onclick option and some specific classes to my radio buttons, but then I am stuck: I don't know how to build the correct js function, and I don't know where to include it (in the .html.erb file of the form, in the header of the app, in the application.js file?).

—————

UPDATE: as per Ziv Galili's answer, here is what I have now:

In 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");
    });
});

In application.js, I added //= require_tree ./custom to take the above code into consideration in my app.

In the view where my form is (Calendars#New view), I now have:

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

However, I can't seem to make this work: when I visit the Calendars#New view, I do see the radio buttons to select either B2C or B2B, but whichever button I select, nothing is displayed below (neither the B2C section nor the B2B section).

What am I missing?

—————

UPDATE 2: So, I updated my code as Ziv Galili's new comment, ie: paying attention to the name of the button group, which is actually calendar[target_relationship].

When I did that, and tried to go to my view, I got a execJS::RuntimeError, which made me realize we were using pure JavaScript, while my Rails app seems to be using CoffeeScript.

So, I deleted app/assets/javascript/custom/calendars.js, converted Ziv Galili's code to CoffeeScript and added it to 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

I also replaced //= require_tree ./custom with //= require_tree . to make sure all my .coffee files were loaded through application.js.

Despite all these code updates, I still do not get the result I am expecting: none of the divs are displayed in my views:

enter image description here

I must be missing something really, really obvious, but I can't figure out what it is.

Any idea?

—————

Any kind of help would be highly appreciated.

Community
  • 1
  • 1
Thibaud Clement
  • 6,607
  • 10
  • 50
  • 103

3 Answers3

4

i would do something like this:

jsFiddle

Explanation:

lets say the HTML will be:

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

add css code so the divs won't be shown on page load:

#calendar_details_b2c,
#calendar_details_b2b
{
  display: none;
}

JS code will be:

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

UPDATE:

as for your update, please pay attention that in the JS section the name of the button group match their name in the HTML file:

js:

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

to find the name in the HTML you can (in chrome):

  1. Right click on one of the radio buttons
  2. press Inspect Element
  3. in the element inspector look for the name attribute of the input

<input checked="checked" id="something_calendar_details_b2c" name="THIS IS THE NAME" type="radio" value="calendar_details_b2c">

NOTE: if you have square brackets in the name (or any other special character) you should wrap it with apostrophes

$('input[type=radio][name="calendar[target_relationship]"]')
Ziv Galili
  • 1,405
  • 16
  • 20
  • Thanks a lot for your detailed answer. Just one quick question: where should I place the JS code in Rails? In my application.js file? – Thibaud Clement Oct 17 '15 at 15:18
  • I have created a `custom.js` file in my `app/assets/javascript` folder, and then I added `//= require custom.js` to my `application.js` file to make sure it was included on page load. In the `custom.js` file, I pasted your code. But it does not seem to work on my end. Any idea of what I may be doing wrong? – Thibaud Clement Oct 17 '15 at 15:41
  • JS code should go into the corresponding js file of the controller you are on (if you are in projects controller, then the file should be called projects.js) (thats my opinion, and not always the correct solution for any situation.) about your problem: try to add surrounding `$( document ).ready(function() {` CODE `});` around your code in the JS file – Ziv Galili Oct 19 '15 at 09:26
  • Ok, thanks a lot. I wrapped my js code as you recommended and moved it into the right file. You can see my question updated with all the relevant code in **UPDATE**. However, it seems I still can't make it work. Any idea what is wrong with what I am doing? Thanks in advance! – Thibaud Clement Oct 19 '15 at 15:55
  • Thanks. I added some new information in the **UPDATE 2** section. I really don't understand what I am doing wrong... – Thibaud Clement Oct 20 '15 at 14:53
  • just wrap the name with apostrophes: `$('input[type=radio][name="calendar[target_relationship]"]')` and it should work – Ziv Galili Oct 20 '15 at 15:39
  • Just updated the name with apostrophes, still get the same result (which I don't understand, because I went through the code many times: it all makes sense and should work). Any chance we can quickly jump on the chat to try and make this work? – Thibaud Clement Oct 20 '15 at 15:45
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/92879/discussion-between-thibaud-clement-and-ziv-galili). – Thibaud Clement Oct 20 '15 at 15:47
1

You can easily use jQuery functions in js file.

just use

$('input[type=radio][name=abc]').change(function() {
    // check radio button value by this.value
    // hide div blocks by $('div#id').hide();
});
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Hassan Ahmed
  • 168
  • 2
  • 9
-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>
Vasily Kabunov
  • 6,511
  • 13
  • 49
  • 53