42

I have read all related questions regarding my question and have tried them all to no avail. I can't seem to make my code work, even though I "think" almost every code I wrote was the same with the solutions posted on this site.

Here's the HTML Code:

<div class="press-title">
  <p class="text" data-toggle="collapse" data-target="#serviceList">
    <span id="servicesButton" data-toggle="tooltip " data-original-title="Click Me!">
      <span class="servicedrop glyphicon glyphicon-chevron-down"></span> Services Offered <span class="servicedrop glyphicon glyphicon-chevron-down"></span>
    </span>
  </p>
</div>
<div id="serviceList" class="collapse">
  <div class="row featurette">
  ...

Here's the JQuery

$('#serviceList').on('shown.bs.collapse'), function() {
    $(".servicedrop").addClass('glyphicon-chevron-up').removeClass('glyphicon-chevron-down');
  }

$('#serviceList').on('hidden.bs.collapse'), function() {
    $(".servicedrop").addClass('glyphicon-chevron-down').removeClass('glyphicon-chevron-up');
  }

I just want to change the icon from down to up, upon collapsing the element. Then toggle back when the same class is clicked. I'm really stuck with this one. Thank you in advance!

Anshad Vattapoyil
  • 23,145
  • 18
  • 84
  • 132
Dominic
  • 928
  • 3
  • 9
  • 19

12 Answers12

153

Pure CSS.

HTML part:

   <a data-toggle="collapse" href="#collapseExample" 
      aria-expanded="false" aria-controls="collapseExample">
        Open/Close collapse
        <i class="fa fa-chevron-right pull-right"></i>
        <i class="fa fa-chevron-down pull-right"></i>
    </a>

The key element here is aria-expanded="false" or "true"

CSS:

a[aria-expanded=true] .fa-chevron-right {
   display: none;
}
a[aria-expanded=false] .fa-chevron-down {
   display: none;
}
Roshaw
  • 1,641
  • 2
  • 10
  • 4
26

The problem is with your jQuery code not being correct.

You're closing the event handler function early on this line:

$('#serviceList').on('shown.bs.collapse'), function() {

See that second closing parenthesis? That's closing the 'on' function early. Try changing your jQuery to look like this:

$('#serviceList').on('shown.bs.collapse', function() {
    $(".servicedrop").addClass('glyphicon-chevron-up').removeClass('glyphicon-chevron-down');
  });

$('#serviceList').on('hidden.bs.collapse', function() {
    $(".servicedrop").addClass('glyphicon-chevron-down').removeClass('glyphicon-chevron-up');
  });
Shaun Wilson
  • 8,727
  • 3
  • 50
  • 48
royse41
  • 2,310
  • 4
  • 22
  • 29
  • It worked! Thank you very much! I'm not that used to JQuery yet hence the amateur mistake. Thank you for your time! :) – Dominic Sep 26 '13 at 09:41
  • 1
    See the pure CSS solutions here: https://stackoverflow.com/a/33496943/5551593 – Andrew Jun 18 '20 at 16:36
25

Try this more elegant solution:

$('#serviceList').click(function(){
    $(this).find('.servicedrop').toggleClass('icon-chevron-down icon-chevron-up');
});
12

Similar to Bojan's answer, I use this solution.
Change HTML code like this:

<span class="chevron_toggleable glyphicon glyphicon-chevron-down"></span>

It's better to use .on event with respect to .click. Also by using class selector it can be used as a site wide solution.

$('.chevron_toggleable').on('click', function() {
    $(this).toggleClass('glyphicon-chevron-down glyphicon-chevron-up');
});
trante
  • 33,518
  • 47
  • 192
  • 272
  • hello it is worked but instead of icon I see ? icon do you know why – Sasha May 13 '15 at 04:18
  • I wanted the user to be able to click the entire panel header to expand / collapse, so I used your example but put the click event on the div that contains the panel header. +1 - thanks for a good example. – Jim Dec 23 '15 at 07:53
  • I like this example, but for some reason it misses clicks (so it will expand but not change icon). there are no errors, I am not just what is causing the issue. – Travis Tubbs Nov 21 '16 at 15:54
12

Pure CSS, with even less code + animation.

HTML part:

   <a data-toggle="collapse" href="#collapseExample" 
      aria-expanded="false" aria-controls="collapseExample">
        Open/Close collapse
        <i class="fa fa-chevron-right pull-right"></i>
    </a>

CSS:

a[aria-expanded=true] .fa-chevron-right {
 transition: .3s transform ease-in-out;
 transform: rotate(90deg);
}
Paul Dasil
  • 121
  • 1
  • 2
  • 1
    Nice! Thanks for sharing. My adjustments: start with `aria-expanded=true`, `chevron-down` and then do `rotate(180deg)` so I get it pointing down with no content. – Steve Greene Feb 08 '20 at 21:13
  • Nice and easy implementation! – Travis Sep 15 '21 at 14:27
  • Good to add that if we want chevron go back we copy same style and change `aria-expanded=false` and `rotate(0deg)`. That way it will smoothly go back to it's initial position. – jean d'arme Jan 12 '23 at 16:37
6

I'd like to offer an option along the same lines as another solution posted here, but uses a single div with transforms. This would also help make clean use of transitions to animate the icons as well.

a[aria-expanded=true] .fa-chevron-right {
   transform: rotate(0deg);
}

a[aria-expanded=false] .fa-chevron-right {
   transform: rotate(90deg); // or whatever direction you need
}
d219
  • 2,707
  • 5
  • 31
  • 36
mbuchok
  • 391
  • 6
  • 18
2

you can try this.

Here's the HTML Code:

<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="false" aria-controls="collapseOne"> Collapsible Group Item #1<span class="glyphicon glyphicon-chevron-up"></span> </a>

Here's the JQuery

$('#accordion').on('shown.bs.collapse hidden.bs.collapse', function (e) {
         $(e.target).prev('.panel-heading').find("span.glyphicon").toggleClass('glyphicon-chevron-up glyphicon-chevron-down',200, "easeOutSine" );
});
gsamaras
  • 71,951
  • 46
  • 188
  • 305
Red Web
  • 37
  • 2
2

The simplest answer I could find and thought it would be useful to add here for others.

Essentially this involved this bit of css

/* Rotating glyphicon when expanding/collapsing */
.collapse-chevron .glyphicon {
  transition: .3s transform ease-in-out;
}
.collapse-chevron .collapsed .glyphicon {
  transform: rotate(-90deg);
}

which applied to this bit of html

<div class="collapse-chevron">
  <a data-toggle="collapse" class="collapsed" href="#collapseFilter">
     <span class="glyphicon glyphicon-chevron-down" aria-hidden="true"></span>
     <strong>link to toggle</strong>
  </a>
  <div class="collapse" id="collapseFilter">
    <p>Some content I want collapsed or expanded</p>
  </div>
</div>

Codepen of this code: https://codepen.io/anon/pen/PKxzVa

Source: this article

See the codepen from the article for some more examples: https://codepen.io/disjfa/pen/EZdMpe

Inti
  • 3,443
  • 1
  • 29
  • 34
  • Nice, but buggy with BS 3 (it doesn't render the chevron-down on page load) (confirmed with codepen edit). – cowbert Aug 25 '17 at 16:54
  • @cowbert You need to make sure that you add the correct classes to the starting html. In my example it starts collapsed so you need to have `class="collapsed"` as I do ^^ – Inti Aug 29 '17 at 14:27
  • 1
    got it to work, thanks! I was using the css aria-expanded attribute match hide chevron trick earlier. – cowbert Aug 29 '17 at 17:49
  • Great - this one even has a bonus little animation between states ;) – Inti Aug 29 '17 at 20:23
1

fixed the issue changing HTML/CSS

HTML:

<a data-toggle="collapse" href="#doc" class="yt-toggle collapsed">View Doc 
    <i class="fa fa-caret-right fa-fw"></i> 
    <i class="fa fa-caret-down fa-fw"></i>
</a>

CSS:

.yt-toggle.collapsed .fa-caret-down {
  display: none;
}

.yt-toggle.collapsed .fa-caret-right {
  display: inline-block;
}

.yt-toggle .fa-caret-right {
  display: none;
}
Mukesh
  • 858
  • 1
  • 10
  • 21
1
<div id="accordion">
  <div class="card">
    <div class="card-header" id="headingOne">
      <h5 class="mb-0">
        <button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
          Collapsible Group Item #1
        </button>
      </h5>
    </div>

    <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>
  <div class="card">
    <div class="card-header" id="headingTwo">
      <h5 class="mb-0">
        <button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
          Collapsible Group Item #2
        </button>
      </h5>
    </div>
    <div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>
  <div class="card">
    <div class="card-header" id="headingThree">
      <h5 class="mb-0">
        <button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
          Collapsible Group Item #3
        </button>
      </h5>
    </div>
    <div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>
</div>


<script>    

$('.card-header').click(function(){
        $cur = $(this);
        setTimeout(function(){ 
            $('.far').removeClass("fa-minus-square").addClass("fa-plus-square");
            if($cur.next().hasClass("show")) {
                //console.log('show');
                $cur.find('.far').removeClass("fa-plus-square").addClass("fa-minus-square");
            } else {
                //console.log('no show');
                $cur.find('.far').removeClass("fa-minus-square").addClass("fa-plus-square");
            }
        }, 500);


    });
    </script>
Sonu Nagar
  • 124
  • 5
0

if you use angularjs you can try this.

.html

<button ng-click="enlarge(x.ID)" class="{{fullglyphon[x.ID]}}" ng-init="fullglyphon[x.ID] = 'btn btn-xs btn-primary glyphicon glyphicon-resize-full'"></button>

.js

    $scope.enlarge = function(myID) { 
                $scope.fullglyphon[myID] = "btn btn-xs btn-primary glyphicon glyphicon-resize-small";
}

toggle last one or do if comparison

if ( $scope.fullglyphon[myID] == "btn btn-xs btn-primary glyphicon glyphicon-resize-small" ) {
                    $scope.fullglyphon[myID] = "btn btn-xs btn-primary glyphicon glyphicon-resize-full";
            }else{
                 $scope.fullglyphon[myID] = "btn btn-xs btn-primary glyphicon glyphicon-resize-small";
                }
Tower Jimmy
  • 567
  • 1
  • 4
  • 15
0

For change collapse icon in Bootstrap 4 with minimal html change, I've done

  • Add to css:

    a[data-toggle="collapse"]:after {
        font-family: 'Glyphicons Halflings';
        content: "\e114";
        float: right;
        color: #4285F4;
    }
    a[data-toggle="collapse"].collapsed:after {
        content: "\e080";
    }
    @font-face {
        font-family: 'Glyphicons Halflings';
        src: url('../fonts/glyphicons-halflings-regular.eot');
        src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
        url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'),
        url('../fonts/glyphicons-halflings-regular.woff') format('woff'),
        url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),
        url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
    }
    
  • Put fonts in proper place, related to css:

    \css\style.css
    \fonts\glyphicons-halflings-regular.eot
    \fonts\glyphicons-halflings-regular.svg
    \fonts\glyphicons-halflings-regular.ttf
    \fonts\glyphicons-halflings-regular.woff
    \fonts\glyphicons-halflings-regular.woff2
    
  • And add class="collapsed" to all collapsed (by default) links:

    <a href="#info" data-toggle="collapse" class="collapsed">Collapsed link</a>
    <div id="info" class="collapse">
    
Grigory Kislin
  • 16,647
  • 10
  • 125
  • 197