Thomas Williams Thomas Williams - 3 months ago 9
jQuery Question

Get body table rows, but not table head

I have a table which has correct thead and tbody.I am grabbing all the table rows in a table, to process them, but unfortunately it is grabbing the header as well. Here is my code:

var base=$(this),$rowCells;
base.find('tr').each(function(){
//get body text
$rowCells=$(this).children();
var $bodyText=$rowCells.map(function() {
return $(this).text();
}).get();
})


Ok Here is what I have tried

base.find('tbody tr').each(function())


but this goes a little crazy goes into an everlasting loop and dies in a big way.
Also tried

base.find('tbody > tr').each(function())


but again this does not work and basically crashes my browser as before.
This code isn't the only code btw but the important looping part. This is just a small part of a jquery plugin I am writing.

Just want to know how I can target the tbody instead of the thead.

I have been requested to post more code. This is my full jquery plugin. What it does is that it creates a new column and takes all the rows and puts them in the first column and hides all the other rows so that it can be viewed on a mobile phone. The plugin is working perfectly but I need to add something to it, and unfortunately the plugin is grabbing header rows where it shouldn't on the line I have marked.



$(document).ready(function(){
$('#mytable1').tSquash({'pixels':'350','titleColumn':'headings w4','textColumn':'redtext'});
$('#mytable2').tSquash({'pixels':'600','titleColumn':'headings w5'});
});


// tSquash V1.0.0
;(function($) {
"use strict";
$.fn.tSquash = function(options,callback) {
var settings =$.extend(true, {},{
'pixels':480,
'titleColumn':"",
'textColumn':"",
},options);

var base=$(this),$rowCells;


base.resize=function()
{
$(window).resize(function(){
base.change();
});
}
base.change=function()
{
if($(window).width() < settings.pixels ){
base.minify();
}
else
{
base.enlarge();
}
}
base.minify=function()
{
if(base.find('th').eq(0).attr('class')!="tSquash")
{
var tablename = '#'+$.trim(base.attr('id'));
// Count columns
var columnCount = $(tablename+' thead th').length;
// get table head text into array $myheadertext
var $headCells = $(base).find('thead tr:first').children();
var $myheadertext = $headCells.map(function() {
return $(this).text();
}).get();

//This adds a column and gives it the class of tSquash
base.find('tr').each(function(){//This is supposed to only get body tr but it is getting header tr too
//get body text
$rowCells=$(this).children();
var $bodyText=$rowCells.map(function() {
return $(this).text();
}).get();

$(this).find('td').eq(0).before('<td></td>');
$(this).find('th').eq(0).before('<th></th>');
$(this).find('td').eq(0).addClass("tSquash");
$(this).find('th').eq(0).addClass("tSquash");

for(var i=0;i<columnCount;i++)
{
//Add text to first column
$(this).find('td').eq(0).append('<span class="'+settings.titleColumn+'">'+$myheadertext[i]+': </span><span class="'+settings.textColumn+'">'+$bodyText[i]+'</span></br>');
$(this).find('td').eq(i+1).hide();
$(this).find('th').eq(i+1).hide();
}

})


}
}
base.enlarge=function()
{
$('.tSquash').remove();
base.find('td').show(),base.find('th').show();
}
base.change();
base.resize();
return base;

}

})(jQuery);

tbody{
border: 1px solid #000;

}
tbody td{
border: 1px solid #000;
padding:10px;
}

#mytable2{
100%;
}

.headings{
font-weight: bolder;
display:inline-block;
}
.redtext
{
color:red;
}


.w4
{
width: 4em;
}
.w5
{
width: 5em;
}

<!doctype html>
<html>
<head>
<title>Test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1">

<link rel="stylesheet" type="text/css" href="test.css">
</head>

<body>
<table id="mytable1" style="width:100%">
<thead>
<tr>
<th>The</th>
<th>First</th>
<th>Stage</th>
<th>Is</th>
<th>The</th>
<th>Hardest</th>
</tr>
</thead>
<tbody>
<tr id="t_1"><td>To</td><td>be</td><td>or</td><td>not</td><td>to</td><td>be</td></tr>
<tr id="t_2"><td>This</td><td>I</td><td>Believe</td><td>is</td><td>the</td><td>last</td></tr>
<tr id="t_3"><td>The</td><td>First</td><td>Stage</td><td>is</td><td>the</td><td>hardest</td></tr>
<tr id="t_4"><td>The</td><td>First</td><td>Stage</td><td>is</td><td>the</td><td>hardest</td></tr>
<tr id="t_5"><td>The</td><td>First</td><td>Stage</td><td>is</td><td>the</td><td>hardest</td></tr>
<tr id="t_6"><td>The</td><td>First</td><td>Stage</td><td>is</td><td>the</td><td>hardest</td></tr>
</tbody>
</table>
<div id="test"></div>
<script type="text/javascript" src="jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="test.js"></script>
</body>

<body>
<table id="mytable2" style="width:100%">
<thead>
<tr>
<th>I</th>
<th>Am</th>
<th>An</th>
<th>Elephant</th>
<th>Man</th>
<th>Today</th>
</tr>
</thead>
<tbody>
<tr><td>To</td><td>be</td><td>or</td><td>not</td><td>to</td><td>be</td></tr>
<tr><td>This</td><td>I</td><td>Believe</td><td>is</td><td>the</td><td>last</td></tr>
<tr><td>The</td><td>First</td><td>Stage</td><td>is</td><td>the</td><td>hardest</td></tr>
<tr><td>The</td><td>First</td><td>Stage</td><td>is</td><td>the</td><td>hardest</td></tr>
<tr><td>The</td><td>First</td><td>Stage</td><td>is</td><td>the</td><td>hardest</td></tr>
<tr><td>The</td><td>First</td><td>Stage</td><td>is</td><td>the</td><td>hardest</td></tr>
</tbody>
</table>
<div id="test"></div>
<script type="text/javascript" src="jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="test.js"></script>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</html>




Answer

Simply access tbody it's the correct way to do it.

base.find('tbody tr').each(function(){   

(P.S: even if you didn't specifically used the <tbody> element, it's added by default by the browser.)

var $table = $("table"); // Or as you use it: $(this) Supposingly a table...

$table.find('tbody tr').each(function() {    
  
  var $rowCells = $(this).find("td"); // TDs of the current iterating TR
  var bodyText = $rowCells.map(function() { // Array to hold all TD text
    return $(this).text();
  }).get();
  
  // HERE Do something with `bodyText` Array,
  // otherwise will got substituted with new values
  // in the second TR iteration
  console.log( bodyText );
  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <thead>
    <tr>
      <td colspan="4">Head</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>TR1 Cell 1</td>
      <td>TR1 Cell 2</td>
      <td>TR1 Cell 3</td>
      <td>TR1 Cell 4</td>
    </tr>
    <tr>
      <td>TR2 Cell 1</td>
      <td>TR2 Cell 2</td>
      <td>TR2 Cell 3</td>
      <td>TR2 Cell 4</td>
    </tr>
  </tbody>
</table>

If you are entering an infinite loop that's most probabily due to some other issues in your plugin.