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)
    {
    node.removeChild(oldTextNode);
    }
}
}

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);
  node.appendChild(newTextNode);
}

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:

removeText(warning);
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.

______________________

Comments

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

HI
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
thanks
kind regards

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix