A346 - User Interface Data Validation |
Modified: |
Users often make mistakes. Before acting on user inputs, the interface must verify the inputs are valid. When possible, the interface should limit the possibility for mistakes. One approach is to provide limited choices through selection lists. Providing a list of states to choose from is more limiting but more accurate than having the user type in a state name.
Whenever possible the interface should detect input mistakes. Mistakes should be automatically corrected when feasible. At a minimum, the user must be notified and given feedback.
Unrestricted user input, such as typed text, must be carefully scrutinized for errors. For example, numerical input should be verified to be a number in a reasonable range of values.
The following examines some basic techniques for validating user input on the client-side using JavaScript.
First a short review of client programming.
The following example limits the possible user inputs to one, clicking the input button, which generates an event, executing the function that doubles the value on the button.
<SCRIPT LANGUAGE="JavaScript">
function double(n) {
n.value = n.value * 2;
}
</SCRIPT>
<FORM NAME="doubleForm">
<INPUT NAME="doubleButton"
TYPE="BUTTON"
VALUE="1"
onClick="double(document.doubleForm.doubleButton);"/>
</FORM>
|
Click to see the script work |
Recall all HTML is structured as a tree following the DOM where document is the tree root. The button has the tree path:
document.doubleForm.doubleButton.value
Passing Objects to Script Functions - Objects can be explicitly accessed by document.doubleForm.doubleButton.value or passed as function parameters. The following passes the button object to function double.
double(document.doubleForm.doubleButton)
The value attribute is then accessed for document.doubleForm.doubleButton.value by n.value.
in.value = n.value * 2;
A clickable input restricts the user to one event, click. Text allows infinite number of choices and potential mistakes.
The following is reliable when the hyperlink is clicked (at least until the number exceeds some large value). The text input allows the user to enter any number or characters. Typing your name and clicking the hyperlink produces a NaN (Not a Number), not useful input.
<SCRIPT LANGUAGE="JavaScript">
function double(n) {
n.value = n.value * 2;
}
</SCRIPT>
<FORM NAME="doubleForm">
<INPUT NAME="doubleText" TYPE="text" VALUE="1"/>
</FORM>
<a href="" onClick="double(document.doubleForm.doubleText); return false;">Double</a>
|
Click the link a few times. Type your name. Click again. |
Text that should be a number can be validated somewhat by applying a number operation and checking if the result is still a number: 4*2 is a number in JavaScript but 4Ray*2 is NaN.
<SCRIPT LANGUAGE="JavaScript">
function double(n) {
if( isNaN(n.value*2) )
n.value = n.value + " Error - Not a Number";
else
n.value = n.value * 2;
}
</SCRIPT>
<FORM NAME="doubleForm">
<INPUT NAME="doubleText" TYPE="text" VALUE="1" SIZE="4"/>
</FORM>
<a href="" onClick="double(document.doubleForm.doubleText); return false;">Double</a>
|
Click the link a few times. Type your name. Click again. |
Exercise 1
|
Detecting errors is Step 1. Attracting the user's attention is Step 2. The message " Error - Not a Number" should gain the user's attention if everything fits in the text box, if the user has typed more than about 20 characters the message is pushed out of sight. Try it.
The <span> tag serves to define the start and end of an element, the element can be empty as below.
The id attribute of the <span> tag defines an object named "oError".
<span id="oError"></span>
The oError.innerHTML changes the HTML between <span> </span>.
oError.innerHTML= "<b> Error - Not a Number</b>";
<SCRIPT LANGUAGE="JavaScript">
function double(n) {
oError.innerHTML = "";
if(isNaN(n.value*2))
oError.innerHTML= "<b>Error - Not a Number</b>";
else
n.value = n.value * 2;
}
</SCRIPT>
<FORM NAME="doubleForm">
<INPUT NAME="doubleText" TYPE="text" VALUE="1"/>
<span id="oError"></span>
</FORM>
<a href="./" onClick="double(document.doubleForm.doubleText); return false;">Double</a>
|
Click the link a few times. Type your name. Click again.
|
Exercise 2
|
Most forms have multiple inputs. For 3 inputs we could manage to extend the previous example. The example below has no error checking.
Forms are represented as an array of inputs. The example has 3 inputs that can be accessed by:
document.doubleForm.doubleText1
or equivalently as an array index by:
document.doubleForm[1]
The example below passes document.doubleForm object to the function double parameter named form so the following is equivalent to the above:
form[1]
<FORM NAME="doubleForm">
<INPUT NAME="doubleText0" TYPE="text" VALUE="1" SIZE="2"/>
<INPUT NAME="doubleText1" TYPE="text" VALUE="1" SIZE="2"/>
<INPUT NAME="doubleText2" TYPE="text" VALUE="1" SIZE="2"/>
</FORM>
<a href="./" onClick="double(document.doubleForm); return false;">Double</a>
<SCRIPT LANGUAGE="JavaScript">
function double(form) {
for(i=0; i<form.length; i++)
form[i].value = form[i].value * 2;
}
</SCRIPT>
|
Click the link a few times. Type your name. Click again.
|
Exercise 3
|
All our example form INPUTs are numbers so we should be able to validate all inputs identically as numbers. Our basic approach is to create an array of <span> objects parallel with the form input objects so that when invalid input is detected, the index of the input in the form is the index to the <span> object used to display a message to the user.
We've created a <span> object for each of 3 INPUTs so that object oError0 corresponds to document.doubleForm[0] etc. The following creates and fills an array of the <span> objects.
var oErrorArray = new Array();
oErrorArray[0]=oError0;
oErrorArray[1]=oError1;
oErrorArray[2]=oError2;
In function double, when an error is detected in form[1] the corresponding object at oErrorArray[1] is changed to the message.
if(isNaN(form[ 1 ].value*2))
oErrorArray[ 1 ].innerHTML= "<b>Error - Not a Number</b>";
<FORM NAME="doubleForm" ID="Form1">
<INPUT NAME="doubleText0" TYPE="text" VALUE="1" SIZE="2" ID="Text1"/>
<span id="oError0"></span>
<INPUT NAME="doubleText1" TYPE="text" VALUE="1" SIZE="2" ID="Text2"/>
<span id="oError1"></span>
<INPUT NAME="doubleText2" TYPE="text" VALUE="1" SIZE="2" ID="Text3"/>
<span id="oError2"></span>
</FORM>
<a href="./" onClick="double(document.doubleForm); return false;">Double</a>
<SCRIPT LANGUAGE="JavaScript">
var oErrorArray = new Array();
oErrorArray[0]=oError0;
oErrorArray[1]=oError1;
oErrorArray[2]=oError2;
function double(form) {
for(i=0; i<form.length; i++) {
oErrorArray[i].innerHTML = "";
if(isNaN(form[i].value*2))
oErrorArray[i].innerHTML= "<b>Error - Not a Number</b>";
else
form[i].value = form[i].value * 2;
}
}
</SCRIPT>
|
Click the link a few times. Type your name. Click again.
|
Exercise 4
|
The previous example does not scale well for large forms because of:
var oErrorArray = new Array();
oErrorArray[0]=oError0;
oErrorArray[1]=oError1;
oErrorArray[2]=oError2;
Rather than typing in the text each array entry, the following generates the appropriate text and uses the eval() function to evaluate.
var oErrorArray = new Array();
for (i=0; i<doubleForm.length;i++)
eval("oErrorArray["+ i +"]=oError"+ i );
For index i=2, the evaluation is:
eval(oErrorArray[2]=oError2 );
<FORM NAME="doubleForm">
<INPUT NAME="doubleText0" TYPE="text" VALUE="1" SIZE="2"/>
<span id="oError0"></span>
<INPUT NAME="doubleText1" TYPE="text" VALUE="1" SIZE="2" />
<span id="oError1"></span>
<INPUT NAME="doubleText2" TYPE="text" VALUE="1" SIZE="2" />
<span id="oError2"></span>
</FORM>
<a href="./" onClick="double(document.doubleForm); return false;">Double</a>
<SCRIPT LANGUAGE="JavaScript">
var oErrorArray = new Array();
for (i=0; i<doubleForm.length;i++)
eval("oErrorArray["+i+"]=oError"+i);
function double(form) {
for(i=0; i<form.length; i++) {
oErrorArray[i].innerHTML = "";
if(isNaN(form[i].value*2))
oErrorArray[i].innerHTML= "<b>Error - Not a Number</b>";
else
form[i].value = form[i].value * 2;
}
}
</SCRIPT>
|
Click the link a few times. Type your name. Click again. Change back to a number. |
Exercise 5
|