Javascript Tutorial -- Adding New Content Dynamically
In our previous lessons, we have learned how to use Javascript to dynamically update content in an HTML document, and we learned that while you sometimes can even add new HTML tags (or elements) using the "innerHTML" method, that is not the ideal way to add new content. The reason innerHTML should not be used to add new content is two-fold: first, innerHTML may or may not always add new HTML tags -- it is not part of the Javascript specification, so while many browsers may let you get away with this, you can't count on it. Second, suppose you have a web page that is continuously updated with user-submitted content (think Digg or Slashdot). It would be a chore to update all of the user-submitted content every time a user submitted another comment, and it would negate Javascript's advantage of being able to update a portion of your HTML document at a time -- if you want to update all of the comments every time a new comment is added, you may as well do the scripting server-side with Perl, PHP or Python.
In this lesson, we learn about a better way to add text and HTML to an HTML document. Be warned: this lesson is probably the most complex yet. The concepts aren't terribly difficult (although we will cozy up to the Document Object Model again), but unlike many of the previous lessons where we learned how to apply a single new method to accomplish a task, in this lesson, we will have to use several new methods, and we will have to use them together to accomplish the task at hand. But take heart -- if you've made it this far, you won't have any problem with this lesson. The new methods are very straightforward, and rather intuitive to use, as well. Here we go!
We'll get started with a little more theory, first. In Lesson 17, we first encountered the Document Object Model, although we didn't discuss it in very much detail since it wasn't strictly necessary to our understanding of HTML forms. However, a basic understanding of the DOM is critical for understanding this lesson.
In a nutshell, web browsers abstract an HTML document into a tree structure. At the root of the tree are the <html>/</html> tags. Underneath the root element are the <head> and <body> elements (and their corresponding closing elements), and underneath them are all of the other elements you find in a well-constructed HTML document. Therefore, for an HTML document to be valid, you cannot have a structure like this, for example:
<!-- this is bad. DON'T DO THIS!!! -->
<p>
<font face="verdana">
blahblahblah
</p>
</font>
Since the <p> tag is a "parent node" to the <font> tag, the <font> tag must be closed before the <p> tag. In most cases, a browser will render such mismatched HTML correctly, but the exact way it will be rendered can vary widely from browser to browser (for that matter, so can properly formatted HTML, but I digress). This is why I tend to write HTML with child nodes indented inside of parent nodes -- it provides a way for me to check that I don't close a parent element before closing a child tag, and it also reflects the tree-like structure of the Document Object Model in the code I am writing (which makes it easy for me to keep straight which nodes are related to other nodes, and what the nature of that relationship is -- more indented == child node; less indented == parent node).
There is much more to the DOM than this, but this is enough background for this lesson. So, now that you understand the basic idea behind the DOM, here is how it applies to adding new tags and new content to an HTML document with Javascript: Javascript contains many, many more methods than we have learned. One of those methods is the "document.createElement()" method. This method takes one parameter -- a text value that tells the createElement() method what kind of HTML tag to create. For example...:
// create a <p> tag:
PNode = document.createElement("p")
// create a <br> tag:
BrNode = document.createElement("br")
// create a <font> tag:
FontNode = document.createElement("font")
Okay, that's pretty easy, so far. But where in your HTML document does createElement() put these new tags? Well, actually, nowhere. All the createElement() does is create a new tag; it does not place it anywhere in the document. So, as you can see, the createElement() tag by itself is not terribly useful.
However, there is another Javascript method called "appendChild()", which is used to, you guessed it, append a child node to some other node that already exists within the HTML document. Suppose you had an HTML document that contained this HTML element:
<p id='UserComments'>
Comments:
</p>
You could use the appendChild() method to append the new node as the last child element under this element. Here's how it's done:
// Let's assign the 'UserComments' element to a variable
// It's easier to keep track of what we're doing this way:
var UserComments = document.getElementById('UserComments')
// Now, create a new <p> tag:
var PNode = document.createElement('p')
// And append the new tag under the "UserComments" tag:
UserComments.appendChild(PNode)
See -- that wasn't so hard, was it? But now we've got another problem: we have created the new node, and we've even placed it in our document...but what good is an empty <p> tag? How do we add some content to the block of HTML code contained in this new tag? Well, there's another method, the "createTextNode()" method, that handles this task. This method accepts a string value as an input parameter, which contains the text you want to add to your document. Here's how you create a new text node:
var TextNode = document.createTextNode('new content goes here')
However, the createTextNode() method works rather like the createElement() method in that, while it will create the new node, it doesn't add it anywhere in the document. So, we will use the appendChild() method again to place it under the parent node:
var CommentBlock = document.getElementById('block')
var Submission = "some text to go in the page somewhere"
var PNode = document.createElement('p')
var TextNode = document.createTextNode(Submission.value)
PNode.appendChild(TextNode)
CommentBlock.appendChild(PNode)
That's it -- that's all there is to adding new content to an HTML document. And, you can repeat these steps over and over again to add new content to the end of your HTML document.
Here is a script that uses an HTML form to accept user input, parses the user input for unsafe data, then appends the new user content to the end of the document. It is a very simple script, but it illustrates the concepts that can be used to create a Javascript forum...except that it doesn't allow any of the user content to be saved. That comes in Lesson 25.