Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap - Icon toggle with jquery

I got a little problem trying to toggle an icon of Bootstrap. When i run code it does what expected the first time you click on the icon it toggle's, but when i click again it doesn't change. Here its my code and any help will be appreciated!

<a><i class="icon-plus"></i></a>

<script>
  $(".icon-minus").click(function(){
    $(this).removeClass("icon-minus").addClass("icon-plus");
  });
  $(".icon-plus").click(function(){
    $(this).removeClass("icon-plus").addClass("icon-minus");
  });
</script>

Update 1:

This icon is for a collapsible menu and the code of that can be found here :)

like image 970
Jorge Najera T Avatar asked Jul 16 '12 16:07

Jorge Najera T


2 Answers

jsBin demo

$(".icon-minus, .icon-plus").click(function(){
    $(this).toggleClass("icon-minus icon-plus");
});

Or this if you dynamically create your elements:

$("#parent_el_NOT_dyn_gen").on('click','.icon-minus, .icon-plus',function(){
    $(this).toggleClass("icon-minus icon-plus");
});
like image 106
Roko C. Buljan Avatar answered Oct 30 '22 21:10

Roko C. Buljan


The jQuery's selector selects DOM elements then applys the click handler to them. It's not re-evaluating the selector after you change the classes on the element.

You probably want the delegate() / on() method from jQuery to dynamically change the the handler that's fired when the item is clicked. Delegate works with event bubbling and will handle the click and evaluate if the source of the click matches the selector (at the time of the click) as opposed to the .click() which attaches the handler directly, once (at the time of page-load or whenever the code was ran).

Another solution is to change the handler somehow, either by evaluating what class is on the existing element or using toggleClass() which will check for a class then invert it.

$(".icon-minus, .icon-plus").click(function() {
   var $this = $(this);
   if ($this.hasClass("icon-plus")) {
      $this.removeClass("icon-plus").addClass("icon-minus");
      return;
   }
   if ($this.hasClass("icon-minus")) {
      $this.removeClass("icon-minus").addClass("icon-plus");
      return;
   }
});

This method will be slightly faster than using on() / delegate() because it's handled at the root handler and not bubbled & checked afterwards. It's also not susceptible to any breaks in the event bubbling. (ie. event.stopPropagation())

like image 25
Aren Avatar answered Oct 30 '22 22:10

Aren