Creating Table onfly
For our DOM script, we're going to be working with a table. What's going to happen is we'll create a table
The Code
Now, lets examine this code bit by bit (no pun intended):
<script language="javascript" type="text/javascript">
var selectedTD = null;
var copiedTD = null;
var table, tbody, tr, td, text;
This code creates our global variables we will be using. selectedTD will store the table cell the user selected. copiedTD will store the table cell the user copied. table, tbody, tr, td, text will store the different parts of the table when we create them with document.createElement().
Creating our table
function createNewRow(txt){
tr = document.createElement("tr");
td = document.createElement("td");
td.setAttribute("width","300");
td.setAttribute("bgColor","purple");
td.setAttribute("style","color:white;font-family:Arial;text-align:center");
td.addEventListener("click", clickTD, false);
text = document.createTextNode(txt);
td.appendChild(text);
tr.appendChild(td);
}
This function creates a new row, storing it in the appropriate global variables we declared earlier. It creates a textNode with the text passed in its sole argument. Also, it assigns some attributes to the table cell tag; the bgColor attribute we'll use a lot in this script, so note that its default, unhightlighted color is "purple" (its highlighted color will be "blue". In addition, we assign an EventListener to the newly created table cell to run when someone clicks on the table cell; we'll take a look at the clickTD function a little later.
div = document.createElement("div");
div.setAttribute("align","center");
table = document.createElement("table");
table.setAttribute("border","3");
div.appendChild(table);
tbody = document.createElement("tbody");
table.appendChild(tbody);
for(i=0;i<5;i++){
createNewRow("This is the text in cell "+parseInt(i+1)+".");
tbody.appendChild(tr);
}
document.body.appendChild(div);
This section of code creates a div element, whose align attribute is set to "center". It also creates a table element, who's a child of the div element. Then, it creates a tbody element, who's a child of the table element. Then, it creates 5 new table rows, using the createNewRow function. It then appends these new rows to the tbody element. Lastly, it appends the div element to the body. Altogether, we've created the following HTML code:
<body>
<div align="center">
<table border="3">
<tbody>
<tr>
<td width="300" bgcolor="purple" style="color:white;font-family:Arial;text-align:center">
This is the text in cell 1.
</td>
</tr>
<tr>
<td width="300" bgcolor="purple" style="color:white;font-family:Arial;text-align:center">
This is the text in cell 2.
</td>
</tr>
<tr>
<td width="300" bgcolor="purple" style="color:white;font-family:Arial;text-align:center">
This is the text in cell 3.
</td>
</tr>
<tr>
<td width="300" bgcolor="purple" style="color:white;font-family:Arial;text-align:center">
This is the text in cell 4.
</td>
</tr>
<tr>
<td width="300" bgcolor="purple" style="color:white;font-family:Arial;text-align:center">
This is the text in cell 5.
</td>
</tr>
</tbody>
</table>
</div>
</body>
The clickTD function
Now, let's examine another code segment:
function clickTD(){
if(selectedTD) selectedTD.setAttribute("bgColor","purple");
if(selectedTD != this){
selectedTD = this;
selectedTD.setAttribute("bgColor","blue");
showForm();
}else{
selectedTD = null;
hideForm();
}
}
This code might look difficult, but it's really not. This function is run when someone clicks on a table cell. Once they click on a table cell, it will become highlighted (by changing the bgColor to "blue") and by unhighlighting the currently selected table cell (by changing the bgColor to "purple"), and a form will popup with options for them to perform on this table cell. If they click on the same highlighted table cell again, it becomes unselected and the form with the operations to perform becomes hidden.
First, it declares the following code to be the function, clickTD. If a table cell is currently highlighted, it unhighlights it, changing its bgColor to "purple". Then, it then sets the selectedTD variable to the table cell the user just clicked on. In addition, it changes the cell's bgColor to the hightlighted color, "blue". Then, it performs the function, showForm, which shows the form, which we'll examine later. However, if the table cell the user just clicked on was already selected (thus, he wants to unselect it), it gives a null value to the selectedTD variable. It also hides the form with the hideForm function, which we'll examine in just a bit.
The Form
Before moving on, let's examine the form code we'll be using:
<form style="display:none">
<div align="center">
<input type="button" value="Delete" onclick="deleteR()">
<font face="Arial, Helvetica, sans-serif">
<input type="button" value="Insert New Row" onClick="insertNR()">
<input type="button" value="Copy Cell" onClick="copyCell(selectedTD)">
<input type="button" value="Paste Cell" onClick="pasteCell()">
<br>
Change Text:</font>
<input name="newTextInput" type="text" size="27">
<input type="button" value="Change Text" onclick="changeText(document.forms[0].newTextInput.value)">
</div>
</form>
Now, let's examine the functions to hide and show this form, which starts off hidden until a table cell is selected.
function hideForm(){document.getElementsByTagName("form").item(0).setAttribute("style","display:none");}
function showForm(){document.forms[0].setAttribute("style","display:block");}
The hideForm function hides the form, and the showForm function shows the form. Also note how you can access the form both of those ways.
Now, we can examine the functions to perform the operations to the selected table cell.
Insert New Row
function insertNR(){
if(document.forms[0].newTextInput.value=="") createNewRow("This is the new table cell");
else createNewRow(document.forms[0].newTextInput.value);
tbody.insertBefore(tr, selectedTD.parentNode.nextSibling);
window.resizeBy(-10,-10);
window.resizeBy(10,10);
}
The function creates a new row. If the newTextInput input box is empty, it creates a new table cell with generic text. Otherwise, it creates a table row with the next in the newTextInput input box. It then inserts it after the table cell row that's selected. Note that selectedTD.parentNode refers to the tr element of the selected td element. So selectedTD.parentNode.nextSibling refers the tr element after the currently selected one. This is so the new one can be inserted after the currently selected one (selectedTD.parentNode), which is before selectedTD.parentNode.nextSibling. Note the the latter part of the code (window.resizeBy()) is to overcome a Mozilla 6 bug that I encountered when I try to insert or paste more than once cell in a row.
Change Cell's Text
function changeText(txt){
if(txt="")return;
selectedTD.firstChild.nodeValue = txt;
}
What this does is change the text of the currently selected table cell to the data located in document.forms[0].newTextInput, which is passed as the argument, txt. However, if document.forms[0].newTextInput.value is empty, it doesn't do anything.
Copy Table Cell
function copyCell(cellToCopy){
copiedTD = selectedTD.cloneNode(true);
copiedTD.setAttribute("bgColor","purple");
copiedTD.addEventListener("click", clickTD, false);
}
This copies the selected table cell. Note that I couldn't have gone: copiedTD = selectedTD because then they'd be referencing the same object in the computer's memory and trying to append both of them to the table would do nothing as one (the same one) would already exist. Also, since the selectedTD cell is highlighted, I don't want the copiedTD cell to also be highlighted, so I unhightlight it. Lastly, since cloning a node doesn't copy it's EventListeners, I need to add them to the copiedTD cell.
Paste Table Cell
function pasteCell(){
if(!copiedTD) return;
tr = document.createElement("tr");
tr.appendChild(copiedTD);
tbody.insertBefore(tr, selectedTD.parentNode.nextSibling);
window.resizeBy(-10,-10);
window.resizeBy(10,10);
copyCell(copiedTD);
}
First, it detects if a table cell has been copied. If it hasn't, it the function stops; however, if some table cell is copied, the code goes on. It creates a new tr element, and appends the copiedTD td cell to it. Then, it inserts the new table row right after the currently selected one. Next, we have the Mozilla fix I talked about before. And lastly, we copy the table cell again because if we didn't and tried to paste the same copied td cell in the table again, it would reference the same object in the memory and already exist.
And that's all there is to our DOM script, simple eh???
Ok, you can stop laughing now :-)
One other thing I should mention is we used Core DOM (basic DOM) to do this, but DOM actually has built in functions for some of this, such as insertRow() and deleteRow(). You can look up methods that apply only to certain elements, such as the ones mentioned here, here DOM-HTML, and the ones mentioned here (for tables) can be found here: DOM-HTML: TABLES.