Structure Expansion For tables and divs using jQuery

Posted on Tuesday March 20, 2012 / by Yelvy Buitrago

In the last few years industry has frowned upon using tables. After all in the beginning of web development we didn't have the luxury of these great browser tools and wonderful CSS. So most UI design was merged right into the structure of the page. But tables still hold an important role in our UI world. The key note to consider is if your design is completely data driven then it might be beneficial to use tables.

This article is dedicated to show how jQuery can give you the ability to use a table structure and expand its sibling rows. This example shows you the power behind the ability to climb the DOM structure to get your target.

The slideDown() and slideUp() methods are the same you would use in any div manipulation. What we try to illustrate here is the ability to catch the users radio click and travel up the DOM to access the next row.

This code illustrates the row slidedown/slideup magic.

jQuery Snippet of Code

$('.col-input input').change(function() {
  if($(this).attr('checked')) {
    $(this).parent().parent().next().children(":first").slideDown("fast");			
    return;
  }
  $(this).parent().parent().next().children(":first").slideUp("fast"); 
});

HTML Snippet of a table row.

<tr>		     
<td class="col-input"><input type="checkbox" ></td>
<td class="col-qty" >020</td>
</tr>

CSS

body { background: #fff; font: normal normal 12px verdana,sans-serif;  color:#000 }

/* Tabular Data Section */
#tableSection { clear: both; width: 70%; padding-top: 20px }
.col-input { width: 25px;}
.col-qty  { width: 60px;}
#studentTbl { background-color: #D3D3D3; border:1px solid #D3D3D3; border-collapse:collapse }
#studentTbl th, #studentTbl td {border:1px solid #C4C4C4; padding: 4px; font-weight: bold; text-align: center; } 
#studentTbl th { background-color: #DB8A39; color: #fff;}
.row-drops .fields { float: left; padding: 10px 15px; width: 100% }
.row-drops .fields label { display: block; margin-left: 2px }

/* expanded light brown table row. */
.exp-row {display: none;} 
.col-qty, .col-qty { background-color: #d9ecfd !important }
.hdr .col-qty { background-color: #0b72d1 !important }

/* jquery alternating color rows */
#studentTbl tr.r1 { background-color: #E1E1E1 }
#studentTbl tr.r2 { background-color: #FCEFE3 }
#studentTbl tr.r3 { background-color: #fff;}
#studentTbl tr.r4 { background-color: #FCEFE3 }

.childinfobox {width: 140px; float: left; font-weight: normal; text-align: left; border:1px solid #C4C4C4; padding: 5px; margin-right: 10px;}
.childpic {width: 100px; float: right; border:1px solid #C4C4C4; padding: 5px; margin-right: 40px;}
.childinfobox label {display: block; font-weight: bold; color: #0b72d1; margin-bottom: 5px; }
.childinfobox ul{list-style:none} 
.childinfobox .crit label {display: inline; font-weight: normal; color: #000;}
.childinfobox .crit span {text-align: right; color: #00A82C; font-weight: bold; }
.flrt {float: right;}

/*style for the article */
.boldme {font-weight: bold;}
.redbold {color:#F90E0E; font-weight: bold; }
#articleSection h3 { color: #1509F4; font-weight: bold; }
#domsection {margin-left: 20px;}

Javascript

$(window).unload( function () {
  $('.col-input input').attr('checked', false); } 
);
$(document).ready(function() {
  var classNames = { 0: 'r1', 1: 'r2', 2: 'r3', 3: 'r4'};
  $('table.striped tbody tr').not('[th]').each(function(index) {
    $(this).addClass(classNames[index % 4]);
  });
  $('.col-input input').change(function() {
    if($(this).attr('checked')) {
      $(this).parent().parent().next().children(":first").slideDown("fast");			
      return;
    }
    $(this).parent().parent().next().children(":first").slideUp("fast"); 
  });
});

HTML

<div id="tableSection">
  <table id="studentTbl" cellpadding="0" celllspacing="0" width="100%" class="striped">
    <thead>	 
    <tr class="hdr">
      <th></th>
      <th class="col-qty">Student ID</th>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Teacher's Name</th>
      <th>Grade</th>
      <th>Parent/Guardian</th>	
      <th>Contact Number</th>
    </tr>
    </thead>
    <tbody>
    <tr>
      <td class="col-input"><input type="checkbox"></td>
      <td class="col-qty">020</td>
      <td>Lucy</td>
      <td>Stewart</td>
      <td>Mrs. Familia</td>
      <td>K</td>
      <td>Suzzy Stewart</td>
      <td>999-898-9090</td>
    </tr>
    <tr>
      <td colspan="8" class="row-drops exp-row">
        <div class="fields"> 
        <div class="childinfobox">
          <label>Personality Criteria</label> 
          Lucy is a quiet little girl.  Loves group activities and tends to be shy in large groups.
          Skills she excels at are mostly spelling and reading. 
        </div>	
        <div class="childinfobox">
          <label>Academic Grades</label> 
          <ul class="crit">
            <li><label>Reading<label><span>A</span></li>
            <li><label>Math<label><span>B</span></li>
            <li><label>Sciene<label><span>A</span></li>
            <li><label>History<label><span>A</span></li>
          </ul>
        </div>
        </div>	
      </td>
    </tr>
    <tr>
      <td class="col-input"><input type="checkbox"></td>
      <td class="col-qty">031</td>
      <td>Johnny</td>
      <td>Flerall</td>
      <td>Mrs. Rosental</td>
      <td>1st</td>
      <td>Grace Flerall</td>
      <td>999-598-5590</td>
    </tr>
    <tr>
      <td colspan="8" class="row-drops exp-row">
        Johnny's content would go here	  
      </td>
    </tr>
    <tr>
      <td class="col-input"><input type="checkbox"></td>
      <td class="col-qty">121</td>
      <td>Mirtha</td>
      <td>Sacon</td>
      <td>Mrs. Moore</td>
      <td>3rd</td>
      <td>Gloria Sacon</td>
      <td>999-598-1120</td>
    </tr>	
    <tr>
      <td colspan="8" class="row-drops exp-row">Mirtha's content would go here</td>
    </tr>
    </tbody>
  </table>
</div>

Using this code:

$(this).parent().parent().next().children(":first").slideUp("fast");

$(this) -- is the input field

.parent -- moves up and detects the td the input is in.

.parent -- moves up from the td to its parent to the tr.

.next -- now that you have made it to the tr level calling the next() method tells your code to find the tr's sibling the next tr.

.children(":first") -- once you have made it to the sibling tr you grab its first child.

.slideDown("fast") -- And last tell it to slide that child the td down.

This gives you the dynamic ability to capture any radio click and drop the next row that was checked.