skip to Main Content

I have accordion buttons that I need to change based on accordion state (show, hide). I can do it no problem with click event but I would like to bind it to the state of the accordion

I tried adding an event handler to the accordion function I have written but I must be doing it incorrectly

var accordionBtn = $('.accordion-btn');
var bedAccordion = $('.accordion');

$(document).ready(function() {
  $(bedAccordion).on('show.bs.collapse', function() {
    $(this).find('i').removeClass('fa-plus');
    $(this).find('i').addClass('fa-minus');
    $('.collapse').collapse('hide');
  });

  $(bedAccordion).on('hide.bs.collapse', function() {
    $(this).find('i').removeClass('fa-minus');
    $(this).find('i').addClass('fa-plus');
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>

<div class="accordion">
  <button class="btn accordion-btn button--arrow-right" type="button" data-toggle="collapse" data-target="#bedAccordion1" aria-expanded="false" aria-controls="bedAccordion1"><i class="fas fa-plus"></i></button>
  <span class="title-3">Test</span>
  <div class="col collapse-content">
    <div class="collapse multi-collapse" id="bedAccordion1">
      <div class="border--left">
        <p><b>Test</b><sup>1</sup><br> Test
        </p>
        <p>test<br> test
        </p>
        <p><b>test</b><sup>1</sup><br> Test</p>
      </div>
    </div>
  </div>
</div>

I’d like to bind this event below to the above function so the changes happen on show and hide collapse

    $(accordionBtn).click(function () {
        $(this).toggleClass('accordion-btn--open');
        $(this).toggleClass('button--arrow-right');
    });
});

bind the button toggle class to the state of the accordion and functions above

2

Answers


  1. You need to call the toggleButton with call method to set the this value.

    More on Javascript call() & apply() vs bind()

    var accordionBtn = $('.accordion-btn');
    var bedAccordion = $('.accordion');
    
    $(document).ready(function() {
      $(bedAccordion).on('show.bs.collapse', function(e) {
        toggleButton.call(this);
        $(this).find('.collapse').collapse('hide');
      });
    
      $(bedAccordion).on('hide.bs.collapse', function() {
        toggleButton.call(this);
      });
    });
    
    function toggleButton() {
      $(this).find('i').toggleClass('fa-plus').toggleClass('fa-minus');
      $(this).find('button').toggleClass('active');
    }
    button.active {
      background: red;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
    
    <div class="accordion">
      <button class="btn accordion-btn button--arrow-right" type="button" data-toggle="collapse" data-target="#bedAccordion1" aria-expanded="false" aria-controls="bedAccordion1"><i class="fas fa-plus"></i></button>
      <span class="title-3">Test 1</span>
      <div class="col collapse-content">
        <div class="collapse multi-collapse" id="bedAccordion1">
          <div class="border--left">
            <p><b>Test</b><sup>1</sup><br> Test
            </p>
            <p>test<br> test
            </p>
            <p><b>test</b><sup>1</sup><br> Test</p>
          </div>
        </div>
      </div>
    </div>
    
    <div class="accordion">
      <button class="btn accordion-btn button--arrow-right" type="button" data-toggle="collapse" data-target="#bedAccordion2" aria-expanded="false" aria-controls="bedAccordion2"><i class="fas fa-plus"></i></button>
      <span class="title-3">Test 2</span>
      <div class="col collapse-content">
        <div class="collapse multi-collapse" id="bedAccordion2">
          <div class="border--left">
            <p><b>Test</b><sup>1</sup><br> Test
            </p>
            <p>test<br> test
            </p>
            <p><b>test</b><sup>1</sup><br> Test</p>
          </div>
        </div>
      </div>
    </div>
    Login or Signup to reply.
  2. In order to have just one accordion open at a time, you can use the parent attribute provided by bootstrap, you just need to provide a wrapper element for your accordions. This also allows to have multiple accordion groups so you can have one accordion active per group.

    To change the icons, just define a function and pass it as the callback for the event, jQuery will take care of binding this to the current element.

    var accordionBtn = $('.accordion-btn');
    var bedAccordion = $('.accordion');
    
    function toggleButton() {
      $(this).find('i').toggleClass('fa-plus').toggleClass('fa-minus');
    }
    
    $(document).ready(function() {
      bedAccordion.on('show.bs.collapse', toggleButton)
        .on('hide.bs.collapse', toggleButton);
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
    
    <!-- Add wrapper element -->
    <div id="accordion-container">
      <div class="accordion">
        <button class="btn accordion-btn button--arrow-right" type="button" data-toggle="collapse" data-target="#bedAccordion1" aria-expanded="false" aria-controls="bedAccordion1"><i class="fas fa-plus"></i></button>
        <span class="title-3">Test</span>
        <div class="col collapse-content">
          <div class="collapse multi-collapse" id="bedAccordion1" data-parent="#accordion-container">
            <div class="border--left">
              <p><b>Test</b><br>Test</p>
              <p><b>test</b><sup>1</sup><br> Test</p>
            </div>
          </div>
        </div>
      </div>
      <div class="accordion">
        <button class="btn accordion-btn button--arrow-right" type="button" data-toggle="collapse" data-target="#bedAccordion2" data-parent="#accordion-container" aria-expanded="false" aria-controls="bedAccordion1"><i class="fas fa-plus"></i></button>
        <span class="title-3">Test</span>
        <div class="col collapse-content">
          <!-- Add the data-parent to indicate which group this accordion belongs to -->
          <div class="collapse multi-collapse" id="bedAccordion2" data-parent="#accordion-container">
            <div class="border--left">
              <p><b>Test</b><br> Test</p>
              <p><b>test</b><sup>2</sup><br> Test</p>
            </div>
          </div>
        </div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search