YUI Unobstrusive Javascript Validation

Ever since I started creating web forms, I have been implementing some sort of javascript validation. This often involved a fair bit of javascript attached to the onsubmit events of the forms. I was even using a Dreamweaver extension that did this for me!

I’ve since been shown the light, and tried some other javascript validation. One package gave me the idea for creating a method of providing validation using Class names on form elements, no messy javascript. Another package showed me more in depth how to accomplish it. But it was based on the Prototype library, and I would have to include that to my scripts (which is fairly large for such a simple task).

So I wanted to write my own. I wanted to apply class names to inputs, textareas, selects, checkboxes and radios and have the form validated without any javascript written into the html at all.

Just as a bit of technical stuff here, it was easy enough to add a listener to the form submissions, but not easy to stop the default action (ie, return false) to the form this way. A forum gave me advice to use the YUI library with it’s event handling to stop the event. And it works, yay! So I guess I too have a package to accompany my script, but the two files required are very small compared to the Protoype script.

How to use

It’s simple enough. In your page, reference the YUI library and event scripts (v0.12 are included in the package for you). Also reference the jsvalidation.js file, which will perform the checking.

Next, create your form. Try to be XHTML compliant, for all of us! Now depending on the type of form elemen you create:

  • text, password and textareas
    Add these classes to the element. You can add more than one class to an element, seperating them with a space. Don’t add two contradicting validations though.

    • required – Will make this field required. Reccomended to use with other classes too.
    • validate-number – Field contents must be a number
    • validate-digits – Field contents must be digits, but spaces are also allowed
    • validate-alpha – Field contents must be alphabetical characters only
    • validate-alphanum – Field contents can be alphbetical and numerical, no punctuation
    • validate-date – A valid javascript date value
    • validate-email – Field must be an email address
    • validate-url – Field must be a URL (including the http://)
    • validate-date-au – A valid date formatted as dd/mm/yyyy
    • validate-currency-dollar – A valid dollar value
  • select elements
    Add these classes to the select element. You can add both if you like.

    • validate-not-first – Make the user choose an option that is not the first on the list
    • validate-not-empty – Make the user choose an option that has a value that is not null
  • radio and checkboxes
    Add this class to only one of the options in a group of radio inputs or checkbox inputs.

    • validate-one-required – At least one checkbox/radio element must be selected in a group

Error messages are defined by adding the title attribute to the same element as the class name with validation. If no title has been specified for any of the failed elements, a friendly message will appear to hide your lazyness.

After validation

The script will check the form elements for valid entries, and apply an additional class name to the elements depending on the success or failure of the validation. For example:

  • text, textarea, password: Adds validation-passed on success, and validation-failed on failure
  • select elements: Adds validation-passed-sel on success, and validation-failed-sel on failure
  • radio and checkboxes: Adds validation-passed-cr on success, and validation-failed-cr on failure

The reason I created different classes for the types of elements is for the flexibility of the designer. You may want a red background for a failed text element, but not for a failed select element.

Also, a messagebox will be displayed with a list of defined error messages, or a simple message if no specific error messages were defined.

Features of the script

In addition to just form validation, this script is intuitive. It will not try to validate hidden fields, or even fields that are not clearly visible to the user (hidden by CSS properties).

I’ve also added a minimum length option to text, textarea and password fields. Similar to the maxlength attribute, you can insert a minlength=”x” attribute to these inputs.

This script is not a class. But merely functions. There are some dependancy functions it requires that I have written myself, including:

  • addClassName(element,class)
  • removeClassName(element,class)
  • isVisible(element)
  • string trimming functions

If you’re a javascript programmer, you may find these useful. The source is also included with the package.

Download and Preview

Update:
Version 2 has a few fixes and now includes a validate-regex class you can apply. This only applies to text fields, and requires a regex= attribute to be applied to the element.

Another Update:
A Prototype version of this script is now available (and it’s smaller!).

Technorati: yahoo, yui, javascript, validation, unobtrusive

How to make a Slide and Hide with Yahoo YUI

Javascript transitions are becoming more and more popular with the Web 2.0 sites. We simply couldn’t use an Ajax powered site without some sort of visual notifications, and although animation is not absolutely neccessary the sites that do use it stand out from the crowd.

There are quite a few transitions covered in the Yahoo Design Pattern Library but I’m going to show you my way of Sliding and Hiding a div. Unlike the design pattern library, I’m not going to tell you why the effect should be used, but exactly how to create it.

Before we get started, you might want to look at the finished product, so you know what the goal of this is.

Overview of the process

When I wanted tp make this transition for a page of mine, as a programmer I thought about how the div would dissapear:

  • The div would maintain size and hide beneath another div with a higher z-index or
  • The div would decrease in size, height or width depending on the orientation of the transition.

Although hiding the slider div beneath another div might have worked, what would happen if the slider moved off the visible screen area? You’d get those nasty scrollbars in the browser window…

So the second option sounded better. But (yes so many buts) what happens to the content of the div when the height/width shrinks? Yes, it moves with it. The solution for that is a small CSS property: overflow:hidden;

That’s a good start, but it’s still nto perfect. For example, when shrinking the width of a div, the content (in the case of text) would wrap as much as possible before it will overflow. It looks tacky believe me.

I’ve found that you can wrap the sliding div with another div, and set the width of the inner div, while setting overflow:hidden on the outer div. If you didn’t quite catch that, have a look at this diagram:

Slide and Hide Diagram

The outer div compresses to the dimensions specified by the transition, while the inner div overflows because the width is set.

Have a look at the source of the example for CSS and Javascript.

Technorati: yahoo, yui, javascript, css, slide, hide

Ajax Loading Gif Generator

In my never ending quest to find things people have made to save me time, a simple google search for a loading gif found this for me: http://www.ajaxload.info/

This is some seriously neat stuff. I’ll be visiting this site often.

Ajax File Browser has it’s own site

The example that turned into demand now has it’s own site.

ajax.jc21.com is now the home of the latest release and demo, with some FAQs thrown in for good measure.

Never forget a name…

It’s been some time since I’ve actually ‘surfed’ the web aimlessly, but today I Stumbled Upon an article titled: ‘Swap Personal Details with the Information Ring.

This looks cool. Hope it takes off!

How to make a great ‘Go Back’ feature

You may or may not know about the PHP $_SERVER variable, HTTP_REFERER. It is meant to hold the URL of the previously visited page that the user has been to. Also, you may already use this variable in buttons or links to allow the user to “Go Back” to their previous page.

When I mentioned that the variable is meant to hold the data, unfortunately this is not always the case. A number of firewalls and other software stop the HTTP_REFERER header from being sent to the server, making any “Go Back” buttons or links on your site useless if you’re referring to this variable (Kerio Personal Firewall is one such application).

A recent look at my own logs tells me that over 25% of the users who download from this site hide their referring address. If you apply the same percentage to your site, that’s a lot of people who go nowhere when they click “Go Back”.

So what do you do? Save the current page to the $_SESSION array!

“But what a pain! having to do this for every page.”

Luckily for you I agree. So I’ve created a file you can include in your scripts to keep track of the users browsing history – automatically!

The script presents 2 constants to you: GOBACK and HISTORYWASPOSTED. GOBACK holds the URL of the previously visited page, and HISTORYWASPOSTED is either set to True or False depending if the user has reached that referring page by use of a POST form or not. Depending on the structure of your site, you’ll have to decide what the HISTORYWASPOSTED constant can do for you. You may not want a user to go back if they arrived at that page by a form. Your script might break without the right POST vars.

Finally, you can specify the history length at the top of the script.

<?php
//----------------------------------------------------------------
//  History - by JC
//  www.jc21.com
//----------------------------------------------------------------
//  Keeps a track of http referers even for those users that
//  disable referring (by firewall software or whatever).
//
//  Usage:  just include this file at the top of your script.
//  The constant variable GOBACK holds the referring page.
//  If that page was reached by a POST form submission, the constant
//  variable HISTORYWASPOSTED will be True.
//----------------------------------------------------------------
 
//Number of history entries. Change this to your liking.
define('HISTORY_MAX',20);
 
 
//Supress errors incase session has already been started.
@session_start();
// Check if here by post
if (count($_POST) > 0) {
	$_hbp = true;
} else {
	$_hbp = false;
}
// Check if history array exists and create if not.
if (!is_array($_SESSION['_HISTORY'])) {
	$_SESSION['_HISTORY'] = array();
}
//Check if this page is already on top
if ($_SESSION['_HISTORY'][1][0] == $_SERVER['REQUEST_URI'] && !$_SESSION['_HISTORY'][1][1]) {
	//We're going back trough our history!
	//Remove the first element of the array
	array_shift($_SESSION['_HISTORY']);
} elseif ($_SESSION['_HISTORY'][0][0] != $_SERVER['REQUEST_URI'] || ($_SESSION['_HISTORY'][0][0] == $_SERVER['REQUEST_URI'] && $_hbp)) {
	// Set this page as a referer.
	array_unshift($_SESSION['_HISTORY'],array($_SERVER['REQUEST_URI'],$_hbp));
}
//Trim array to x many history entries.
if (count($_SESSION['_HISTORY']) > (HISTORY_MAX+1)) {
	// get number of extras.
	$_e = (count($_SESSION['_HISTORY']) - (HISTORY_MAX+1));
	for ($x=0;$x<$_e;$x++) {
		array_pop($_SESSION['_HISTORY']);
	}
}
// Set GOBACK and HISTORYWASPOSTED
if (isset($_SESSION['_HISTORY'][0])) {
	define('GOBACK',$_SESSION['_HISTORY'][1][0]);
	define('HISTORYWASPOSTED',$_SESSION['_HISTORY'][1][1]);
} else {
	define('GOBACK',false);
	define('HISTORYWASPOSTED',false);
}
// Cleanup vars.
unset($_e,$_hbp);
?>

Download this code: history.inc.php

And here’s how you might use it:

<?php
include('history.inc.php');
?>
 
<p>Hello World</p>
 
<?php
//check if referring page wasn't result of a POST
if (!HISTORYWASPOSTED) {
	?>
	<p><a href="<?php echo GOBACK; ?>">Go Back</a></p>
	<?php
}
?>

Download this code: history_use.php