At the Forge - JavaScript

Like the language or hate it, JavaScript and Ajax finally give life to the Web.
Modifying the Page

So far, we have seen that JavaScript makes it easy to read values from the page. But part of the magic of JavaScript, and the reason why it sits at the core of Ajax, is that we can modify the contents of the page almost as easily as we can read them. For example:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script type="text/javascript">
    function helloWorld() {

        var username = document.getElementById("username").value;

        if (username == "")
        {
        alert("Please enter your name in the text field.");
        }
        else
        {
        alert("Hello, " + username + "!");

        var result = document.getElementById("result")
        var status_text =
            document.createTextNode("Thanks for clicking!");
        result.appendChild(status_text);
        }
    }
    </script>
    <title>Test JavaScript page</title>
</head>
<body>
    <p>Hi there!</p>

    <p>Enter your name: <input type="text" id="username" /></p>

    <p><input type="button" value="Click me!"
        onclick="helloWorld();" /></p>

    <p id="result"></p>

</body>
</html>

The difference between this version and the previous one is in the else clause of the if statement. After displaying the “hello” alert box, we look for an element whose ID is result. This belongs to a new <p> element on the page, whose contents are currently empty, and which sits just below the button. Note the difference between our two invocations of getElementById. In the case of the username, we want the text that the user has entered, and thus invoke the value method on the returned node. In the case of result, we keep the node itself in the variable, without grabbing any value or other property. That's because we want to modify the result node, adding a text node containing our message.

And indeed, we create the new text node by invoking document.createTextNode, passing it an argument of the text we want to display. Creating the text node does not display it; in order for us to put it on the page, we must attach it to a node that is already being displayed. We will attach it to our result node, using the appendChild method.

Now, each time we click on the click me! button, we not only get an alert, but modify the contents of the page as well.

There is a problem with the above code, however. Because we used the appendChild method to add our text node, we end up creating and appending a new text node once for each click of the button. After clicking the button ten times, for example, we will see our “thanks for clicking” message displayed ten times on the page.

The easiest way to avoid this is to ask the result node if it has any children. If it does, we can assume we have already displayed our result. If no children exist, we safely can go ahead with adding the new text node:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script type="text/javascript">
    function helloWorld() {

        var username = document.getElementById("username").value;

        if (username == "")
        {
        alert("Please enter your name in the text field.");
        }
        else
        {
        alert("Hello, " + username + "!");

        var result = document.getElementById("result")

        if (result.childNodes.length > 0)
        {
            alert("Already has children; not adding to the message");
        }
        else
        {
            var status_text =
            document.createTextNode("Thanks for clicking!");
            result.appendChild(status_text);
        }
        }
    }
    </script>
    <title>Test JavaScript page</title>
</head>
<body>
    <p>Hi there!</p>

    <p>Enter your name: <input type="text" id="username" /></p>

    <p><input type="button" value="Click me!"
        onclick="helloWorld();" /></p>

    <p id="result"></p>

</body>
</html>

The above, and final, version of our HTML page adds a new if statement after retrieving the result node. Just as we can add new nodes to result, we also can query it to find out if it already has children. When it is first downloaded to the user's browser, the result node has no children. It is empty. So, we can invoke result.childNodes, which returns a list of all children of the result node.

In this case, when we simply want to check to see if any children exist, we invoke the length method on the returned node list. If any number of children exist, we alert the user to the fact that we're not going to add to the message. We will modify the HTML page once, adding our “thanks for clicking” message, but if the user clicks again, JavaScript will detect the existing text node and not make the changes.

______________________

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState