At the Forge - JavaScript, Forms and Ajax

Dynamic user detection and registration made easy via Ajax.

This is the way that most client-side Web programs are structured. JavaScript functions do the actual work, but they are invoked by event handlers defined in the HTML. So, in Listing 3, we see:

<p>Username: <input type="text" name="username"
    onchange="checkUsername()" /></p>

This tells the browser that when the username text field changes, it should invoke the checkUsername() function. When this function is executed, it begins with the following:

var new_username = document.forms[0].username.value;

The new_username variable gets the value of the username text field. We do this by starting off with the document object (representing our HTML document), then taking the first element of its forms array (representing the first, and only, form in the document). The username property of the form gives us the node for the username text field, whose value we can then retrieve (as a string) with the value property.

Traversing the tree in this way is typical when working with JavaScript. However, it is also possible to jump immediately to a particular form element, assuming that element has been assigned an id attribute. IDs must be unique within a document, meaning that we can find a node with the appropriate method:

var warning = document.getElementById("warning");
var submit_button = document.getElementById("submit-button");

Each of the above two lines uses document.getElementById to retrieve a node from the document tree, identified with an id attribute. (If nothing matches, the variable is set to the null value.)

The list of user names has been hard-coded in Listing 3, which is something you would never try in an actual application. I discuss this further below, and we will find production-quality, Ajax-style solutions next month.

Dynamically Modifying the Page

Now that we have a list of user names in JavaScript, we want to force the user to choose a user name that does not clash with one already in use. We will do this by checking the proposed user name against the list that we have already collected. If the user name is already taken, we will warn the user by modifying the HTML of the current page and then by disabling the submit button. Only when the chosen user name is new and unique will the user be allowed to submit it to the server. This doesn't mean we will remove our uniqueness checks on the server or in the database, but it offloads some of that checking to the client and makes the application more immediately responsive to the user's needs.

We do this by iterating over usernames, the array containing user names:

for (i=0 ; i<usernames.length; i++)
    if (usernames[i] == new_username)
        found = true;

If we find a match between the user's requested new user name and one in the array, then we set the found variable to be true. Otherwise, it continues to be set to false. This then tells us whether we need to warn the user about a conflict and disable the submit button or vice versa.

Warning the user consists of two steps. The first involves setting the warning text—that is, the text inside of the <p> tags above the form—to an appropriate message. We already set the variable warning to point to that node at the beginning of the checkUsername function, which means that we now must eliminate all children of the warning node. Actually, we don't want to eliminate all children, but merely the ones with a nodeValue property, because that is where text is stored. The removeText function does that by iterating over each of a node's children, checking to see if it contains text and removing it if it does:

if (node.childNodes)
for (var i=0 ; i < node.childNodes.length ; i++)
    var oldTextNode = node.childNodes[i];
    if (oldTextNode.nodeValue != null)

Once we have removed text children from the warning node, we then can add a new text child to the warning node, containing the message we want to display. This is done in the appendText function:

function appendText(node, text) {
  var newTextNode = document.createTextNode(text);

As of this point, the user has received a warning about the chosen user name, indicating that it will not be accepted because the user name was already taken. However, we cannot rely on users to read and follow the instructions in a warning message. Rather, we should disable the form's submit button, making it difficult for users even to send the bad user name to our server-side program. We can do this by setting the submit button's disabled property:

submit_button.disabled = true;

To recap—when the user enters a value in the username text field that is in the usernames array, we remove any existing text children from the warning node. We then add a new text child node to warning, indicating that the chosen user name already has been taken. Finally, we disable the submit button in the HTML form.

Of course, we want the user to submit the form eventually, but only after entering a user name not in the usernames array. This means we must remove text children from the warning node, and then re-enable the submit button:

submit_button.disabled = false;

Sure enough, this combination of JavaScript functions seems to do the trick. User names that are not in the usernames array remove any error messages and re-activate the form, allowing us to submit it to the server-side CGI program and register with the site. User names that are in the array, however, produce a warning and stop us from being able to submit the form. It's not Ajax just yet, but it is more responsive to the user than our pure server-side solution.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

is that can do for mysql and for long title of artiles

seodigger's picture

this is very good post
but i wonder you can help for the one wwork with mysql and
special in case of record have long title
eg: when some one posting articles the Ajax will check for its title ( may be long ) and find in data, is some realy similar articles exiting with that title .. so poster do not make double post ..
if have any solution please pm mail me yahoo binhaus
kind regards

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