David
David

Reputation: 15

Accordion expand collapse icon issue

I'm building an accordion that includes several children and displays an open/close icon on click.

The issue I'm having is with the icons. It's fine when you expand and collapse one at a time, but when you open multiple items the icons start acting oddly and display minuses when they should be pluses.

I've experimented with each and if else statements, but now luck as of yet.

I've also provided a link to my CodePen

$(document).ready(function(){
    $('.pub-accordion-content').hide();
    
    $('#pub-accordion').find('.pub-accordion-toggle').click(function(){

        var $this = $(this);

        //Toggle icon
        $this.toggleClass("open");

        //Expand or collapse this panel
        $this.next().slideToggle('fast')
        
        //Hide the other panels
        $(".pub-accordion-content").not($this.next()).slideUp('fast');
    });
});
#pub-accordion {
    padding: 24px;    
  }
  #pub-accordion h4:first-child {
    border-top: 1px solid #ccc;  
  }
  #pub-accordion h4 {    
    border-bottom: 1px solid #ccc;
    color: #00539f;
    font-size: 1.6em;
    margin: 0;
    padding: 16px 0 16px 33px;
    cursor: pointer;
  }
  #pub-accordion .closed {
    background: url(http://www.dcholloway.co.uk/codepen/primary-collapse-icon.png) no-repeat 0 13px;
  }
  #pub-accordion .open {
    background: url(http://www.dcholloway.co.uk/codepen/primary-expand-icon.png) no-repeat 0 13px;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Size Guide - - - - - - - - - - - - - - - - -->
<div class="row row__im impage--no-margin">
    <div class="page">
      <div class="row">
        <div class="s-100 m1-100 m2-100 l-100">

            <div id="pub-accordion">
                <h4 class="pub-accordion-toggle closed">Boys size guide</h4>
                <div class="pub-accordion-content default">
                    <p>Lorem ipsum dolor sit amet mauris eu turpis.</p>
                </div>
                <h4 class="pub-accordion-toggle closed">Girls size guide</h4>
                <div class="pub-accordion-content">
                    <p>Lorem ipsum dolor sit amet mauris eu turpis.</p>
                </div>
                <h4 class="pub-accordion-toggle closed">Boys plus fit size guide</h4>
                <div class="pub-accordion-content">
                    <p>Vivamus facilisisnibh scelerisque laoreet.</p>
                </div>
                <h4 class="pub-accordion-toggle closed">Girls plus fit size guide</h4>
                <div class="pub-accordion-content">
                    <p>Vivamus facilisisnibh scelerisque laoreet.</p>
                </div>
            </div>  


        </div>
      </div>
    </div>
</div>

Upvotes: 1

Views: 1267

Answers (3)

Paolo Forgia
Paolo Forgia

Reputation: 6748

Adding $('h4').removeClass("open").addClass("closed"); to the click event is one solution. This remove the class open to all the <h4> and add close.

It works also with $(.pub-accordion-toggle).

Edit: I made some corrections because I noticed that there were a problem when you clicked on an opened element.

$(document).ready(function() {
  $('.pub-accordion-content').hide();

  $('#pub-accordion').find('.pub-accordion-toggle').click(function() {

    var $this = $(this);
    var toOpen = $this.hasClass("open");
    $('h4').removeClass("open").addClass("closed");


    //Toggle icon
    if (!toOpen) {
      $this.removeClass("closed").addClass("open");
    }

    //Expand or collapse this panel
    $this.next().slideToggle('fast')

    //Hide the other panels
    $(".pub-accordion-content").not($this.next()).slideUp('fast');
  });
});
#pub-accordion {
  padding: 24px;
}

#pub-accordion h4:first-child {
  border-top: 1px solid #ccc;
}

#pub-accordion h4 {
  border-bottom: 1px solid #ccc;
  color: #00539f;
  font-size: 1.6em;
  margin: 0;
  padding: 16px 0 16px 33px;
  cursor: pointer;
}

#pub-accordion .closed {
  background: url(http://www.dcholloway.co.uk/codepen/primary-collapse-icon.png) no-repeat 0 13px;
}

#pub-accordion .open {
  background: url(http://www.dcholloway.co.uk/codepen/primary-expand-icon.png) no-repeat 0 13px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Size Guide - - - - - - - - - - - - - - - - -->
<div class="row row__im impage--no-margin">
  <div class="page">
    <div class="row">
      <div class="s-100 m1-100 m2-100 l-100">

        <div id="pub-accordion">
          <h4 class="pub-accordion-toggle closed">Boys size guide</h4>
          <div class="pub-accordion-content default">
            <p>Lorem ipsum dolor sit amet mauris eu turpis.</p>
          </div>
          <h4 class="pub-accordion-toggle closed">Girls size guide</h4>
          <div class="pub-accordion-content">
            <p>Lorem ipsum dolor sit amet mauris eu turpis.</p>
          </div>
          <h4 class="pub-accordion-toggle closed">Boys plus fit size guide</h4>
          <div class="pub-accordion-content">
            <p>Vivamus facilisisnibh scelerisque laoreet.</p>
          </div>
          <h4 class="pub-accordion-toggle closed">Girls plus fit size guide</h4>
          <div class="pub-accordion-content">
            <p>Vivamus facilisisnibh scelerisque laoreet.</p>
          </div>
        </div>


      </div>
    </div>
  </div>
</div>

Upvotes: 1

Gerard
Gerard

Reputation: 15786

You closed the panel but didn't replace the icon. I've adjusted the function at the bottom of the jQuery code.

$('.pub-accordion-content').hide();

$('#pub-accordion').find('.pub-accordion-toggle').click(function() {

  var $this = $(this);

  // Replace the icon
  $(".pub-accordion-toggle").removeClass("open");

  //Hide the other panels
  $(".pub-accordion-content").not($this.next()).slideUp('fast');

  //Toggle icon
  $this.toggleClass("open");

  //Expand or collapse this panel
  $this.next().slideToggle('fast')

});
#pub-accordion {
  padding: 24px;
}

#pub-accordion h4:first-child {
  border-top: 1px solid #ccc;
}

#pub-accordion h4 {
  border-bottom: 1px solid #ccc;
  color: #00539f;
  font-size: 1.6em;
  margin: 0;
  padding: 16px 0 16px 33px;
  cursor: pointer;
}

#pub-accordion .closed {
  background: url(http://www.dcholloway.co.uk/codepen/primary-collapse-icon.png) no-repeat 0 13px;
}

#pub-accordion .open {
  background: url(http://www.dcholloway.co.uk/codepen/primary-expand-icon.png) no-repeat 0 13px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row row__im impage--no-margin">
  <div class="page">
    <div class="row">
      <div class="s-100 m1-100 m2-100 l-100">

        <div id="pub-accordion">
          <h4 class="pub-accordion-toggle closed">Boys size guide</h4>
          <div class="pub-accordion-content default">
            <p>Lorem ipsum dolor sit amet mauris eu turpis.</p>
          </div>
          <h4 class="pub-accordion-toggle closed">Girls size guide</h4>
          <div class="pub-accordion-content">
            <p>Lorem ipsum dolor sit amet mauris eu turpis.</p>
          </div>
          <h4 class="pub-accordion-toggle closed">Boys plus fit size guide</h4>
          <div class="pub-accordion-content">
            <p>Vivamus facilisisnibh scelerisque laoreet.</p>
          </div>
          <h4 class="pub-accordion-toggle closed">Girls plus fit size guide</h4>
          <div class="pub-accordion-content">
            <p>Vivamus facilisisnibh scelerisque laoreet.</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Upvotes: 0

Guruprasad J Rao
Guruprasad J Rao

Reputation: 29683

Just add the below line within click event at the beginning.

$(".pub-accordion-toggle").removeClass('open');

So it will look like,

$('#pub-accordion').find('.pub-accordion-toggle').click(function(){
    $(".pub-accordion-toggle").removeClass('open');//this here
    var $this = $(this);

    //Toggle icon
    $this.toggleClass("open");

    //Expand or collapse this panel
    $this.next().slideToggle('fast')

    //Hide the other panels
    $(".pub-accordion-content").not($this.next()).slideUp('fast');
});

You just remove any open class from .pub-accordion-toggle element. That's what it does.

Updated Pen

Upvotes: 1

Related Questions