2

I currently have a problem with the slideToggle() jQuery effect on a table row with a nested table.

I have the following HTML markup:

<table>
  <tbody>
    <tr>
      <th>One</th>
      <th>Two</th>
      <th>Three</th>
    </tr>
    <tr class="show-details">
      <td>Item1</td>
      <td>Item2</td>
      <td>Item3</td>
    </tr>
    <tr class="details">
      <td colspan="3">
        <table>
          <tbody>
            <tr>
              <td>Lorem Ipsum</td>
              <td>Ipsum Lorem</td>
            </tr>
          </tbody>
        </table>
      </td>
    </tr>
    <tr class="show-details">
      <td>Item1</td>
      <td>Item2</td>
      <td>Item3</td>
    </tr>
    <tr class="details">
      <td colspan="3">
        <table>
          <tbody>
            <tr>
              <td>Lorem Ipsum</td>
              <td>Ipsum Lorem</td>
            </tr>
          </tbody>
        </table>
      </td>
    </tr>
  </tbody>
</table>

I want to hide the detail row right away and show it with the slideToggle() function. I have the following jQuery code:

$(function() {
  $(".details").hide();
  $('.show-details').click(function(e){
    $(this).next(".details").slideToggle(500);
    $("td > span", this).toggleClass('open')
  });
});

The problem is that the row goes from display:none; to display:table-row; which results in a display:none; to display:block; to display:table-row;. The effect then jumps to display block, then animates the height of the row (+ overflow it by a ton, so the next row jumps down for a few secs) and then at last turn into display:table-row; when the animation is over.

Any suggestions to get the effect working with a simple slideToggle to display the .detail row?

I've tried the answers in this question without any luck.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

4 Answers4

4

I think this is an inherent dysfunction with table cells. The solution is to replace them with styled DIVs:

<style type="text/css">
.cell {
    display: inline-block;
    border: 1px solid;
}
.head {
    font-weight: bold;
}
.head .cell, .row .cell {
    width: 50px;
}
.details .cell {
    width: 75px;
}
</style>


<div class="head">
    <div class="cell">One</div>
    <div class="cell">Two</div>
    <div class="cell">Three</div>
</div>
<div class="row show-details">
    <div class="cell">Item1</div>
    <div class="cell">Item2</div>
    <div class="cell">Item3</div>
</div>
<div class="row details">

    <div class="row">
        <div class="cell">Lorem Ipsum</div>
        <div class="cell">Ipsum Lorem</div>
    </div>
</div>    

<div class="row show-details">
    <div class="cell">Item1</div>
    <div class="cell">Item2</div>
    <div class="cell">Item3</div>
</div>
<div class="row details">

    <div class="row">
        <div class="cell">Lorem Ipsum</div>
        <div class="cell">Ipsum Lorem</div>
    </div>

</div>

http://jsfiddle.net/mblase75/mv7Y5/1/

Blazemonger
  • 90,923
  • 26
  • 142
  • 180
  • +1 - I moved to styled divs and never looked back at tables again. – DefyGravity Oct 14 '11 at 20:57
  • 1
    @DefyGravity The current thinking, of course, is that tables have their place, but only for tabular data, not for page layout. In my opinion, if you're using nested tables, then you really shouldn't be using tables at all. – Blazemonger Oct 14 '11 at 20:59
  • Yea, was going for a quick fix before a major overhaul down the road. Guess I just have to get going on the major overhaul right away. – Kenneth Dahlstrøm Oct 14 '11 at 21:33
1

There is actually a way to get the same affect with nested tables - you were on the right track to begin with but your jQuery was wrong. WIth Gravity's jQuery, I was able to simply assign the classes to the respective table row and it all works beautifully.

HTML

<table>
            <thead>
              <tr>
                <th>Month</th>
                <th>From Date</th>
                <th>To Date</th>
                <th>Execution Date</th>
                <th>Status</th>
              </tr>
            </thead>
            <tbody>
         <tr class="row show-details odd">
                <td>4-APR</td>
                <td>TExt</td>
                <td>&nbsp;</td>
                <td>05/06/2011</td>
                <td>Done</td>
             </tr>
<tr class="row details">
    <td colspan="5">
<table>
        <thead>
         <tr>
          <th>File Name</th>
          <th>Date Created</th>
        </tr>
        </thead>
        <tbody>
        <tr class="odd">
                  <td>Aetna XLS</td>
          <td>05/06/2011</td>
        </tr>
        <tr class="even">
          <td>XLS</td>
          <td>05/06/2011</td>
        </tr>
        <tr class="odd">
          <td>XLS</td>
          <td>05/06/2011</td>
        </tr>
     </tbody>
</table>

CSS

.cell {
    display: inline-block;
}
.head {
    font-weight: bold;
}
.head .cell, .row .cell {
    width: 100%;
}
.details .cell {
    width: 100%;
}

jQuery

<script>   
$(function() {
    $(".details").hide();
    $('.show-details').click(function(e) {
        $(this).next(".details").fadeToggle(500);
//      $("td > span", this).toggleClass('open')
    });
});
</script>

This way, I didn't have to redo all my CSS, table structure or even touch my tables at all. I just assigned the classes to the TR and voila!

Josh Darnell
  • 11,304
  • 9
  • 38
  • 66
alien.ninja
  • 95
  • 2
  • 13
0

If you really want to use TRs because you dont want to rewrite it, add this css, so that when it toggles it goes to "block" instead of "table-row"

tr{
     display:block
};
Daryl H
  • 624
  • 8
  • 8
0

really try to use the styled divs answer. Otherwise, I have had better cross browser consistency with fadeToggle(500) for hiding and displaying table rows across IE. Again, you'll still need to confirm fadeToggle's behavior is acceptable.

$(function() {
//seriously consider styling these as display:hidden on load
  $(".details").hide(); 
  $('.show-details').click(function(e){
    $(this).next(".details").fadeToggle(500);
    $("td > span", this).toggleClass('open')
  });
});
DefyGravity
  • 5,681
  • 5
  • 32
  • 47