Category: Forms; Keywords: errors
validation
div
style
Users make errors - a fact of life. Just imagine if they were all perfect and never made a mistake. How easy our lives would be. This is never going to happen though is it and in the mean time we need to continue spoon feeding them with helpful advice on how to use our applications. Probably the most common use of error reporting (if not the only) is when users fill out an online form. I have written many articles on this site dealing with data validation and as it plays such a large part in my working day I am forever coming up with new ideas.
My latest idea (prompted by a question from Jonas Pettersson) was a change to the way in which the user is displayed the list of all the errors that they need to address before a form can be submitted. The norm I tend to stick to is that you use a JavaScript prompt to alert the user to an error as and when they each happen. The user then corrects the first error and tries to resubmit. If there are still errors on the form then they get alerted again, and again, and again, until the form has no errors and it can be submitted. A much nicer approach would be to present them with all the errors in one go. Then they can work through them all and only need to try resubmitting the form once.
In trying to do this I came up with quite a few different approaches. Let's stop messing about and get on with an example. Consider the simple form below:
Form Validation Errors
Enter your values in the form below:
First Name:
Surname:
Favourite Browser:
Before entering any data press the Validate button and see what happens. You should see what appears to be a new window pop up with a list of errors in it. At this point I am assuming you are using an up to date browser such as IE5.5 or NN6.
With the "window" in place, try moving it around so that you can get to the fields and make the necessary changes. When you have filled one field, hit the button again and notice the change. Now fill all the fields and hit Validate - the window should disappear.
So how does this work then?
Obviously it is not actually a window* and is only a layer that has been made to look like one. The ins and outs of how to do this can be found on the website of the author of this wonderful piece of DHTML at http://www.brainjar.com. All you really need to worry about is adding a layer to your form and the relevant JavaScript and CSS files.
First let's add links to the files we need. You can download them from the left hand column of this page. Place the contents of these files somewhere in your database that you can reference them - personally I would add them to Pages with the same name as the files that are treated as HTML - then you can add the following lines to your HTML Head Contents:
"<script type=\"text/javascript\" src="/" + DBPath + "/popupWins.js"></script>" + @NewLine +
"<link rel=\"stylesheet\" href=\"/" + DBPath + "/popupWins.css\" type=\"text/css\">"
These are all that are required to control and format the "window" layer. We now need to add the framework of the layer by adding the following Pass-Thru HTML to you form somewhere:
<div id="ErrorLayer" class="window" style="left:150px;top:150px;width:300px;">
<div class="titleBar"> <span class="titleBarText">Form Validation Errors</span>
<img class="titleBarButtons" alt="" hidefocus=true src="/path/to/database.nsf/buttons.gif" usemap="#sampleMap1">
<map name="sampleMap1">
<area shape="rect" coords="0,0,13,13" href="" alt="" title="Minimize" onclick="this.parentWindow.minimize();return false;">
<area shape="rect" coords="14,0,27,13" href="" alt="" title="Restore" onclick="this.parentWindow.restore();return false;">
<area shape="rect" coords="28,0,41,13" href="" alt="" title="Close" onclick="this.parentWindow.close();return false;">
</map>
</div>
<div id="ErrorContainer" class="clientArea" style="height:200px;">
<!-- This is where errors are displayed// -->
</div>
</div>
This layer is hidden by the stylesheet when you first open the form. It gets displayed by the JavaScript function that is used to validate the form. It's in this function that we build the error list and place it in the layer shown above. Let's see what the JavaScript looks like. It's worth reading this carefully and understanding the logic as this is the idea I am trying to explain:
function validate( frm )
{
//this Array will hold Field Object, Field Label, Error Message Help
var valErrors = new Array();
with ( frm )
{
if (Firstname.value == "")
valErrors[valErrors.length] = [Firstname, 'First Name', 'You need to enter a text entry here'];
if (Surname.value == "")
valErrors[valErrors.length] = [Surname, 'Surname', 'You need to enter a text entry here'];
if (FaveBrowser.selectedIndex == 0)
valErrors[valErrors.length] = [FaveBrowser, 'Favourite Browser', 'You need to make a selection here'];
}///end with;
//build the string of errors
var str = ""; var err = ""; var msg = ""; var lnk = "";
var srt = "";
//Add the errors to the Layer's HTML
if (valErrors.length > 0)
{
document.getElementById('ErrorContainer').innerHTML = (srt + str);
if (winList['ErrorLayer']) winList['ErrorLayer'].open(); return false;
}
else
{
document.getElementById('ErrorContainer').innerHTML = "No errors";
if (winList['ErrorLayer']) winList['ErrorLayer'].close(); return false;
}///end if
}///end function;
The difference between this code and the normal validation logic is that, when an error in encountered, information is stored in an array. When all validations are complete this array is looped through to build a string of HTML that the function then sets as the content of the "Error Layer". Once it has placed the HTML in to the layer it calls the winList procedure to display the error "window". If there are no errors then the window is closed.
Things to consider:
Obviously this is not the perfect solution. For a start it will only work with the most up to date, standards compliant browsers. Also, you may have noticed that, the source file for the required JavaScript to generate the "windows" is 16KB - a lot to download every time you and your users open a form. OK on an Intranet but none too great for the Internet.
As an alternative, a better idea would be to use a simple fixed layer that lacks the ability to be moved or resized. In this case all you need is the following HTML on your form:
<div id="ErrorLayer" style="position:absolute; width:400px; height:120px; z-index:1; left: 450px; top: 200px">
<p> </p>
</div>
Then in the last few lines of the validation JavaScript we simplify it to the following:
//Add the errors to the Layer's HTML
if (valErrors.length > 0){
document.all.ErrorLayer.innerHTML = str;
} else {
document.all.ErrorLayer.innerHTML = "No errors";
}
* We could use a true popup window but this will probably end up being left around on the users PC and they wouldn't be able to reference the list without switching to and fro while they complete the form. If you want to use a pop-up window here is the JavaScript to use:
//Launch a new window to show the errors
if (valErrors.length > 0){
var win = window.open('',null,'menubar=no,width=250,height=150');
win.document.writeln('<html>');
win.document.writeln('<body>');
win.document.writeln(str);
win.document.writeln('</body>');
win.document.writeln('</html>');
}