PDA

View Full Version : using getElementsByTagName and innerHTML to sequentially number table rows



robertbyrnes
12-11-2009, 03:35 AM
I don't have any experience writing in JavaScript, and I am looking for help writing some code that will dynamically number the table rows in an HTML document when it is loaded in the browser.

The unique HTML tag in this document is the <th></th> so I thought I could use getElementsByTagName and innerHTML to sequentially number the table rows automatically when the page gets loaded.

Right now, there are 250 rows, and every time I modify the page by inserting a new row, I have to manually go through each cell and manually type in its new numerical value.

Here is the testing page where I am working:
http://quasor.lunarpages.com/~mymass2/WWL/fixturetable.htm

Any help would be greatly appreciated!
Robert

jscheuer1
12-11-2009, 05:44 AM
The tr elements on any page are already numbered from 0 to however many - 1. So you really don't need to number them. Doing:


document.getElementsByTagName('tr')[0]

will get you the first one. Doing:


document.getElementsByTagName('tr')[document.getElementsByTagName('tr').length - 1]

will get you the last one. Doing:


var trs = document.getElementsByTagName('tr');
for(var i = 0; i < trs.length; ++i){
doSomthing(trs[i]);
}

Will doSomthing() with each one. Doing:


var trs = document.getElementsByTagName('tr');
for(var i = 0; i < trs.length; ++i){
if(i % 2 === 0){
doSomthing(trs[i]);
}
}

Will doSomthing() with each even numbered (starting from 0 as the first even numbered one) row.

robertbyrnes
12-11-2009, 12:39 PM
Thank you very much for such a quick and detailed response!

The problem with using the <tr> tags is that the page contains rows that are used to create other aspects of the page at the beginning and end of the document. Whereas, the <th> tags specifically contain only the values of the numbered rows.

Any way to specifically target the <th> tags?

Thanks again!
Robert

jscheuer1
12-11-2009, 12:50 PM
A th is just a specialized sort of td. You could do the same things with those as I explained above, just substitute th for tr in the code. But you will no longer be counting rows, just th tags, of which there could be more than one in a row. If you only want rows with th tags in them, you could do something like:


function doSomething(row){
var kids = row.childNodes;
for(var i = 0; i < kids.length; ++i){
if(kids[i].tagName && kids[i].tagName.toLowerCase() === 'th'){
doSomeOtherThing(row);
break;
}
}
}

var trs = document.getElementsByTagName('tr');
for(var i = 0; i < trs.length; ++i){
doSomthing(trs[i]);
}

The doSomeOtherThing function could do whatever you want to the rows, it will only do this to rows that contain at least one th element.

robertbyrnes
12-12-2009, 07:44 PM
Thanks again for your help. Yes, I use the <th> tag elsewhere in the document which means I'm going to have to target only the tags that contain my numbering sequence.

I was hoping for a simple solution, perhaps:

<script type="text/javascript">
var ths = document.getElementsByTagName('th');
for(var i = 0; i < ths.length; ++i){
document.write("L" + i);
}
</script>

But this obviously isn't it...

thanks again!

jscheuer1
12-12-2009, 08:07 PM
You can't get the elements of a page (except at the very end of the document) until it has loaded, and you can't document.write after the page has loaded. You could get the elements at the end of the document and write to the end of the document, but I don't think that's what you want to do, even so, there is a better way (inserting a text node).

The other problem is that it now appears that only some of the th elements are to receive this treatment. Which ones? Do they all share a class name? If so one could further refine on that basis, so you could have something like:


function doSomething(row){
var kids = row.childNodes;
for(var i = 0; i < kids.length; ++i){
if(kids[i].tagName && kids[i].tagName.toLowerCase() === 'th' && kids[i].className === 'header'){
kids[i].insertBefore(document.createTextNode('L' + (i + 1) + ': '), kids[i].firstChild);
break;
}
}
}

var trs = document.getElementsByTagName('tr');
for(var i = 0; i < trs.length; ++i){
doSomthing(trs[i]);
}

robertbyrnes
12-13-2009, 04:06 AM
Hey John -

Thanks for sticking with me on this - you're being very generous with your time and effort.

I created a class "auto" for the 250 <th> targeted tags in the revised document:
http://quasor.lunarpages.com/~mymass2/WWL/fixturetableJAVA.htm

I changed 'header' to 'auto' in your script - and played back and forth with changing some other things around like using... getElementsByTagName('th') instead of ('tr') and adding an "e" to doSomthing.

I'm wondering if "function doSomething" is more of a placeholder and I should be using a known function there instead?

Anyway, the script isn't producing the numbering sequence on the web page.

I have been reading a lot about Javascript on the web, and I am learning, but I've got a lot more to go!

Thanks again for your time and efforts!
Robert

jscheuer1
12-13-2009, 05:13 AM
By trial and error you might eventually get what you want, or not. There are various ways. Here's what I did - first I got rid of all that were like (highlighted):


<th scope="row" class="auto">L20</th>


So that all of the th tags with the class auto were empty.

Next I changed:


<script type="text/javascript">
function doSomething(row){
var kids = row.childNodes;
for(var i = 0; i < kids.length; ++i){
if(kids[i].tagName && kids[i].tagName.toLowerCase() === 'th' && kids[i].className === 'auto'){
kids[i].insertBefore(document.createTextNode('L' + (i + 1) + ': '), kids[i].firstChild);
break;
}
}
}

var trs = document.getElementsByTagName('th');
for(var i = 0; i < trs.length; ++i){
doSomething(trs[i]);
}

</script>

to:


<script type="text/javascript">
(function(){
var thNum = 0;
function doSomething(th){
if(th.className === 'auto'){
th.insertBefore(document.createTextNode('L' + (++thNum) + ': '), th.firstChild);
}
}

function getThs(){
var ths = document.getElementsByTagName('th');
for(var i = 0; i < ths.length; ++i){
doSomething(ths[i]);
}
}
if (window.addEventListener){
window.addEventListener('load', getThs, false);
}
else if (window.attachEvent){
window.attachEvent('onload', getThs);
}
})();
</script>

That seemed to do it. I'm not clear though on whether or not this is what you want, or if it is, why. It seems to me that the numbers would then change according to however many th tags you had with the class auto. And though it might look nice, these numbers wouldn't signify much of anything that's useful. That is to say that the only reason I can think of for doing it this way would be to accommodate a changing number of tags that qualify. But as the number of tags changes, especially if one is removed or inserted other than at the end, the numbers would change as well, so wouldn't from change to change necessarily point to anything in particular.

Another consideration is that, for folks with javascript disabled or unavailable, there will be no numbers.

But I may have missed the real point of this.

robertbyrnes
12-13-2009, 04:08 PM
Yes! That does the job very well, indeed!

Right, if someone has JavaScript disabled, or unavailable, they won't see the numbering sequence... but then, this page is really going to be the least of their web browsing problems!

When this fixture table first began, we used letters of the alphabet, as is the convention in this industry, and we only had some twenty rows. The table has grown to 250 rows, and as we add and subtract rows, or shift them up or down in the table, I would always manually adjust the numbering sequence to keep the table in order. Now, I can just let the browser do it.

Having the rows numbered helps people to clearly identify the row and fixtures in question.

Thanks again for your help. I've been scratching my head over this one for years!

I will comment in a credit to John Scheuer at dynamicdrive.com, if this is correct.
Robert

jscheuer1
12-13-2009, 04:53 PM
Having the rows numbered helps people to clearly identify the row and fixtures in question.

Well, what if the rows change between the time they identify the row and the time you or someone else looks to see what they're interested in? It could end up being the wrong row.


I will comment in a credit to John Scheuer at dynamicdrive.com, if this is correct.

You may use this credit if you like (and still want to use the script after my above comment):


<script type="text/javascript">
/* Cell Numbering Script (c)2009 John Davenport Scheuer
as first seen in http://www.dynamicdrive.com/forums/
username: jscheuer1 - This Notice Must Remain for Legal Use
*/

(function(){
var thNum = 0;
function doSomething(th){
if(th.className === 'auto'){
th.insertBefore(document.createTextNode('L' + (++thNum) + ': '), th.firstChild);
}
}

function getThs(){
var ths = document.getElementsByTagName('th');
for(var i = 0; i < ths.length; ++i){
doSomething(ths[i]);
}
}
if (window.addEventListener){
window.addEventListener('load', getThs, false);
}
else if (window.attachEvent){
window.attachEvent('onload', getThs);
}
})();
</script>