Any time a user submits a form on a web site, you need to validate that data. Validation can be done in two places: on the client's browser, or on the web server.
Client-side validation is mostly just a convenience for the web user. Rather than wait for a form to be submitted and a new page loaded, the user gets immediate feedback and has a chance to correct any errors before the page is submitted.
The problem I ran into was, how do I know that the validation is being performed identically on both the client and server?
First I defined a few simple helper functions:
getdigits. This returns a string with everything but the
VBScriptfunction getdigits (s) dim re set re = new regexp re.pattern = "[^\d]" re.global = true getdigits = re.replace (s, "") set re = nothing end function
luhn. This is the luhn
checksum algorithm, used to validate such things as credit card numbers and
bank routing numbers.
VBScriptfunction luhn (cc) dim sum, i sum = 0 for i = len (cc) - 1 to 1 step -2 sum = sum + array (0, 2, 4, 6, 8, 1, 3, 5, 7, 9) (cint (mid (cc, i, 1))) next for i = len (cc) to 1 step -2 sum = sum + cint (mid (cc, i, 1)) next luhn = (sum mod 10 = 0) end function
Support for regular expressions under VBScript is terrible, so I made a
validateRE helper function.
VBScriptfunction validateRE (s, regex) dim re set re = new regexp re.pattern = regex re.ignorecase = true validatere = re.test (s) set re = nothing End Function
Most of the actual work is done with regular expressions.
var isNonblank_re = /\S/; var isWhole_re = /^\s*\d+\s*$/; var isInteger_re = /^\s*(\+|-)?\d+\s*$/; var isDecimal_re = /^\s*(\+|-)?((\d+(\.\d+)?)|(\.\d+))\s*$/; var isCurrency_re = /^\s*(\+|-)?((\d+(\.\d\d)?)|(\.\d\d))\s*$/; var isEmail_re = /^\s*[\w\-\+_]+(\.[\w\-\+_]+)*\@[\w\-\+_]+\.[\w\-\+_]+(\.[\w\-\+_]+)*\s*$/;
isNonblank. This just checks that the input string isn't
isWhole checks that an input string is a whole number
isInteger checks that an input string is an integer, with
an optional +/- sign character.
isDecimal checks that an input string is a decimal number,
with an optional +/- sign character.
isCurrency works just like
that only zero or two digits are allowed after the decimal point
isEmail checks that an input string looks like a valid
email address. I've seen many, many different examples of email address
validation, including huge unreadable thousand-character regular
expressions. Some do as little as just checking for the @ symbol,
others try to verify the top-level domain (.com, .org), etc. Frankly, I
don't see the point. No matter how strict your validation is, some
joker can invent an email address that bypasses it. The best you can do
is check for obvious typos.
Having defined the helper functions and the regular expressions, most of the actual validation functions are trivial one-liners:
VBScriptfunction isNonblank (s) isNonblank = validateRE (s, isNonblank_re) end function
A few are a bit more complicated...
isValidCC validates a credit card number. Well, it makes
sure something looks like a valid credit card number anyhow. It
doesn't force the user to use any particular format and just ignores
anything that isn't a digit. (I've seen credit card forms where you had
to enter the entire number in a specific format, or without any spaces.
Those programmers were idiots.
isValidCC is table-driven, making it easy to add or remove
cards depending on what the vendor accepts on his site.
function isValidABA (routingNumber) verifies that a string
looks like a valid American Banking Association routing number.
Note that all of these functions ignore leading and trailing spaces. Why? Because someone entering data into a form won't necessarily see those spaces, and won't understand why his perfectly reasonable data is being rejected. You just need to be sure to trim off the spaces after the validation is done.
Okay, now I have all these little functions. How do I know they work identically in both languages?
VBScript validation functions. (rename to .asp)
Test program. (rename to .asp)
You'll need an IIS server to run the VBScript files of course.