Home arrow HTML arrow Page 2 - Forms & JavaScript Living Together in Harmony
HTML

Forms & JavaScript Living Together in Harmony


Have you ever created a form-based web page, using JavaScript, that didn't work properly on your browser? If so, this is where Jeff jumps in to help you out with tips on how to use your JavaScript responsively when dealing with forms.

Author Info:
By: Jeff Howden
Rating: 5 stars5 stars5 stars5 stars5 stars / 14
May 06, 2003
TABLE OF CONTENTS:
  1. · Forms & JavaScript Living Together in Harmony
  2. · JavaScripting Problems and Solutions
  3. · Conclusion

print this article
SEARCH DEVARTICLES

Forms & JavaScript Living Together in Harmony - JavaScripting Problems and Solutions
(Page 2 of 3 )

What are some examples of irresponsible use of JavaScript with forms?

Look Ma! No submit button!

The first and most common is the use of a dropdown menu as navigation (See Figure 1 below). Aside from the obvious usability and accessibility concerns inherent in this design faux pas, some developers unnknowingly render the navigation useless to non-JavaScript users by omitting a submit button. Often the argument for not including the submit button is that it uglies the design.

I'd argue that the dropdown menu isn't much prettier, even with lots of css styling applied to it. However, most designers and some developers are vain and would rather sacrifice usability for the sake of "the look". So, non-JavaScript users suffer.


Figure 1: An example of a site that uses dropdown menus as navigation, with no apparent means for non-JavaScript users to get to the same content. You might be thinking the blue square in the top-right of the figure is a submit button. Don't let it fool ya. Just because it's sitting next to a dropdown menu doesn't mean it has anything to do with it. It's actually a link. See what I mean.

<lisp>The submit buttons must be purple and do that faaaabulous image swapping thingy like the navigation!</lisp>

The second is the gratuitous abuse of branding colors and rollovers spilling over in to submit buttons (and all too often the form elements themselves, thanks to CSS). As if graphical submit buttons aren't bad enough, some designers practically demand the graphical submit buttons rollover when the user mouses over them (Figure 2 below is a fine example of this).

Unfortunately, too many developers are stuck using wygiwyd software and/or are unaware of the possibilities available in the latest browsers that don't require neutering the form for non-JavaScript users in order to quell the unrelenting demands of the designer. If they do seek help from other developers in finding a solution, the suggestion is almost always to wrap an image with a link that calls the submit() method. Too bad that's not the solution.

Figure 2: An example of a site that places design element behavior over usability and accessibility. If I don't have JavaScript enabled, I can't submit the form by clicking on the "Submit" button. In Mercedes-Benz USA's favor is that you can still submit the form by pressing the ENTER key on the keyboard when the cursor is in the Zip Code field. See what I mean.

That's not how you validate a form?

There are right ways to perform form validation with JavaScript and then there are wrong ones. All too often, developers implement validation the wrong way. For JavaScript enabled users, the result is the same. However, done the wrong way, non-JavaScript users are left with a form that does absolutely nothing when they click the submit button.

If you read no further, take with you the knowledge that the only ways to properly perform form validation with JavaScript is to use the onsubmit event handler of the <form> tag or the onclick event handler of a non-graphical submit button to call a function that returns a boolean of true or false.

So what's the solution?

The most obvious solution is to not use JavaScript at all. However, that usually negatively impacts a user's experience by forcing a round-trip to the server just to get the form back with error messages indicating required fields they didn't enter data or pattern-matched fields with syntactically invalid data. Besides, this article is about using JavaScript responsibly with forms not about not using JavaScript at all.

Taming the dropdown menu

If you insist on going against evidence that using dropdowns as navigation is a bad idea, at least include a mechanism to make them usable by your non-JavaScript users. If you're at least marginally conscious of usability issues, you'll resign yourself to not using the onchange event handler to change the page. That means you'll likely have some other mechanism like a button or link that finds the user's selection and changes the page to the one they selected. Making this work for non-JavaScript users will require only a small amount of work.

You'll need to change that link or button to a regular submit button. You can even use a graphical submit button if you prefer. Rather than calling the function from the submit button though, you'll need to move the call to the onsubmit event handler so this will work with the most browsers possible (Some browsers <cough>Netscape Navigator 4.x</cough> don't support onclick event handlers on graphical submit buttons).

You'll also need to reference a server-side script in the action attribute that the non-JavaScript users will submit the form to. This server-side script will take the value they selected from the dropdown menu and perform a simple redirect.

See Listing 1 for some example JavaScript illustrating this technique. Listing 2 contains some example ColdFusion code that could be used to facilitate that server-side portion of this solution.

Listing 1 The HTML & JavaScript for the client-side processing

<script language="JavaScript" type="text/javascript">
<!--
function navigateForm(obj)
{
if(obj.selectedIndex != -1 && obj.options[obj.selectedIndex].value)
top.location.href = obj.options[obj.selectedIndex].value;
return false;
}
//-->
</script>
<form action="navigate.cfm" method="post" onsubmit="return navigateForm(this.form.navigateSelect)">
<select name="navigateSelect" id="navigateSelect" size="1">
<option value="">Choose One</option>
<option value="/">Home</option>
<option value="/products/">Products</option>
<option value="/faq/">FAQ</option>
<option value="/about_us/">About Us</option>
<option value="/contact_us/">Contact Us</option>
</select>
<input type="submit" value="Go" />
</form>


Listing 2 The ColdFusion for the server-side processing

<cfparam name="form.navigateSelect" default="/">
<cflocation url="#form.navigateSelect#" addtoken="No">


If you just can't live with the submit button being visible to your JavaScript enabled users, leave some room in the design for it and only show it to non-JavaScript users by wrapping it in a <noscript> tags. See Listing 3 below for an example of the HTML.

Listing 3 Hiding the Submit button from JavaScript-enabled users

<form action="navigate.cfm" method="post" onsubmit="return navigateForm(this.form.navigateSelect)">
<select name="navigateSelect" id="navigateSelect" size="1">
<option value="">Choose One</option>
<option value="/">Home</option>
<option value="/products/">Products</option>
<option value="/faq/">FAQ</option>
<option value="/about_us/">About Us</option>
<option value="/contact_us/">Contact Us</option>
</select>
<noscript>
<input type="submit" value="Go" />
</noscript>
</form>


Note: The <noscript> tags were introduced with JavaScript1.1. Therefore, any browser that doesn't support JavaScript1.1 will ignore the <noscript> tags and attempt to display anything contained within them. As the only browser this really affects is Netscape Navigator 2.x, you're not likely to experience this problem.

{mospagebreak title=Appeasing The Demanding Designer&toc=1}

Provided you're willing and able to make this functionality available for only a portion of your audience, you can give the design what he or she wants without crippling the form for non-JavaScript users. Don't let this notion of some visitors missing out on the foofoo eye-candy stop you from doing the right thing. Though the numbers could vary for your own site, I'm probably talking about 5% or less of your audience not getting the rollover effect the designer is so proud of. However, all of your users, despite their support for JavaScript, should be able to use the form.

Before we charge off into some example code showing how to accomplish this, let's take a look how it's usually accomplished in a manner that makes it unusable for non-JavaScript users. Listing 4 below contains HTML for a very small form.

Listing 4 Snazzy but an obstacle for some

<form action="/login.cfm" name="loginForm" method="post">
<input type="text" name="username" value="" /><br />
<input type="password" name="password" value="" /><br />
<a href="JavaScript:document.loginForm.submit()"
onmouseover="rollOver('loginButton', 'on')"
onmouseout="rollOver('loginButton', 'off')"
><img name="loginButton"
src="images/login_off.gif"
width="88"
height="31"
border="0"
alt="Login"
/></a>
</form>


So how do we remedy this situation so it's usable by all visitors to our site? Simple remove the <a> tag and use an image submit button instead of a regular image. We'll also move the onmouseover and onmouseout event handlers to the image submit. Most (like 95+%) of the browsers that will be visiting your site will support these event handlers on the image submit. Those that don't will simply get a normal, "boring" image submit button. See Listing 5 below to see what the code in Listing 4 looks like after this conversion.

Listing 5 Snazzy and usable too

<form action="/login.cfm" name="loginForm" method="post">
<input type="text" name="username" value="" /><br />
<input type="password" name="password" value="" /><br />
<input type="image"
src="images/login_off.gif"
width="88"
height="31"
border="0"
alt="Login"
onmouseover="rollOver('loginButton', 'on')"
onmouseout="rollOver('loginButton', 'off')">
</form>


"Are you an idiot? Tell me you didn't just put that there." or Validating Form Data

The last one that's so often funked up by irresponsible JavaScripters is form validation. The sad thing is that they mess it up not out of spite, but because they don't understand the right way to do it. The wrong way to do it almost always involves the use of the submit() method. So, what exactly is the right way?

The right way involves building the form and its functionality from start to finish without any JavaScript. Complete all your server-side checking and processing. Then, come back and add your client-side checking to improve the user's experience. It's as simple as adding an onsubmit event handler to your <form> tag.

Since this event is cancellable, we preface our validation function call with a return statement. The validation function will return a boolean value of true or false finishing off this return statement. A return true statement will result in the default behavior the form submitting. Conversely, a return false statement will result in the form submission being aborted. See Listing 6 below for an example of how the function in the onsubmit event handler is called.

Listing 6 How to call your validation function with the onsubmit event handler

<form
action="/login.cfm"
name="loginForm"
method="post"
onsubmit="return validateForm(this)"
>


Note: See my article on event handlers and cancelling events called "JavaScript: The Point of No Return!?" for an overview of these concepts.

Let's take a look at our form validation function validateForm() to see how it works. Before we do though, it'd be a good idea to see the form we'll be working with. For simplicity, we'll be validating a simple login form with username and password fields. See Listing 7 below for the HTML for this login form.

Listing 7 Our Login Form

<form
action="/login.cfm"
name="loginForm"
method="post"
onsubmit="return validateForm(this)"
>
<label for="username"
><u>U</u>sername</label>
<input type="text"
name="username"
id="username"
tabindex="1"
accesskey="u"
value="" /><br />
<label for="password"
><u>P</u>assword</label>
<input type="password"
name="password"
id="password"
tabindex="2"
accesskey="p"
value="" /><br />
<input type="submit"
tabindex="3"
accesskey="l"
value="Login" />
</form>


When the user submits the form our validateForm() function is called (Follow along with the code in Listing 8 below). The function creates a couple of variables local to the function that it'll use for storing the return value (returnValue), the concatenated error message (errorMessage), and which field needs to receive focus if the form doesn't validate (focusField). Then the function checks the username and password fields for values.

If either field is blank, it adds some text to the errorMessage variable, sets the focusField variable to the current field if it hasn't been set yet, and changes the returnValue variable to false. If both fields have values then returnValue keeps its initial value of true. This boolean is then returned to the calling event handler by the return statement on the last line of our function. The event handler uses this boolean value that comes back from the function in combination with the return statement just before the function call and allows submission if the boolean is true or halts submission if it is false.

Listing 8 validateForm()

<script language="JavaScript" type="text/javascript">
<!--
function validateForm(form)
{
var returnValue = true;
var errorMessage = 'The following field(s) are required and do not contain any information:\n\n';
var focusField = null;
if(!form.username.value)
{
errorMessage += ' - Username\n';
if(!focusField)
focusField = form.username;
returnValue = false;
}
if(!form.password.value)
{
errorMessage += ' - Password\n';
if(!focusField)
focusField = form.password;
returnValue = false;
}
if(!returnValue)
{
alert(errorMessage);
if(focusField)
focusField.focus();
}
return returnValue;
}
//-->
</script>


blog comments powered by Disqus
HTML ARTICLES

- Does HTML5 Need a Main Element?
- Revisiting the HTML5 vs. Native Debate
- HTML5: Not for Phone Apps?
- HTML5 or Native?
- Job Hunting? Freelancer.com Lists This Quart...
- HTML5 in the News
- Report: HTML5 Mobile Performance Lags
- The Top HTML5 Audio Players
- Top HTML5 Video Tutorials
- HTML5: Reasons to Learn and Use It
- More of the Top Tutorials for HTML5 Forms
- MobileAppWizard Releases HTML5 App Builder
- HTML5 Boilerplate: Working with jQuery and M...
- HTML5 Boilerplate Introduction
- New API Platform for HTML5

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials