Traversing an HTML Table with JavaScript and DOM Interfaces
DYNAMICALLY MANIPULATING
HTML
ELEMENTS
WITH
DOM
LEVEL
1
By Marcio Galli
Gecko Technology Evangelist
INTRODUCTION
-
This technote is an overview of some powerful, fundamental DOM level 1.0
methods and how to use them from JavaScript. You will learn how to create,
access and control, and remove HTML elements dynamically. The DOM methods
presented here are not specific to HTML; they also apply to XML. The
demonstrations provided here will work fine in any browser with full support
for DOM level 1, such as the Mozilla browser or others based on it like the
next-generation Navigator browser from Netscape. The code samples in this
document also work on IE5.
Note: The DOM methods presented here are part of the Document Object Model (Core) level 1 specification. DOM level 1 includes both methods for generic document access and manipulation (DOM 1 Core) as well as methods specific to HTML documents (DOM 1 HTML).
CONTENTS
-
Quick Summary Of DOM Methods and Attributes Used in this Technote
Starting With Sample Code - overview of sample1.html
- Sample1 - dynamically creates an example HTML Table with 4 cells
- The HTML table markup that was dynamically generated
- Object tree for the sample HTML Table
Fundamental DOM Methods - sample2.html
- Accessing node elements using getElementsByTagName(..) and the item(..) methods
- Creating TextNodes with document.createTextNode(..)
- Inserting Elements with appendChild(..)
- Creating New Elements with the Document interface and the createElement(..) method
- Removing nodes with the removeChild(..) method
Sample1.html - creating a table dynamically
- Reviewing the HTML Table structure
- Creating Element Nodes and Inserting Them Into the Document Tree
Manipulating the table with DOM and CSS
- Getting a text node from a table
- Getting an attribute value
- Hiding a column by changing style properties
QUICK SUMMARY OF DOM METHODS AND ATTRIBUTES USED IN THIS TECHNOTE
-
method: document.getElementsByTagName(tagNameString)
Example: myDocumentElements=document.getElementsByTagName("body");What it does: Returns a list of all the elements in the document that have tag name tagNameString
For more Information: W3C's DOM Level 1 - interface Document, interface Element
method: item(n)
Example: myBody=myDocumentElements.item(0);What it does: From a list, returns item number n
For more Information: W3C's DOM Level 1 - interface NodeList
method: document.createElement(tagNameString)
Example: myNewPTAGnode=document.createElement("p");What it does: Creates and returns a new element with tag name tagNameString
For more Information: W3C's DOM Level 1 - interface Document
method: document.createTextNode(textString)
Example: myTextNode=document.createTextNode("world");What it does: Creates and returns a new text node with textString as its text
For more Information: W3C's DOM Level 1 - interface Document
method: parentElement.appendChild(newChildElement)
Example: myBody.appendChild(myNewPTAGnode);What it does: Adds newChildElement as a child element of parentElement at the end of the list
For more Information: W3C's DOM Level 1 - interface Node
attribute: textNode.data;
Example: textdata=myceltext.data;What it does: Returns a text string that is the content of textNode.
For more Information: W3C's DOM Level 1 - interface CharacterData
attribute: attributeNode.value;
Example: myattributevalue=myattribute.value;What it does: Returns a text string that is the value of attributeNode.
For more Information: W3C's DOM Level 1 - interface Attr
STARTING WITH SAMPLE CODE - OVERVIEW OF SAMPLE1.HTML
-
This technote is an introduction to the DOM through sample code. Once
you are familiar with the Level 1 DOM's fundamental methods, you can
continue your study using the additional information in the
reference section. To get started, to try out
the following HTML sample. It uses DOM level 1
methods from JavaScript to create an HTML table dynamically.
See below for a fully commented version
of this code sample. Basically, it creates a small table with four cells
and text content inside each cell. The text content of the cell is:
"cell is row y column x" showing the row and column numbers for
that cell in the table.
- First we created the TABLE element.
- Next, we created the TBODY element, which is a child of the TABLE element.
- Next, we used a loop to create the TR elements, which are children of the TBODY element.
- For each TR element, we used a loop to create the TD elements, which are children of TR elements.
- For each TD element, we then created the text node with the table cell's text.
- First, we attach each text node to its parent TD element using
<html> <head> <title>Sample code - Traversing an HTML Table with JavaScript and DOM Interfaces</title> <script> function start() { var mybody=document.getElementsByTagName("body").item(0); mytable = document.createElement("TABLE"); mytablebody = document.createElement("TBODY"); for(j=0;j<2;j++) { mycurrent_row=document.createElement("TR"); for(i=0;i<2;i++) { mycurrent_cell=document.createElement("TD"); currenttext=document.createTextNode("cell is row "+j+", column "+i); mycurrent_cell.appendChild(currenttext); mycurrent_row.appendChild(mycurrent_cell); } mytablebody.appendChild(mycurrent_row); } mytable.appendChild(mytablebody); mybody.appendChild(mytable); mytable.setAttribute("border","2"); } </script> </head> <body onload="start()"> </body> </html> |
Study carefully the order in which we created the elements and the text node:
Once we have created the TABLE, TBODY, TR, and TD elements and then the text node, we then append each object to its parent in the opposite order:
mycurrent_cell.appendChild(currenttext);
mycurrent_row.appendChild(mycurrent_cell);
mytablebody.appendChild(mycurrent_row);
mytable.appendChild(mytablebody);
mybody.appendChild(mytable);Remember this technique. You will use it frequently in programming for the W3C DOM. First, you create elements from the top down; then you attach the children to the parents from the bottom up.
Here's the HTML markup generated by the JavaScript code:
... <TABLE border=5> <tr><td>cell is row 0 column 0</td><td>cell is row 0 column 1</td></tr> <tr><td>cell is row 1 column 0</td><td>cell is row 1 column 1</td></tr> </TABLE> ... |
Here's the DOM object tree generated by the code for the TABLE element and its child elements:
Figure 1 - Object tree for the sample HTML Table
You can build this table and its internal child elements by using just a few DOM methods. Remember to keep in mind the tree model for the structures you are planning to create; this will make it easier to write the necessary code. In the TABLE tree of Figure 1 the element TABLE has one child, the element TBODY. TBODY has two children. Each TBODY's child (TR) has one child (TD). Finally, each TD has one child, a text node.
FUNDAMENTAL DOM METHODS - SAMPLE2.HTML
-
Accessing node elements by using getElementsByTagName(..) and the item(..) methods
-
First, we get a list of all the body elements via
document.getElementsByTagName("body")
Since there is only one body element in any valid HTML document, this list will have only one item.
-
Next, we get the first element on that list, which will be the
object for the body element itself, via
myBody=myDocumentElements.item(0);
-
Next, we get all the p elements that are children of the body via
myBodyElements=myBody.getElementsByTagName("p");
-
Finally, we get the second item from the list of p elements via
myP=myBodyElements.item(1);
Using getElementsByTagName to retrieve elements by their tag name
getElementByTagName is a method of both the Document interface and the Element interface, so both the root document object as well as all Element objects have the getElementByTagName method. To get a list of children of some element, selecting them by tag names, you can use element.getElementsByTagName(tagname).
getElementsByTagName returns a list of child elements that have the specified tagname. From that list of child elements, you can reach an individual element by calling the item method, passing an index for the item number you want returned. The first child element of the list is element number zero. It's easy and very simple but needs attention when you are working with large structures. In the next topic we continue working with the Table sample. The following sample is a simpler one, intended to show some basic methods:
<html> <head> <title>Sample code - Traversing an HTML Table with JavaScript and DOM Interfaces</title> <script> function start() { // get a list of all the body elements (there will only be one) myDocumentElements=document.getElementsByTagName("body"); // the body element itself is the first item of the list myBody=myDocumentElements.item(0); // now, get all the p elements that are children of the body myBodyElements=myBody.getElementsByTagName("p"); // get the second item of the list of p elements myP=myBodyElements.item(1); } </script> </head> <body onload="start()"> <p>hi</p> <p>hello</p> </body> </html> |
In this example, we set the myP variable to the DOM object for the second p element inside the body:
Once you have gotten the DOM object for an HTML element, you can set its properties. For example, if you want to set the style background color property, you just add:
myP.style.background="rgb(255,0,0)"; // setting inline STYLE attribute |
Creating TextNodes with document.createTextNode(..)
Use the document object to invoke the createTextNode method and create your text node. You just need to pass the text content. The return value is an object that represents the text node.
myTextNode=document.createTextNode("world"); |
This means that you have created a node of the type TEXT_NODE (a piece of text) whose text data is "world", and myTextNode is your reference to this node object. To insert this text into your HTML page, you need to make this text node a child of some other node element.
Inserting Elements with appendChild(..)
So, by calling myP.appendChild([node_element]), you are making the element a new child of the second P element.
myP.appendChild(myTextNode); |
Click here to see the complete source of sample2, including these two new lines to create a text node that appends itself as child of the second P element. After testing this sample, note that the words hello and world are together: helloworld. So visually, when you see the HTML page it seems like the two text nodes hello and world are a single node, but remember that in the document model, there are two nodes. The second node is a new node of type TEXT_NODE, and it is the second child of the second P tag. The following figure shows the recently created Text Node object inside the document tree.
NOTE: createTextNode and appendChild is a simple way to include white space between the words hello and world. Another important note is that the appendChild method will append the child after the last child, just like the word world has been added after the word hello. So if you want to append a Text Node between hello and world you will need to use insertBefore instead of appendChild. Click here to see an example with insertBefore and here for its source code. |
Creating New Elements with the document object and the createElement(..) method
You can create new HTML elements or any other element you want with createElement. For example, if you want to create a new P element as a child of the BODY element, you can use the myBody in the previous example and append a new element node. To create a node simply call document.createElement("tagname"). For example:
myNewPTAGnode=document.createElement("p"); myBody.appendChild(myNewPTAGnode); |
Removing nodes with the removeChild(..) method
Each node can be removed. The following line removes the text node which contains the word world of the myP (second P element).
myP.removeChild(myTextNode); |
Finally you can add myTextNode (which contains the word world) into the recently created P element:
myNewPTAGnode.appendChild(myTextNode); |
Click here to see the sample2b.html - this final example and here for the source code. The final state for the modified object tree looks like this:
SAMPLE1.HTML - CREATING A TABLE DYNAMICALLY
-
For the rest of this technote we will continue working with sample1.html.
The following figure shows the table object tree structure for the table
created in the sample.
- Get the body object (first item of the document object).
- Create all the elements.
- Finally, append each child according to the table structure (as in the above figure). The following source code is a commented version for the sample1.html.
Reviewing the HTML Table structure
Creating Element Nodes and Inserting Them Into the Document Tree
The basic steps to create the table in sample1.html are:
NOTE: At the end of the start function there is a new line of code. The table's border property was set using another DOM method, setAttribute. setAttribute has two arguments: the attribute name and the attribute value. You can set any attribute of any element using the setAttribute method. |
<head> <title>Sample code - Traversing an HTML Table with JavaScript and DOM Interfaces</title> <script> function start() { // get the reference for the body var mybody=document.getElementsByTagName("body").item(0); // creates an element whose tag name is TABLE mytable = document.createElement("TABLE"); // creates an element whose tag name is TBODY mytablebody = document.createElement("TBODY"); // creating all cells for(j=0;j<2;j++) { // creates an element whose tag name is TR mycurrent_row=document.createElement("TR"); for(i=0;i<2;i++) { // creates an element whose tag name is TD mycurrent_cell=document.createElement("TD"); // creates a Text Node currenttext=document.createTextNode("cell is row "+j+", column "+i); // appends the Text Node we created into the cell TD mycurrent_cell.appendChild(currenttext); // appends the cell TD into the row TR mycurrent_row.appendChild(mycurrent_cell); } // appends the row TR into TBODY mytablebody.appendChild(mycurrent_row); } // appends TBODY into TABLE mytable.appendChild(mytablebody); // appends TABLE into BODY mybody.appendChild(mytable); // sets the border attribute of mytable to 2; mytable.setAttribute("border","2"); } </script> </head> <body onload="start()"> </body> </html> |
MANIPULATING THE TABLE WITH DOM AND CSS
-
Getting a text node from a table
This example introduces two new DOM attributes. First it uses the childNodes attribute to get the list of child nodes of mycel. The childNodes list includes all child nodes, regardless of what their name or type is. Like getElementsByTagName, it returns a list of nodes. The difference is that getElementsByTagName only returns elements of the specified tag name. Once you have the returned list, use item(x) method to retrieve the desired child item. This example stores in myceltext the text node of the second cell in the second row of the table. Then, to display the results in this example, it creates a new text node whose content is the data of myceltext and appends it as a child of the BODY element.
NOTE: If your object is a text node, you can use the data attribute and retrieve the text content of the node. |
mybody=document.getElementsByTagName("body").item(0); mytable=mybody.getElementsByTagName("table").item(0); mytablebody=mytable.getElementsByTagName("tbody").item(0); myrow=mytablebody.getElementsByTagName("tr").item(1); mycel=myrow.getElementsByTagName("td").item(1); // first item element of the childNodes list of mycel myceltext=mycel.childNodes.item(0); // content of currenttext is the data content of myceltext currenttext=document.createTextNode(myceltext.data); mybody.appendChild(currenttext); |
Getting an attribute value
At the end of sample1 there is a call to setAttribute on the mytable object. This call was used to set the border property of the table. To get attributes, use the getAttribute method, which returns an attribute object. To retrieve the value of the attribute, use the value property:
myattribute=mytable.getAttribute("boder"); myattributevalue=myattribute.value; alert("myattributevalue"); |
Hiding a column by changing style properties
Once you have the object in your JavaScript variable, you can set style properties directly. The following code is a modified version of sample1.html in which each cell of the second column is hidden and each cell of the first column is changed to have a red background. Note that the style property was set directly.
<html> <body onload="start()"> </body> <script> function start() { var mybody=document.getElementsByTagName("body").item(0); mytable = document.createElement("TABLE"); mytablebody = document.createElement("TBODY"); for(j=0;j<2;j++) { mycurrent_row=document.createElement("TR"); for(i=0;i<2;i++) { mycurrent_cell=document.createElement("TD"); currenttext=document.createTextNode("cell is:"+i+j); mycurrent_cell.appendChild(currenttext); mycurrent_row.appendChild(mycurrent_cell); // set the cell background color // if the column is 0. If the column is 1 hide the cel if(i==0) { mycurrent_cell.style.background="rgb(255,0,0)"; } else { mycurrent_cell.style.display="none"; } } mytablebody.appendChild(mycurrent_row); } mytable.appendChild(mytablebody); mybody.appendChild(mytable); } </script> </html> |
REFERENCES
SAMPLE CODES OF THIS TECHNOTE
- sample1 - source code - Dynamically creating a table
- sample2 - source code - Get an object reference with getElementsByTagName
- sample2a - source code - Appending new elements
- sample2b - source code - Removing elements
STANDARD DOCUMENTATION AND DIRECTORIES
- Standard Documentation - W3C Document Object Model Level 1 - Specification
- JavaScript.W3C_DOM Category at dmoz.org
SAMPLE CODE AND DEMONSTRATIONS
- Scrolling Banner - demonstrates a scrolling banner implementation - uses DOM1
and DOM2
- Taboca Demonstrations for Gecko - collection of DOM demos
- Toshirou
Takahashi's DOM Sample Code - Numerous samples showing how to use DOM features
- DMOZ.org, DOM demos directory Directory with DOM demonstrations at DMOZ.ORG
- Style Sample Codes - Using DOM to access and manipulate styles - DMOZ.ORG
RELATED TECHNOLOGIES AND DOCUMENTATION
- Standard Documentation - W3C Document Object Model Level 2 - Draft Specification
- XML 1.0 Specification
- Cascading Style Sheets, level 1 - Specification
SUPPORT
mozilla.org does not provide technical support services to browser users or web content developers. mozilla.org does have newsgroups, but they are intended for discussions about the design and development of the Mozilla browser and its future features, not for user or web developer support "how to" questions.
Much information on these standards and technologies can be found at http://www.w3.org, http://www.ecma.ch, and http://developer.netscape.com/. If after consulting those resources you have questions about developing content and applications using the technologies mentioned in this TechNote, here is a list of newsgroups on these topics:
Newsgroup | Topic of Newsgroup |
comp.infosystems.www.authoring.html | Usenet HTML newsgroup |
netscape.public.dev.html | Netscape DevEdge HTML 4.0 newsgroup |
comp.text.xml | Usenet XML newsgroup |
netscape.public.dev.xml | Netscape DevEdge XML newsgroup |
comp.infosystems.www.authoring.stylesheets | Usenet CSS newsgroup |
netscape.public.dev.css | Netscape DevEdge CSS newsgroup |
netscape.public.dev.dom | Netscape DevEdge DOM newsgroup |
comp.lang.javascript | Usenet JavaScript newsgroup |
netscape.devs-javascript | Netscape DevEdge JavaScript newsgroup |
If you would like user or developer support for a particular vendor's product, please contact that vendor for details. If you would like technical support or other assistance from Netscape regarding the features or technologies of shipping (post-release, not beta) Netscape products, please visit the Netscape DevEdge Online Support Area.
FEEDBACK
Do you have comments or suggestions about this article? Please use the following link: