The Document Object Model (DOM) is a way to refer to—and manipulate via javascript—elements on a web page. Each element is called a node. Nodes can be tags (element nodes) or the text within a tag (text node). Javascript commands can be written to target specific nodes; you can change a node, add a new node, or eliminate one. In this exercise you will create a page that allows users to dynamically add, subtract, and replace paragraphs on the page that they are viewing (see the example to the right).
<form action="#">
<p><textarea id="textArea" rows="5" cols="30"></textarea></p>
<p>
<label><input type="radio" name="nodeAction" />Add node</label>
<label><input type="radio" name="nodeAction" />Delete node</label>
<label><input type="radio" name="nodeAction" />Insert before node</label>
<label><input type="radio" name="nodeAction" />Replace node</label>
</p>
<p>Paragraph #: <select id="grafCount"></select>
<input type="submit" value="Submit" /></p>
</form>
<div id="modifiable"> </div>
This creates a form (like that above) with a text field and four radio buttons. It also creates a selector menu (but leaves it empty for now) and a submit button. The <div> block called "modifiable" will be where the dynamically created paragraphs will be written.
<script language="javascript" type="text/javascript">
</script>
window.onload = initAll;
var nodeChangingArea;
function initAll() {
document.getElementsByTagName("form")[0].onsubmit = function() {return nodeChanger();}
nodeChangingArea = document.getElementById("modifiable");
}
This first section executes the function "initAll" once the page loads and sets up a variable called "nodeChangingArea." Then we create the "initAll" function. This function tells the browser to perform the function "nodeChanger" when the submit button is pressed. It also assigns the variable "nodeChangingArea" to the <div> tag called "modifiable."
function addNode() {
var inText = document.getElementById("textArea").value;
var newText = document.createTextNode(inText);
var newGraf = document.createElement("p");
newGraf.appendChild(newText);
nodeChangingArea.appendChild(newGraf);
}
The "addNode" function first creates a variable called "inText" which captures the text entered by the user. Then a new text node called "newText" which is filled with the text in "inText." The text node has to be placed in some kind of element node so we create that next, "newGraf," which we specify as a paragraph tag. We could designate it as any tag we want ("h1," "span," "div," etc.). Then we add ("append") the text found in "newText" to the paragraph ("newGraf"). Finally, the new paragraph tags and the text within are placed inside the "nodeChangingArea," which is the empty <div> block called "modifiable."
function delNode() {
var delChoice = document.getElementById("grafCount").selectedIndex;
var allGrafs = nodeChangingArea.getElementsByTagName("p");
var killGraf = allGrafs.item(delChoice);
nodeChangingArea.removeChild(killGraf);
}
This function first determines which paragraph was chosen by the user via the pop-up menu (called "grafCount") and passes that number on to the variable "delChoice." Then the element (paragraph) that corresponds to that number is deleted via the DOM ("removeChild").
function insertNode() {
var inChoice = document.getElementById("grafCount").selectedIndex;
var inText = document.getElementById("textArea").value;
var newText = document.createTextNode(inText);
var newGraf = document.createElement("p");
newGraf.appendChild(newText);
var allGrafs = nodeChangingArea.getElementsByTagName("p");
var oldGraf = allGrafs.item(inChoice);
nodeChangingArea.insertBefore(newGraf,oldGraf);
}
This function works very similarly to "addNode," except it uses a new variable—"inChoice" which records which paragraph was selected by the user via the pop-up menu. The new paragraph is then inserted prior to the selected paragraph.
function replaceNode() {
var inChoice = document.getElementById("grafCount").selectedIndex;
var inText = document.getElementById("textArea").value;
var newText = document.createTextNode(inText);
var newGraf = document.createElement("p");
newGraf.appendChild(newText);
var allGrafs = nodeChangingArea.getElementsByTagName("p");
var oldGraf = allGrafs.item(inChoice);
nodeChangingArea.replaceChild(newGraf,oldGraf);
}
This one is identical to "insertNode" except for the last line—"insertBefore" is replaced by "replaceChild," which is fairly self-explanitory.
function nodeChanger() {
var actionType = -1;
var currentPgraphCount = nodeChangingArea.getElementsByTagName("p").length;
var radioButtonSet = document.getElementsByTagName("form")[0].nodeAction;
for (var i=0; i<radioButtonSet.length; i++) {
if (radioButtonSet[i].checked) {
actionType = i;
}
}
switch(actionType) {
case 0:
addNode();
break;
case 1:
if (currentPgraphCount > 0) {
delNode();
break;
}
case 2:
if (currentPgraphCount > 0) {
insertNode();
break;
}
case 3:
if (currentPgraphCount > 0) {
replaceNode();
break
}
default:
alert("No valid action was chosen");
}
document.getElementById("grafCount").options.length = 0;
for (i=0; i<nodeChangingArea.getElementsByTagName("p").length; i++) {
document.getElementById("grafCount").options[i] = new Option(i+1);
}
return false;
}
This function does several things. For one it looks to see which button has been pressed and applies the appropriate function accordingly ("insertNode," "replaceNode," etc.). It also makes sure that it can accomplish the requested effect; in other words, it checks to see if there is a paragraph to delete when that option is selected, etc. It also provides the pop-up menu with the proper number of paragraphs ("graffCount.")
4 pts |
Portfolio quality design. |
3 pts |
Good looking; above average work. |
2 pts |
It works, but it's nothing fancy. |
1 pts |
Something's not working right. |
0 pts |
Poor showing; mostly incomplete or full of errors. |