I am trying to push display:none property rows to the bottom of table. However, my code pushes only the first tr with display:none property. The second row stays at the same position, and I am not able to push it down to bottom of the table.
<html>
<head>
<script>
function moveHiddenRows()
{
var table = document.getElementById('res');
var rows = table.getElementsByTagName('tr');
for (var a=0, b=rows.length; a<b; a++)
{
if (rows[a].style.display == 'none')
{
var row = rows[a].parentNode.removeChild(rows[a]);
table.appendChild(row);
}
}
for(var i=0;i<rows.length;i++)
{
if(i%2==0)
rows[i].className="even";
else
rows[i].className="odd";
}
}
</script>
<style>
.odd{
background-color:red;
}
.even{
background-color:yellow;
}
</style>
</head>
<body onload="javascript:moveHiddenRows();">
<table id="res">
<tbody>
<tr><td>ABC</td></tr>
<tr><td>asd</td></tr>
<tr style="display:none;"><td>XYZ</td></tr>
<tr style="display:none;"><td>asd</td></tr>
<tr><td>asd</td></tr>
<tr><td>asd</td></tr>
</tbody>
</table>
</body>
</html>
Part of your problem is here:
Firstly, don’t declare variables inside an if block, javascript only has function scope so better to declare them at the top of the function so the scope is obvious. I’ll leave it for you to fix.
Secondly, in IE rows must be added to a tbody element, other browsers used to add them to the tbody if you don’t, but lately Firefox has not done that, so add them to a tBody.
Lastly, your problem is that rows is an HTMLCollection, so it’s live. When you move the first row, at index 1, the one below it becomes row 1. So on the next iteration on index 2, it gets the row below it (i.e. the one that was originally index 3 but is now 2 ‘cos you moved 1 to the bottom). On the last iteration, you get the row you already moved to the bottom.
The simple solution is to go through the collection backwards. Oh, and you don’t have to remove and replace the element, you can just move it:
Note however that the rows have been swapped in order. Sorry about that! An alternative to keep them in order is to convert the collection to an array (simply loop over the collection and add the rows to an array), or mess with the counters:
since rows[a].parentNode is the tbody. Note that this moves it to the bottom of the tbody, so if you have multiple tbody elements you’ll need to get a reference to the last one and add them there: