Page 14 of 22 - Chapter 14
Validating the User's Details
Our next task is to create the checkout_validate.inc
file we have included in both the personal details page and the credit card info
page.
It contains
four client-side functions, the first of which is numericOnly. This function goes through each
character in a string and checks to see if it's a valid character or not -
as specified
by sValidChars. If it's not valid (i.e. not a
number), the character is removed and when all characters have been checked,
the function returns what's left.
<script language="JavaScript">
// Removes all characters which are not digits
// from a string
function numericOnly(sString)
{
var sNumericOnly = "";
var sValidChars = "1234567890";
for (var iCharPos = 0; iCharPos < sString.length; iCharPos++)
{
if (sValidChars.indexOf(sString.charAt(iCharPos)) != -1)
{
sNumericOnly = sNumericOnly + sString.charAt(iCharPos);
}
}
return sNumericOnly;
}
|
Note that if we didn't have to worry about version 3 browsers, we could make
good use of the version 4 browsers' support for JavaScript 1.2 and replace
the function with the line:
sString = sString.replace(/(\D)+/g,"")
|
Visual Basic developers will recognize the next function we create which
trims all white space - tab, space, and line feed - characters from the beginning
and end of a string. In effect this is the JavaScript equivalent of the VB
trim statement.
Our
trim function works
by looping through from the start of the string checking each character to
see if it's white space or not. If it hits a non-whitespace character it breaks
out of the loop and we have found the start of the valid string. The same
algorithm, but starting from the end of the string, finds the last valid character
at the end of the string.
// Removes all whitespace characters
// from start and end of a string
function trim(sString)
{
sTrimmedString = "";
if (sString != "")
{
var iStart = 0;
var iEnd = sString.length - 1;
var sWhitespace = " \t\f\n\r\v";
while (sWhitespace.indexOf(sString.charAt(iStart)) != -1)
{
iStart++;
if (iStart > iEnd)
break;
}
// If the string not just whitespace
if (iStart <= iEnd)
{
while (sWhitespace.indexOf(sString.charAt(iEnd)) != -1)
iEnd--;
sTrimmedString = sString.substring(iStart,++iEnd);
}
}
return sTrimmedString;
}
|
Again, using regular expressions and the string object's method, the whole
function could be achieved in two lines.
|
sString = sString.replace(/^[\s]+/g,"");
sString = sString.replace(/[\s]+$/g,"");
|
Our third function ensures that the user has completed all the form elements.
It loops through each element in the Form.Elements[]
collection, which can be abbreviated to Form[],
and if it's an text or radio
element, it checks it has a value. For radio button groups we need to loop though
each radio button in the group and check to see if one has been selected. The
naming convention I have used for radio buttons is to prefix the name with rad. To let the user know which element
has failed validation the name of the radio button can be used with the rad prefix removed to make it more readable.
// Checks all text boxes and radio button groups
// have a VALUE entered
function checkCompleted(theForm)
{
var bRadioChecked;
var sElementGroupName;
var theElement;
// loop through all elements on form
for (var iElement = 0; iElement < theForm.length;iElement++)
{
theElement = theForm[iElement];
// <INPUT TYPE="TEXT">
if (theElement.TYPE == "text")
{
if (trim(theElement.VALUE) == "")
{
alert("You must complete all the form details");
theElement.focus();
theElement.select();
return false;
}
}
// <INPUT TYPE="RADIO">
else if (theElement.TYPE == "radio")
{
bRadioChecked = false;
sElementGroupName = theElement.NAME;
// all radio buttons in a group have the same NAME
// so loop through all radio elements with same NAME
// until one true or last one reached
while (theElement.NAME == sElementGroupName)
{
if (theElement.checked == true)
{
bRadioChecked = true;
}
iElement++;
theElement = theForm[iElement];
}
if (bRadioChecked == false)
{
// radio button names in form radCreditCard
// so just cut off first 3 characters
alert("Please select your " +
sElementGroupName.substring(3,sElementGroupName.length));
return false;
}
iElement--;
}
}
return true;
}
|
The final validation routine checks our cboExpMonth and cboExpYear
select elements that make up the card expiry date to see that
the card date has not already expired. However, we encounter a problem here
in that the values returned by the Date object in JavaScript
are particularly platform and browser dependent - some browsers return 99 as the year, others the full 4 digits
1999. Here we get round the problem
by assuming the year 2000 if the value returned by the getYear()
method is 0 or by simply adding 1900 if it's another value below 1900. Note
that if we were using JavaScript 1.3 (IE5, NC4.06+) or JScript5, the getFullYear() method of the Date object would
solve this problem.