Location: PHPKode > scripts > dbff > dbff/dbff_jsChk.php
<?php
/*  Name: dbff_jschk.php
	Author: Jerry Mattsson
	Version: 1.2
	Support class for dbff, additional javascript check code generator for browser forms checks.
	Created: Sep-2003, Updated Apr-2004 w fld-chk-parameters, added trim/rtrim for empty fld chk
	Updated with new record definition and datatypes july 2005, Cleaned up code Nov-06.
	Copyright(©) 2003 Jerry Mattsson, www.Timehole.com, Released under GPL2, see doc file.
    ----------------------------------------------------------------------------------------------
   This code should generate javascript code for field tests in forms based on the description
   in the dbff record definition. See dbff.doc for usage. See contacts_sample.php for example usage.
   Typical record spec could be:
   $flds = array (
     'name'  => array ('size'=>20, 'chkNN'=>true),
     'title' => array ('size'=>4),
     'email' => array ('size'=>30, 'type'=>'Email'),
     'units' => array ('size'=>2,  'type'=>'Int'),
     'amount'=> array ('size'=>2,  'type'=>'Number'),
     'when'  => array ('size'=>10, 'type'=>'date', 'chkDateFmt'=>'yyyy-mm-dd',
     'what'  => array ('size'=>2,  'chkFmt'=>'%s %d',
     'used   => array ('size'=>2,  'chkMinLen'=>minLen),
     'min    => array ('size'=>2,  'chkMin'=>minVal,
     'max    => array ('size'=>2,  'chkMax'=>maxVal),
     'list1  => array ('size'=>2,  'chkList'=>array('a','b','c','d'),
     'id'    => array ('size'=>10, 'pk'=>true));

   Datatypes That are tested Int, Number, Email. Other is supposed to be string/varchar.
      There are no tests implemented for Date and DateTime yet. I have not come up with simple
      enough code to use in this class. If used together with dbff, date/datetime is checked there.

   Tests true/false is: chkNN, chkMin(fld,min), chkMax(fld,max), chkMinLen(n), chkList(a,b,c), chkFmt(s,fmt).
      The tests chkDateFmt(d,f) and chkEqual(s1,s2) has no active equivalent function in dbff and is not
      used at the moment, and could therefore actually be removed.

   Needs Event eg. 'onSubmit="return formname_chk(this);"';  The "_chk" is appended to the formname by the
      class to form a javascript function name, so this must not exist elsewhere in your code.
      Field id/names must be unique in the page, duplicate names will cause js to "not find" the element
      and return string undefined to the test function. They are also case sensitive so mixing generated
      records and manually entered filed names might cause the same type of problems or causing the tests
      to fail.

   Usage: You should have this class included and initiated preferably in the header section by:
      $js = new dbff_jsChk;               // Define
      print $js->jsGen($formname, $flds); // Generate and Add code to page
*/
  //////////////////////////////
 // Javascript user messages //
//////////////////////////////
$js_msg = array (
	'e_chkNN'       =>'The field requires a value, please enter one!',
	'e_chkLen'      =>'The entered value is too long, the Maximum character length is ',
	'e_chkMinLen'   =>'The entered value is too short, the Minimum character length is ',
	'e_chkInt'      =>'The entered value must be an Integer',
	'e_chkNum'      =>'The entered value must be a Number',
	'e_chkDate'     =>'The entered value must be a Date',
	'e_chkDateTime' =>'The entered value must be a Date and Time',
	'e_chkMin'      =>'The entered value must be greater than ',
	'e_chkMax'      =>'The entered value must be less than ',
	'e_chkFmt'      =>'The entered value must be in the format: ',
	'e_chkList'     =>'The entered value must be in the List: ',
	'e_chkEmail'    =>'The supplied Email does not look ok, please check it!',
	'e_chkDateFmt'  =>'The supplied Date is not in a valid, format: ',
	'e_Equal'       =>'The entered values does not match!',
	'e_chkMod10'    =>'The supplied value is not valid!',
	'q_submit'      =>'Submit the entered information?'
	 );
  // Msgs End //

class dbff_jsChk {
	var $jstr;
	var $NN=TRUE;
	var $Len=TRUE;
	var $MinLen=TRUE;
	var $Int=TRUE;
	var $Num=TRUE;
	var $Min=TRUE;
	var $Max=TRUE;
	var $Fmt=TRUE;
	var $List=TRUE;
	var $Email=True;
	var $Date=True;
	var $DateTime=True;
	var $Mod10=True;
	var $Equal=True;

function jsGen($formname, $flds) {
   $this->start();
   $this->frmchk($formname, $flds);
   return $this->end();
}

function start() {
   ///////////////////////////////////////////////////////////
  // Initial javascript code, always included              //
 // Includes submit function to verify the completed form //
///////////////////////////////////////////////////////////
global $js_msg;
	$this->jstr = '
	<SCRIPT LANGUAGE="JavaScript">
	<!--';
	$this->jstr .= "\n\tvar q_submit=	\"" . $js_msg['q_submit'] .'"';
	$this->jstr .= '
	function goURL(url) {
	   window.location = url;
	}
	function isDigit (c) { // Returns true if character is a digit 0..9 //
		return ((c>="0")&&(c<="9"))
	}
	function isEmpty(s) { // Check if field string s is empty, true if it is !! //
	  // trim leading and trailing spaces
	  while (s.substring(0,1) == " ") { s = s.substring(1,s.length); }
          while (s.substring(s.length-1, s.length) == " ") { s = s.substring(0,s.length-1); }
		if((s==null)||(s.length==0||s =="")) return true;
		return false;
	}
	function submitForm (form) { // Submit form if it is confirmed //
		var resp = confirm(q_submit);
		// if (resp) { alert(\'responce=\'+resp); /* form.submit(); */ }
		if (resp) { form.submit; }
		else      { form.reset(); return false; };
	}';
}
function frmchk($formname, $flds) {
    /////////////////////////////////////////////////////////////////////////
   // Create check function for each check used in definition array.      //
  // call fldchk to perform the appropriate check function               //
 // All field names/attributes tested as upper Case, chkNN => CHKNN etc //
/////////////////////////////////////////////////////////////////////////
	$str = '
	function ' . $formname . '_chk(form) { // Form Field validation //';
	$str .= "\n\tvar doSubmit=true;";
	$str .= "\n\twhile(doSubmit) {";
        while ( list ($fld_name, $val) = each ($flds) ) { // take it one-by-one...could be all of them
         if (is_array($val)) {
	  // $fld_name = strtoupper($fld_name);
          while ( list ($attribute, $attval) = each ($val)) {
	    $a = strtoupper($attribute);
	    if ($a=='CHKNUM')       $str.=$this->fldchk($fld_name,'chkNum');
	    if ($a=='CHKINT')       $str.=$this->fldchk($fld_name,'chkInt');
	    if ($a=='CHKDATEFMT')   $str.=$this->fldchk($fld_name,'chkDateFmt','"'. $attval.'"');
	    if ($a=='TYPE' && strtoupper($attval)=='NUMBER')   $str.=$this->fldchk($fld_name,'chkNum');
	    if ($a=='TYPE' && strtoupper($attval)=='INT')      $str.=$this->fldchk($fld_name,'chkInt');
	    if ($a=='TYPE' && strtoupper($attval)=='DATE')     $str.=$this->fldchk($fld_name,'chkDate');
	    if ($a=='TYPE' && strtoupper($attval)=='DATETIME') $str.=$this->fldchk($fld_name,'chkDateTime');
	    // where is the date format ?
	    if ($a=='TYPE' && strtoupper($attval)=='EMAIL')  $str.=$this->fldchk($fld_name,'chkEmail');
	    if ($a=='CHKNN')     $str.=$this->fldchk($fld_name,'chkNN');
	    if ($a=='SIZE')      $str.=$this->fldchk($fld_name,'chkLen',$attval);
	    if ($a=='CHKMIN')    $str.=$this->fldchk($fld_name,'chkMin',$attval);
	    if ($a=='CHKMAX')    $str.=$this->fldchk($fld_name,'chkMax',$attval);
	    if ($a=='CHKMINLEN') $str.=$this->fldchk($fld_name,'chkMinLen',$attval);
	    if ($a=='CHKMOD10')  $str.=$this->fldchk($fld_name,'chkMod10');
	    if ($a=='CHKFMT')    $str.=$this->fldchk($fld_name,'chkFmt',$attval);
	    if ($a=='CHKLIST')   $str.=$this->fldchk($fld_name,'chkList','"'.implode(",",$attval).'"');
	    if ($a=='EQUAL')     $str.=$this->fldchk($fld_name,'Equal',$attval[0],$attval[1]);
	  };
	 };
	};
	$str .= "\n\tbreak;\n\t}";
	$str .= "\n\tif(doSubmit) submitForm(form); else return false;";
	$str .= "\n\t}";
	$this->jstr .= $str;
}
function end() {
  ////////////////
 // Script End //
////////////////
	$this->jstr .= '
	// -->
	</script>';
	return $this->jstr;
}
function fldchk($fld, $chktype, $val1=NULL, $val2=NULL) {
  ///////////////////////////////////////////////////////////
 // Add js-call for each check to be performed on a field //
///////////////////////////////////////////////////////////
	// trace print // $str  = 'alert("'.$fld.'" + form.elements["'.$fld.'"].value)';
	$str  = "\n\t if (!$chktype(form.elements[";
	$chktype = strtoupper($chktype);
	switch($chktype) {
		case 'CHKNN':
			if($this->NN) $this->g_NN(); 		// Include JS-code for this function
			$str .= '"'.$fld.'"].value))';				break;
		case 'CHKNUM':
			if($this->Num) $this->g_Num();
			$str .= '"'.$fld.'"].value))';				break;
		case 'CHKINT':
			if($this->Int) $this->g_Int();
			$str .= '"'.$fld.'"].value))';				break;
		case 'CHKDATE':
			if($this->Date) $this->g_Date();
			$str .= '"'.$fld.'"].value))';				break;
		case 'CHKDATETIME':
			if($this->DateTime) $this->g_DateTime();
			$str .= '"'.$fld.'"].value))';				break;
		case 'CHKLEN':
			if($this->Len) $this->g_Len();
			$str .= '"'.$fld.'"].value,'.$val1.'))';		break;
		case 'CHKMINLEN':
			if($this->MinLen) $this->g_MinLen();
			$str .= '"'.$fld.'"].value,'.$val1.'))';		break;
		case 'EQUAL':
			if($this->Equal) $this->g_Equal();
			$str .= '"'.$fld.'"].value,'.$val1.',' . $val2 . '))';	break;
		case 'CHKLIST':
			if($this->List) $this->g_List();
			$str .= '"'.$fld.'"].value,'.$val1.'))';		break;
		case 'CHKFMT':
			if($this->Fmt) $this->g_Fmt();
			$str .= '"'.$fld.'"].value,'.$val1.'))';		break;
		case 'CHKMIN':
			if($this->Min) $this->g_Min();
			$str .= '"'.$fld.'"].value,'.$val1.'))';		break;
		case 'CHKMAX':
			if($this->Max) $this->g_Max();
			$str .= '"'.$fld.'"].value,'.$val1.'))';		break;
		case 'CHKEMAIL':
			if($this->Email) $this->g_Email();
			$str .= '"'.$fld.'"].value))';				break;
		case 'CHKDATEFMT':
			if($this->Date) $this->g_DateFmt();
			$str .= '"'.$fld.'"].value,'.$val1.'))';		break;
		case 'CHKMOD10':
			if($this->Mod10) $this->g_Mod10();
			$str .= '"'.$fld.'"].value))';				break;
		default: 							break;
	};
	$str .= '{ doSubmit=false; form.elements["'.$fld.'"].focus();  break; }';
	return $str;
}
    //////////////////////////////////////////////////////////////////////
   // Geneate code for each test, Datatypes: Int, Number, Email and    //
  // Checks: chkNN, chkFmt, chkDateFmt, chkList, chkMin, chkMax, size //
 // Javascript error messages must exist in js_msg indexes           //
//////////////////////////////////////////////////////////////////////
function g_mod10() {
global $js_msg;
	$this->jstr .= "\n\tvar e_chkMod10=	\"" . $js_msg['e_chkMod10'] .'"';
	$this->jstr .= '
	function chkMod10(n) { // Check last digit is mod10 check digit //
	var digit=0;
	var sum=0;
	var i=0;
	   for(i=0; i<n.length-1; i++) { // Check in value digit by digit (last digit is check digit)
	      digit=parseInt(n.charAt(i));
	      if (i%2==0)  { digit = digit * 2; }    // multiply by 2 every other digit
	      if (digit<10) { sum += digit; }
	      else          { sum += digit-9; }
	   }
	i = Math.ceil(sum/10);
	i = (i * 10) - sum;
	   if (n.substr(n.length-1,1)==i) return true;
	   alert(e_chkMod10);
	   return false;
	};';
}
function g_isDate() {
	$this->jstr .= '
	function isDate(s) { // Check date, must be in numeric format yyyymmdd //
	if(isEmpty(s)) return true;
	var year  = parseInt(s.substr(0,4));
	var month = s.substr(4,2);
	var day   = s.substr(6,2);
	while(true) {
	   if (month<1  || month>12 || day<1    || day>31 || year<1900 || year>2100) break;
	   if (month==4 || month==6 || month==9 || month==11) if (day==31) break;
	   if (month==2) {
		var leap=parseInt(year/4);
		if (day>29) break;
		if (day==29 && ((year/4)!=parseInt(year/4))) break;
	   }
	   return(true);
	};
	return false;
	}';
}
function g_DateFmt() {
// Date (re)Format check yyyy/mm/dd, yyyy-mm-dd, mm/dd/yy etc //
global $js_msg;
	$this->Date=FALSE;
	$this->jstr .= "\n\tvar e_chkDateFmt=	\"" . $js_msg['e_chkDateFmt'] .'"';
	$this->g_isDate();
	$this->jstr .= '
	function chkDateFmt (s,f) { // Match date string to format mask //
	var out="", y="", m="", d="", H="", M="", S="";
	while(true) {
		if(f.length<6) break; // Minimum date format mask is yymmdd
		for (i = 0; i < f.length; i++) {
			c = s.charAt(i);
			if (isDigit(c) ) {
				if(f.charAt(i)=="y") y=y+c;
				if(f.charAt(i)=="m") m=m+c;
				if(f.charAt(i)=="d") d=d+c;
				if(f.charAt(i)=="H") H=H+c;
				if(f.charAt(i)=="M") M=M+c;
				if(f.charAt(i)=="S") S=S+c;
			};
		};
		if(y.length==2) y = "20"+y;
		out = y+m+d;
		if(out.length<8) break;
		if(isDate(out)) return true;
		break;
	};
	alert(e_chkDateFmt + out +" "+f); return false;
	}';
}
function g_Email() {
// Check Email Format //
global $js_msg;
	$this->Email=FALSE;
	$this->jstr .= "\n\tvar e_chkEmail=	\"" . $js_msg['e_chkEmail'] .'"';
	$this->jstr .= '
	function chkEmail(s) { // Check the email format, does not allow singel char domains //
		var dom = s.indexOf(".");
		if(isEmpty(s)) return true;
		if((dom > 2) && (s.indexOf("@") > 0) && s.length > dom+2) return true;
		alert(e_chkEmail); return false;
	}';
}
function g_Fmt() {
// Format check, Format string is made up of characters and
// format info where %c=character %d=digit
global $js_msg;
	$this->Fmt=FALSE;
	$this->jstr .= "\n\tvar e_chkFmt=	\"" . $js_msg['e_chkFmt'] .'"';
	$this->jstr .= '
	function chkFmt (s,f) { // Match num/email string to format mask //
		if(printf(s,f)==s)   return true;
		alert(e_chkFmt + f); return false;
	}';
}
function g_Int() {
global $js_msg;
	$this->Int=FALSE;
	$this->jstr .= "\n\tvar e_chkInt=	\"" . $js_msg['e_chkInt'] .'"';
	$this->jstr .= '
	function chkInt (s) { // Search string char by char, error if not numeric //
		var i, c;
		for (i = 0; i < s.length; i++) {
		if (!isDigit(s.charAt(i))) { alert(e_chkInt); return false; }
		}
	return true;
	}';
}
function g_Num() {
global $js_msg;
	$this->Num=FALSE;
	$this->jstr .= "\n\tvar e_chkNum=	\""  . $js_msg['e_chkNum'] .'"';
	$this->jstr .= '
	function chkNum (s) { // Search string char by char, error if not numeric //
	var i, c;
	for (i = 0; i < s.length; i++) {
		c = s.charAt(i);
		if (i==0) { if (c=="-"||c=="+") continue; }
		else { if (c=="."||c==",") continue; } /* should be more specific */
		if (!isDigit(c) ) { alert(e_chkNum); return false; }
		}
	return true;
	}';
}
function g_Date() { // not implemented/done == dummy tests
global $js_msg;
	$this->Date=FALSE;
	$this->jstr .= "\n\tvar e_chkDate=	\"" . $js_msg['e_chkDate'] .'"';
	$this->jstr .= '
	function chkDate (s) { // Not a fool proof date check //
		if(isEmpty(s)) return true;
	return true;
	}';
	// simple code missing, could be: string replace /-. etc with ,
	// then try variant 123,321,1M3,3M1 where M=converted monthname
	// in string as s = "2000"+","+"11"+","+"29"; d = new Date(s); if (isNaN(d)) return false;
}
function g_DateTime() { // not implemented/done == dummy tests
global $js_msg;
	$this->DateTime=FALSE;
	$this->jstr .= "\n\tvar e_chkDateTime=	\"" . $js_msg['e_chkDateTime'] .'"';
	$this->jstr .= '
	function chkDateTime (s) {
		if(isEmpty(s)) return true;
	return true;
	}';
	// code as date chk and add time test.
}
function g_Len() {
global $js_msg;
	$this->Len=FALSE;
	$this->jstr .= "\n\tvar e_chkLen=	\"" . $js_msg['e_chkLen'] .'"';
	$this->jstr .= '
	function chkLen (s,len) { // Check if string is longer than len //
		if (s.length>len) { alert(e_chkLen + len); return false; }
	return true;
	}';
}
function g_Equal() {
global $js_msg;
	$this->Equal=FALSE;
	$this->jstr .= "\n\tvar e_Equal=	\"" . $js_msg['e_Equal'] .'"';
	$this->jstr .= '
	function Equal (s1,s2) { // Check if strings is equal //
		if (s1!=s2) { alert(e_Equal); return false; }
	return true;
	}';
}
function g_MinLen() {
global $js_msg;
	$this->MinLen=FALSE;
	$this->jstr .= "\n\tvar e_chkMinLen=	\"" . $js_msg['e_chkMinLen'] .'"';
	$this->jstr .= '
	function chkMinLen (s,len) { // Check if string is at least len //
		if (s.length<len) { alert(e_chkMinLen + len); return false; }
	return true;
	}';
}
function g_List() {
global $js_msg;
	$this->List=FALSE;
	$this->jstr .= "\n\tvar e_chkList=	\"" . $js_msg['e_chkList'] .'"';
	$this->jstr .= '
	function chkList (s,l) { // Check if value s is in list l//
		if(isEmpty(s)) return true;
		var i = 0;
		while (i<l.length) { if (s==l[i++]) return true; }
		alert(e_chkList + l); return false;
	}';
}
function g_Min() {
global $js_msg;
	$this->Min=FALSE;
	$this->jstr .= "\n\tvar e_chkMin=	\"" . $js_msg['e_chkMin'] .'"';
	$this->jstr .= '
	function chkMin (n,min) { // Check if n is greater than min inclusive//
		if(isEmpty(n)) return true;
		if(n>=min) return true;
		alert(e_chkMin + min); return false;
	}';
}
function g_Max() {
global $js_msg;
	$this->Max=FALSE;
	$this->jstr .= "\n\tvar e_chkMax=	\"" . $js_msg['e_chkMax'] .'"';
	$this->jstr .= '
	function chkMax (n,max) { // Check if n is less than max inclusive//
		if(isEmpty(n)) return true;
		if(n<=max) return true;
		alert(e_chkMax + max); return false;
	}';
}
function g_NN() {
global $js_msg;
	$this->NN=FALSE;
	$this->jstr .= "\n\tvar e_chkNN=	\"" . $js_msg['e_chkNN'] .'"';
	$this->jstr .= '
	function chkNN(s) { // Check if field string s is empty. //
		if (isEmpty(s)) { alert(e_chkNN); return false; }
	return true;
	}';
}
}
// dbff_jsChk End
?>
Return current item: dbff