Search code examples
javascripthtmlcsstwitter-bootstraptogglebutton

Can't get div to show when unchecked


I am trying to use bootstrap toggle to create a switch to change between monthly and annual plans. I got the toggle to function in the sense it moves and looks right but I can not get the JS part to work. So it will only show the monthly div right now and will not switch to the annual div. Currently this is what I have

Toggle

<div class="container">
   <div class="row">
     <div class="col-md-5"></div>
     <div class="col-md-4 selectCenter">
       <br>
       <input type="checkbox" checked  id="toggle" data-toggle="toggle" data-on="Monthly" data-off="Annual" data-style="ios" data-onstyle="primary" data-offstyle="primary">
     </div>
   </div>

Monthly div

<section class="se-section" id="monthly">
    <div class="container">
      <div class="row">
       <div class="col-md-4 col-sm-6">
         <h1>Monthly</h1>
       </div> <!-- end col-md-4 -->
      </div> <!-- end row -->
    </div> <!-- end container -->
  </section>

Annual div

<section class="se-section" id="annual">
    <div class="container">
      <div class="row">
       <div class="col-md-4 col-sm-6">
         <h1>Annual</h1>
       </div> <!-- end col-md-4 -->
      </div> <!-- end row -->
    </div> <!-- end container -->
  </section>

Then my javascript

var toggle = document.getElementById("toggle");
var monthly = document.getElementById("monthly");
var annual = document.getElementById("annual");

if(toggle.checked){
  monthly.style.display = 'block';
  annual.style.display = 'none';
}
if(!toggle.checked){
  monthly.style.display = 'none';
  annual.style.display = 'block';
}

Solution

  • You need to understand a very basic concept in JavaScript, which is doing stuff when something else happens. In technical terms, binding to an event. You bind execution of some code (usually wrapped up in a function) every time some event happens:

    target.addEventListener(type, listener[, options]);
    
    • type is the event itself (its name)
    • listener is the name of the function to be executed (you can have an anonymous function instead of a name, but it's better to keep it tidy and just put your code inside a named function
    • options are:
      • capture: A Boolean indicating that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.
      • once: A Boolean indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.
      • passive: A Boolean indicating that the listener will never call preventDefault(). If it does, the user agent should ignore it and generate a console warning. See Improving scrolling performance with passive listeners to learn more.
      • mozSystemGroup: A Boolean indicating that the listener should be added to the system group. Available only in code running in XBL or in Firefox's chrome.

    options is optional

    Now, back to your example:

    var toggle = document.getElementById("toggle"),
        monthly = document.getElementById("monthly"),
        annual = document.getElementById("annual");
    
    // define functionality: 
    function toggleDivs() {
       monthly.style.display = toggle.checked ? 'block' : 'none';
       annual.style.display = toggle.checked? 'none' : 'block';
    }
    
    // bind to `change` on toggle:
    toggle.addEventListener('change', toggleDivs, {passive:true});
    
    // bind to `window.onload` (so it runs once when the page is loaded):
    window.onload = toggleDivs;
    

    That's about it. Please note binding a function like this on window.onload is not exactly best practice (it can override another bind on it or can be overridden by a subsequent similar function). Read this for details.


    Alternatively, since you're using Bootstrap, it means you're also using jQuery, which enables a more concise syntax:

    // define the function: 
    function toggleDivs() {
      $('#monthly').css('display', $('#toggle').prop('checked') ?
        'block':'none');
      $('#weekly').css('display', $('#toggle').prop('checked') ?
        'none':'block');    
    }
    // bind to `change` on `#toggle` : 
    $('#toggle').on('change', toggleDivs);
    
    // bind to `load` on `window` :
    $(window).on('load', toggleDivs);