Search code examples
javascripthtmlcssarrayshtml-table

How can I exclude the headers row from specific functions that hide/show table rows?


I've seen a script that divides table to "pages" in the same page, I was wondering how could I exclude the header row so that it would always show and also that the new tables would have the style of the original full table. Maybe even with an added option to disable the splitting if you don't want it to be split all the time (not necessary). While the page and therefore the table are being created dynamically from another file. I want to add an option for the user to add his own rows, but that's a matter for another time.

http://www.dynamicdrive.com/forums/showthread.php?37116-Divide-table-to-pages

That's the code with added lines as an example:

<tbody id="some_id"><tr id="header" class="header">
<th>head1</th>
<th>head2</th>
<th>head3</th>
</tr>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Paginate Table Script - Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
/* All Styles Optional */
.tdiv {
float: left;
margin-right: 1em;
}
</style>
<script type="text/javascript">

/* Paginate Table Script ©2008 John Davenport Scheuer
   as first seen in http://www.dynamicdrive.com/forums/
   username: jscheuer1 - This Notice Must Remain for Legal Use
   */

// you can init as many tables as you like in here by id: paginateTable('id', 0, num_max_rows);
paginateTable.init = function(){ // remove any not used
paginateTable('test1', 0, 4);
paginateTable('test2', 0, 3);
};

////////////////////// Stop Editing //////////////////////

function paginateTable(table, way, max){
max? paginateTable.max[table] = max : max = paginateTable.max[table];
way = way == 1? 1 : way == -1? 0 : -1;
var r = document.getElementById(table).rows, i = 0;
for(i; i < r.length; ++i) // find current start point
 if(r[i].style.display != 'none')
  break;
for(i; i < r.length; ++i){ // continue on to find current end point
 if(r[i].style.display == 'none'){
  paginateTable.endPoint[table] = i;
  break;
 };
 paginateTable.endPoint[table] = 0; // if no end point found, table is 'virgin' or at end
};
if(way == 1 && r[r.length - 1].style.display != 'none') return; // table was already at the end and we tried to move forward
// if moving forward, start will be old end, else start will be old start - max or 0, whichever is greater:
paginateTable.startPoint[table] = way? paginateTable.endPoint[table] : Math.max( 0, paginateTable.startPoint[table] - max);
paginateTable.endPoint[table] = paginateTable.startPoint[table] + --max; // new end will be new start + max - 1
for (i = r.length - 1; i > -1; --i) // set display of rows based upon whether or not they are in range of the calculated start/end points
 r[i].style.display = i < paginateTable.startPoint[table] || i > paginateTable.endPoint[table]? 'none' : '';
};

paginateTable.startPoint = {};
paginateTable.endPoint = {};
paginateTable.max = {};

if(window.addEventListener)
window.addEventListener('load', paginateTable.init, false);
else if (window.attachEvent)
window.attachEvent('onload', paginateTable.init);

//////////////// End Paginate Table Script ///////////////

</script>
</head>
<body>
<div class="tdiv">
<input type="button" value="Next" onclick="paginateTable('test1', 1);">
<input type="button" value="Previous" onclick="paginateTable('test1', -1);">
<table id="test1">
<tbody id="some_id"><tr id="some_header" class="some_header">
<th>head1</th>
<th>head2</th>
<th>head3</th>
</tr>
<td>0</td>
</tr>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>5</td>
</tr>
<tr>
<td>6</td>
</tr>
<tr>
<td>7</td>
</tr>
<tr>
<td>8</td>
</tr>
<tr>
<td>9</td>
</tr>
<tr>
<td>10</td>
</tr>
</table>
</div>
<div class="tdiv">
<input type="button" value="Next" onclick="paginateTable('test2', 1);">
<input type="button" value="Previous" onclick="paginateTable('test2', -1);">
<table id="test2">
<tr>
<td>0</td>
</tr>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>5</td>
</tr>
<tr>
<td>6</td>
</tr>
<tr>
<td>7</td>
</tr>
<tr>
<td>8</td>
</tr>
<tr>
<td>9</td>
</tr>
<tr>
<td>10</td>
</tr>
</table>
</div>

</body>
</html>

First I removed test2 table obviously since I don't need more than 1 set of buttons for that. But I'm not sure how to both keep the first row and the style when the tables are being split that way, maybe there's an easier way to split it (without creating new pages, since it's supposed to be one file for ease of use and partly to be used offline)

I want to understand how to manipulate a function like that for the future.


Solution

  • You could slice the rows to skip the first one.
    But better use the proper HTML and wrap you header into <thead> and the rest into <tbody>:

    {
    const r = [...document.getElementById('table').rows].slice(1);
    r[0].cells[0].textContent = 'Test';
    }
    {
    const r = document.querySelectorAll('#table2>tbody>tr');
    r[0].cells[0].textContent = 'Test';
    }
    <table id="table">
      <tr id="#header"><th>Header</th></tr>
      <tr><td>Data</td></tr>
    </table>
    
    <table id="table2">
      <thead>
        <tr id="#header"><th>Header</th></tr>
      </thead>
      <tbody>
        <tr><td>Data</td></tr>
      </tbody>
    </table>