The Gravey Framework and RATS RIA

grvValidate.js

Summary

Collection of routines to validate data form fields

Version: 2.0

Author: Bruce Wallace (PolyGlotInc.com)


Method Summary
static Object grvAbstractException( funcName )
           return the formatted message for a calling-abstract-method exception
static String grvAsBoolStr(flag)
           Generate string representation of given boolean value
static void grvASSERT(condition,msg)
           throw an exception if given condition is not true
static boolean grvBoolValue(s)
           Evaluate boolean string value
static Object grvBreak(msg)
           output the given message and ask user if they wish to break
static void grvBreakpoint()
           cause the debugger to stop (ala a breakpoint)
static String grvDateParseErrorMsg(dateStr)
           Verify that given string contains a date.
static void grvDebugWindow( <String> contents )
           open debug window with contents in scrollable area
static void grvError(msg)
           output the given error message and ask user if they wish to break
static String grvFilterNum( str )
           remove dollar formatting characters from given string
static boolean grvIsAlpha(s)
           Verify that all characters in given string are alpha chars.
static boolean grvIsAlphaBlank(s)
           Verify that all characters in given string are alpha or blank chars.
static boolean grvIsAlphaNum(s)
           Verify that all characters in given string are alphanumeric chars.
static boolean grvIsDigit(c)
           Verify that given character is a digit (0 ..
static boolean grvIsEmpty(x)
           Verify that given string is "empty".
static boolean grvIsFalse(s)
           Verify that given string equates to "false".
static boolean grvIsFloat(s)
           Verify given string represents a float.
static boolean grvIsIntDelimInt(s,delim)
           Verify that given string is a delimited integer
static boolean grvIsInteger(s)
           Verify that given string contains an integer.
static boolean grvIsLetter(c)
           Verify that given character is an English letter (A ..
static boolean grvIsPhoneNum(s)
           Verify given string is a phone number.
static boolean grvIsSelected(s)
           Verify that given string explicitly equates to "true".
static boolean grvIsSignedFloat(s)
           Verify that given string contains a signed or unsigned floating point (real) number.
static boolean grvIsTrue(s)
           Verify that given string equates to "true".
static boolean grvIsUndefined(<anyType> x)
           Perform a robust test for JavaScript "undefined" using the wisdom at Dont Assume Undefined is Undefined.
static boolean grvIsZipCode(s)
           Verify that the given string is a zip code
static void grvLoudThrow( exceptionObj )
           throw an exception but first give user a chance to "break"
static Object grvMissingArgException( argDesc, funcName )
           return the formatted message for a missing-argument exception
static void grvMustOverride( funcName )
           throw an exception because given function is abstract
static void grvNotImplemented( what )
           throw an exception because given functionality is unimplemented
static Object grvNotImplementedException( what )
           return the formatted message for a not-implemented exception
static Object grvTooFewArgsException( funcName, required, passed )
           return the formatted message for a too-few-arguments exception
static String grvTrimStr(sInString)
           Strip leading and trailing whitespace from given string
static void grvValidateArgs( callerName, <StringArray> argDescArray, callersArgs )
           generic utility function to verify that required args (of the caller of this function) have been passed; The given array of descriptions defines how many arguments should be found with a defined value; Therefore, the caller of this routine should place its optional arguments at the end of its parameter list with no description specified in "optArgDescArray".
static void grvValidateDate( fieldName )
           validate date value of form field with given element ID
static void grvValidateDollar( fieldName )
           validate dollar value of form field with given element ID
static void grvValidateFloat( fieldName )
           validate float value of form field with given element ID
static void grvValidateInteger( fieldName )
           validate integer value of form field with given element ID
static void grvWarnInvalid(<element> theField, <String> s)
           Notify user that contents of field theField are invalid.

// This file uses JSDoc-friendly comments [ http://jsdoc.sourceforge.net/ ]

/**
 * @file         grvValidate.js
 * @fileoverview Collection of routines to validate data form fields
 * @author       Bruce Wallace  (PolyGlotInc.com)
 * @version      2.0
 */

//////////////////////////////////////////////////////////////////
// GRAVEY LEXICAL CODING CONVENTIONS:
// (*) All private variables or functions start with "_"
// (*) All variables and functions start with a lowercase letter
// (*) All Classes start with an uppercase letter
// (*) All Class methods and instance variables start with lowercase
// (*) All Class "static" methods and variables start with uppercase
// (*) All constants start with "k"
// (*) All global variables start with "g"
// (*) All event handler functions start with "on"
//
// (*) All Gravey utility global variables start with "gGrv"
// (*) All Gravey MVC     global variables start with "gMVC"
// (*) All Gravey EDO     global variables start with "gEDO"
// (*) All Gravey utility functions start with "grv"
// (*) All Gravey MVC     functions start with "mvc"
// (*) All Gravey MVC event handler functions start with "onMVC"
// (*) All Gravey EDO event handler functions start with "onEDO"
// (*) All Gravey MVC classes start with "MVC"
// (*) All Gravey EDO classes start with "EDO"
//////////////////////////////////////////////////////////////////

/** Strip leading and trailing whitespace from given string @type String */
function grvTrimStr(sInString) {
  sInString = sInString.replace( /^\s+/g, "" );// strip leading
  return sInString.replace( /\s+$/g, "" );// strip trailing
}

/**
 * Perform a robust test for JavaScript "undefined" using the wisdom
 * at <a target="_blank" 
 * href="http://pt.withy.org/ptalk/archives/2005/06/dont_assume_undefined_is_undefined.html">
 * Dont Assume Undefined is Undefined</a>.
 * @param {anyType} x variable to check for undefinedness
 * @return true iff x is undefined (as opposed to merely null)
 * @type boolean
 */
function grvIsUndefined(x) {
	 return x === void 0;
}

/** Verify that given string is "empty". @type boolean */
function grvIsEmpty(x)
{
	if (x==null) return true;
	var s = ""+x; //force to string
	if (s.length==0) return true;
	s = grvTrimStr(s);
	return (s.length==0);
}

/** Evaluate boolean string value
 * @return boolean value or null if not boolean
 * @type boolean
 */
function grvBoolValue(s)
{
	s = ""+s;//force to string
	if (grvIsTrue (s)) return true;
	if (grvIsFalse(s)) return false;
	return null;
}

/** Generate string representation of given boolean value
 * @return boolean value or null if not boolean
 * @type String
 */ 
function grvAsBoolStr(flag)
{
	if (flag==true ) return "true";
	if (flag==false) return "false";
	return null;
}

/** Verify that given string explicitly equates to "true". @type boolean */
function grvIsSelected(s)
{
	return grvIsEmpty(s) ? false : grvIsTrue(s);
}

/** Verify that given string equates to "true". @type boolean */
function grvIsTrue(s)
{
	var x = s.toLowerCase();
	return x=="y" || x=="yes" || x=="true" || x=="1";
}

/** Verify that given string equates to "false". @type boolean */
function grvIsFalse(s)
{
	var x = s.toLowerCase();
	return x=="n" || x=="no" || x=="false" || x=="0";
}

/** Verify that given character is an English letter (A .. Z, a..z). @type boolean */
function grvIsLetter(c)
{   return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) ); }

/** Verify that given character is a digit (0 .. 9). @type boolean */
function grvIsDigit(c)
{	return (c >= "0") && (c <= "9");	}

/** Verify that all characters in given string are alpha chars. @type boolean */
function grvIsAlpha(s)
{
	if (grvIsEmpty(s)) return true;
    for (var i=0; i<s.length; ++i) 
        if (!grvIsLetter(s.charAt(i))) return false;

    return true;
}

/** Verify that all characters in given string are alpha or blank chars. @type boolean */
function grvIsAlphaBlank(s)
{
	if (grvIsEmpty(s)) return true;
	var c;
    for (var i=0; i<s.length; ++i){
    	c = s.charAt(i);
        if (c!=' ' && !grvIsLetter(c)) return false;
    }

    return true;
}


/** Verify that all characters in given string are alphanumeric chars. @type boolean */
function grvIsAlphaNum(s)
{
	if (grvIsEmpty(s)) return true;
	var c = '';
    for (var i=0; i<s.length; ++i)
    {
    	c = s.charAt(i);
        if (!grvIsLetter(c) && !grvIsDigit(c)) return false;
    }

    return true;
}


/** Verify that given string contains an integer.
 * Accepts non-signed integers only. Does not accept floating 
 * point, exponential notation, etc.
 * We don't use parseInt because that would accept a string
 * with trailing non-numeric characters.
 * @return true if all characters in string s are numbers 
 * @type boolean
 */
function grvIsInteger(s)
{
	if (grvIsEmpty(s)) return true;
    for (var i=0; i<s.length; ++i)  
        if (!grvIsDigit(s.charAt(i))) return false;

    return true;
}

/** Verify that given string is a delimited integer
 * @return True iff string s is <int><delim><int>
 * @type boolean
 */
function grvIsIntDelimInt(s,delim)
{
	s = ""+s;//force to string
	if (grvIsEmpty(s)) return true;
    var seenDelim = false;
    if (s == delim) return false;
	var c = '';
    for (var i=0; i<s.length; ++i)
    {
        c = s.charAt(i);
        if ((c == delim) && !seenDelim) seenDelim = true;
        else if (!grvIsDigit(c)) return false;
    }
    return true;
}

/** Verify that the given string is a zip code
 * @return True iff string s is <int><optional-dash-then-int>.
 * @type boolean
 */
function grvIsZipCode(s){ return grvIsIntDelimInt(s,"-"); }

/** 
 * Verify given string represents a float. Does not accept exponential notation.
 * @return True if string s is an unsigned floating point (real) number. 
 * @type boolean
 */
function grvIsFloat(s){ return grvIsIntDelimInt(s,"."); }

/** Verify given string is a phone number.
 * @return True if string s only has <digits><space>x()-# chars.
 * @type boolean
 */
function grvIsPhoneNum(s)
{
	if (grvIsEmpty(s)) return true;
	var c = '';
    for (var i=0; i<s.length; ++i)
    {
    	c = s.charAt(i);
        if (!grvIsDigit(c)
         && c!='x' && c!=' ' && c!='#' && c!='-' && c!='(' && c!=')')
          return false;
    }
    return true;
}

/** Verify that given string contains a signed or unsigned
 * floating point (real) number. First character is allowed
 * to be + or -. Does not accept exponential notation.
 * @return true iff string contains a "real" number. 
 * @type boolean
 */
function grvIsSignedFloat(s)
{
	s = ""+s;//force to string
	if (grvIsEmpty(s)) return true;
	var startPos = 0;
	// skip leading + or -
	if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") ) startPos = 1;    
	return (grvIsFloat(s.substring(startPos, s.length)));
}

/** Verify that given string contains a date.
 * @return error message on invalid date or null if valid
 * @type String
 */
function grvDateParseErrorMsg(dateStr)
{
  if (grvIsEmpty(dateStr)) return null;

  var datePat    = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
  var matchArray = dateStr.match(datePat); // is format OK?

  if (matchArray == null)
    return "Please enter date as either mm/dd/yyyy or mm-dd-yyyy.";

  // parse date into variables
  month = matchArray[1];
  day   = matchArray[3];
  year  = matchArray[5];

  if (month < 1 || month > 12)
    return("Month must be between 1 and 12.");

  if (day < 1 || day > 31)
    return("Day must be between 1 and 31.");

  if ((month==4 || month==6 || month==9 || month==11) && day==31)
    return("Month " + month + " doesn't have 31 days!");

  if (month == 2) { // check for february 29th
    var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
    if (day > 29 || (day==29 && !isleap))
      return("February " + year + " doesn't have " + day + " days!");
  }
  return null;  // date is valid
}

/** remove dollar formatting characters from given string
 * @return filtered version of numeric string
 * @type String
 */
function grvFilterNum( str ) {
	var re = /\$|,/g; // remove "$" and ","
	return str.replace(re, "");
}

/** Notify user that contents of field theField are invalid.
 * @param {element} theField HTML element containing form field
 * @param {String} s describes expected contents of theField.value.
 */
function grvWarnInvalid(theField, s)
{
	if (grvIsEmpty(s)) return;
	theField.focus();
    theField.select();
    alert(s);
}

/** validate dollar value of form field with given element ID */
function grvValidateDollar( fieldName )
{
	var field = document.getElementById( fieldName );
    field.value = filterNum(field.value);
    if (!grvIsSignedFloat(field.value))
	  grvWarnInvalid( field, "Please enter a valid dollar amount" );
}

/** validate integer value of form field with given element ID */
function grvValidateInteger( fieldName )
{
	var field = document.getElementById( fieldName );
    field.value = filterNum(field.value);
    if (!grvIsInteger(field.value))
	  grvWarnInvalid( field, "Please enter a valid integer" );
}

/** validate float value of form field with given element ID */
function grvValidateFloat( fieldName )
{
	var field = document.getElementById( fieldName );
    //field.value = filterNum(field.value);
    if (!grvIsSignedFloat(field.value))
	  grvWarnInvalid( field, "Please enter a valid number" );
}

/** validate date value of form field with given element ID */
function grvValidateDate( fieldName )
{
	var field = document.getElementById( fieldName );
    grvWarnInvalid( field, grvDateParseErrorMsg(field.value) );
}

// ----------------------------------------------------------------------------
// Utility routines to support param validations, exceptions, and debugging
// ----------------------------------------------------------------------------

/**
 * open debug window with contents in scrollable area
 * @param {String} contents what to put into this debug window
 */
function grvDebugWindow( contents )
{
    window.open().document.write
    	("<textarea cols=150 rows=40>"+ contents + "</textarea>" );
}

/** cause the debugger to stop (ala a breakpoint) */
function grvBreakpoint()
{
	//open window with current dynamic HTML displayed
	grvDebugWindow( document.body.parentNode.innerHTML );
	//cause Javascript debugger to kick in on undefined object reference
	//OR, comment out the next line and pre-set a breakpoint here via debugger
    UNDEFINED();
}

/** output the given message and ask user if they wish to break
 * @return true iff not "break"ing
 */
function grvBreak(msg)
{
	if (msg.length>200) { grvDebugWindow( msg ); msg="(see window)"; }
	if (confirm(msg+"\nBreak here?")) grvBreakpoint(); else return true;
}

/** output the given error message and ask user if they wish to break */
function grvError(msg){
 if (grvBreak("ERROR:"+msg))
 	alert("It is recommended that you close this window and try again.");
}

/** throw an exception if given condition is not true */
function grvASSERT(condition,msg){
	if (condition) return;
	grvError(msg);
	throw msg;
}

/** throw an exception but first give user a chance to "break" */
function grvLoudThrow( exceptionObj ) {
	grvBreak(exceptionObj);
	throw exceptionObj;
}
/** return the formatted message for a missing-argument exception @String */
function grvMissingArgException( argDesc, funcName ) {
	return "Error: "+argDesc+" wasnt passed to "+funcName;
}
/** return the formatted message for a too-few-arguments exception @String */
function grvTooFewArgsException( funcName, required, passed ) {
	return funcName + " requires "+ required +" arguments, but was passed " + passed;
}
/** return the formatted message for a calling-abstract-method exception @String */
function grvAbstractException( funcName ) {
	return "Abstract "+ funcName + " was called but never overridden!";
}
/** return the formatted message for a not-implemented exception @String */
function grvNotImplementedException( what ) {
	return what + " is not implemented yet!";
}
/** throw an exception because given function is abstract */
function grvMustOverride( funcName ) {
	grvLoudThrow( grvAbstractException( funcName ) );
}
/** throw an exception because given functionality is unimplemented */
function grvNotImplemented( what ) {
	grvLoudThrow( grvNotImplementedException( what ) );
}

/**
 * generic utility function to verify that required args
 * (of the caller of this function) have been passed; The given
 * array of descriptions defines how many arguments should be
 * found with a defined value;  Therefore, the caller of this
 * routine should place its optional arguments at the end of its
 * parameter list with no description specified in "optArgDescArray".
 * @param {StringArray} argDescArray array of strings describing
 * required parameters; Note: Optional constructor parameters should
 * not be included in this array.
 * @throws grvMissingArgException
 * @see #Class
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function grvValidateArgs( callerName, argDescArray, callersArgs )
{
	if (argDescArray==null || argDescArray.length==0) grvError("Bad call to grvValidateArgs");

    // callersArgs is the arguments object of the function that
    // called us. Its length property is the number of actual args passed.
    var passed = callersArgs.length;

    // argDescArray should be an array of arg names of args that musnt be null
    var required = argDescArray.length;
    if (passed < required)
	  grvLoudThrow( grvTooFewArgsException( callerName, required, passed ) );

    for (var i=0; i<required; ++i)
	 if ( grvIsUndefined( callersArgs[i] ) )
	  grvLoudThrow( grvMissingArgException( argDescArray[i], callerName ) );
}

The Gravey Framework and RATS RIA

Documentation generated by JSDoc on Sat Dec 8 21:52:02 2007