2

I am trying to toggle a hidden row in table using jquery. In addition, I want to change the state of a glyphicon from plus to minus (and vice versa) when I click on the icon. For some reason, I am having issues with class selector. When I go from plus icon to minus icon, it works fine. However, I cannot go from minus icon to plus icon. jquery click hook is still processing the wrong function.

Here is the jsfiddle http://jsfiddle.net/gs4te89g/

HTML:

<table id="table" class="table table-hover table-striped" style="margin-top: 0px;">
    <thead>
      <tr>
        <th class="detail" rowspan="1"><div class="fht-cell"></div></th>
        <th style="" data-field="id" tabindex="0"><div class="th-inner ">Item ID</div>
          <div class="fht-cell"></div></th>
        <th style="" data-field="name" tabindex="0"><div class="th-inner ">Item Name</div>
          <div class="fht-cell"></div></th>
        <th style="" data-field="price" tabindex="0"><div class="th-inner ">Item Price</div>
          <div class="fht-cell"></div></th>
      </tr>
    </thead>
    <tbody>
      <tr data-index="0">
        <td><a class="detail-icon" href="javascript:"><i class="glyphicon glyphicon-plus icon-plus" id="1"></i></a></td>
        <td style="">0</td>
        <td style="">Item 0</td>
        <td style="">$0</td>
      </tr>
        <tr id="detail-view1" style="background-color:yellow;display: none;">
        <td colspan="4">My Hidden Row</td>
      </tr>
 </tbody>

and javascript:

 $('.glyphicon.glyphicon-plus').on('click', function (e) {
    e.preventDefault();
    $(this).removeClass('glyphicon-plus icon-plus');
    $(this).addClass('glyphicon-minus icon-minus');
    $('#detail-view'+this.id).toggle('slow');
});
$('.glyphicon.glyphicon-minus').on('click', function (e) {
    e.preventDefault();
    $(this).removeClass('glyphicon-minus icon-minus');
    $(this).addClass('glyphicon-plus icon-plus');
    $('#detail-view'+this.id).toggle('slow');
});
hvs
  • 518
  • 1
  • 5
  • 21
  • Think of `$('.glyphicon.glyphicon-minus').on('click', function (e) {})` as two parts: (1) retrieves `$('.glyphicon.glyphicon-minus')` elements, (2) binds click event to them. When the page loads and the script is run, how many `$('.glyphicon.glyphicon-minus')` elements are there? – Stryner Oct 29 '15 at 18:11
  • Just use `toggleClass`. http://jsfiddle.net/g161ppg6/1/ – azium Oct 29 '15 at 18:15
  • The other answers including delegation or class checking are addressing a more complex issue that is unnecessary for you to solve. – azium Oct 29 '15 at 18:17

2 Answers2

1

Yes, you need to use event delegation instead...

Try this...

    $('tr').on('click', '.glyphicon.glyphicon-plus',function (e) {
        e.preventDefault();
        $(this).removeClass('glyphicon-plus icon-plus');
        $(this).addClass('glyphicon-minus icon-minus');
        $('#detail-view'+this.id).toggle('slow');
    });
    $('tr').on('click', '.glyphicon.glyphicon-minus',function (e) {
        e.preventDefault();
        $(this).removeClass('glyphicon-minus icon-minus');
        $(this).addClass('glyphicon-plus icon-plus');
        $('#detail-view'+this.id).toggle('slow');
    });

The reason for this is because you are binding to an element that doesn't exist yet, hence it not working. By delegating the event binding to it's parent, in this I have chosen the tr element, you can bind to elements that are not present yet.

An0nC0d3r
  • 1,275
  • 13
  • 33
0

You can wrap the code into one function and use hasClass instead:

$('.glyphicon').on('click', function (e) {
    e.preventDefault();
    if ($(this).hasClass('glyphicon-plus')){
        $(this).removeClass('glyphicon-plus icon-plus');
        $(this).addClass('glyphicon-minus icon-minus');
        $('#detail-view'+this.id).toggle('slow');
    } else 
    {
        $(this).removeClass('glyphicon-minus icon-minus');
        $(this).addClass('glyphicon-plus icon-plus');
        $('#detail-view'+this.id).toggle('slow');
    }
});

http://jsfiddle.net/gs4te89g/2/

The issue in your code is that you bind to a minus icon when it doesn't exist in the dom.

Dmitry Sadakov
  • 2,128
  • 3
  • 19
  • 34