PHP Classes

File: script/FormDataValidator.js

Recommend this page to a friend!
  Classes of Stefan Kientzler   Complex PHP Form Design and Generator   script/FormDataValidator.js   Download  
File: script/FormDataValidator.js
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Complex PHP Form Design and Generator
Display and process complex HTML forms HTML forms
Author: By
Last change:
Date: 3 years ago
Size: 10,261 bytes
 

Contents

Class file image Download
/** * This class can validate the marked input fields of the form with given id. * Each field that is marked with the custom 'data-validation' attribute is * validated according to the information this attribute contains. */ class FormDataValidator { /** * pass the id of the form element to the constructor. * @param string id */ constructor(config) { this.config = config; this.focusItem = null; this.focusTabIndex = null; this.errors = 0; } /** * Perform the validation. * @returns bool true if all elements contains valid data, false on error */ validate() { var i; var aValidationElements = this.getValidationElements(); var length = aValidationElements.length; for (i = 0; i < length; i++) { // since getValidationElements() only return existing items with 'data-validation' attribute // there's no need to check this values against null let item = aValidationElements[i]; let validate = item.getAttribute('data-validation'); // we can't use the split function because the param may contain the ':' itself (time-separator...) // let [type, param] = validate.split(':'); let pos = validate.indexOf(':'); let type = (pos >= 0) ? validate.substring(0, pos) : validate; let param = (pos >= 0) ? validate.substring(pos + 1) : ''; let valid = false; switch (type) { case 'integer': valid = this.isValidInteger(item.value, param); break; case 'float': valid = this.isValidFloat(item.value, param); break; case 'date': valid = this.isValidDate(item.value, param); break; case 'time': valid = this.isValidTime(item.value, param); break; default: break; } if (valid !== false) { item.value = valid; this.setError(false, item); } else { this.setError(true, item); } } // if errors found, dispplay message and set focus to last input if (this.errors > 0) { var strMsg; if (this.config.errorMsg !== undefined) { strMsg = this.config.errorMsg; } else { strMsg = "The form contains invalid information that is marked in red!<br/><br/>Please correct or complete your entries. "; } var popup = document.getElementById('errorPopup'); if (popup) { popup.innerHTML = strMsg; popup.style.display = 'block'; } if (this.focusItem !== null) { this.focusItem.focus(); } return false; } return true; } /** * Get all elements inside the form with the attribute 'data-validation' set. * @returns array */ getValidationElements() { let validationElements = []; let form = document.getElementById(this.config.formID); let formElements = form.getElementsByTagName('*'); let length = formElements.length; for (let i = 0; i < length; i++) { if (formElements[i].getAttribute('data-validation') !== null) { validationElements.push(formElements[i]); } } return validationElements; } /** * Check, if input is a valid date. * strParam[0]: separator * strParam[1..]: YMD, DMY, MDY for the order of year, month and day * @param string strDate value to checked * @param string * @returns false|string false if invalid, otherwise formated value */ isValidDate(strDate, strParam) { let strSep = strParam.charAt(0); let strYMD = strParam.substring(1); // remove all whitespace strDate = strDate.toString().trim(); if (strDate == '') { return ''; } let iY = 0, iM = 0, iD = 0; switch (strYMD) { case 'YMD': [iY, iM, iD] = strDate.split(strSep); break; case 'DMY': [iD, iM, iY] = strDate.split(strSep); break; case 'MDY': [iM, iD, iY] = strDate.split(strSep); break; default: // console.log('invalid format specification for date validation [' + strParam + ']!'); return false; } if (isNaN(iY) || isNaN(iM) || isNaN(iD)) { return false; } // values < 33 are 21'st century and 33...99 20'st Century! if (iY < 100) { if (iY < 33) { iY += 2000; } else { iY += 1900; } } if (iY < 1900) { return false; } // simply initialize a new Date-Object and compare all parts... (Note: JS Date works with month 0...11 !!) let date = new Date(iY, --iM, iD); if (iD != date.getDate() || iM++ != date.getMonth() || iY != date.getFullYear()) { return false; } // all fine - let's format pretty... switch (strYMD) { case 'YMD': strDate = iY + strSep + ("00" + iM).slice(-2) + strSep + ("00" + iD).slice(-2); break; case 'DMY': strDate = ("00" + iD).slice(-2) + strSep + ("00" + iM).slice(-2) + strSep + iY; break; case 'MDY': strDate = ("00" + iM).slice(-2) + strSep + ("00" + iD).slice(-2) + strSep + iY; break; } return strDate; } /** * Check, if input is a valid time * strParam[0]: separator * strParam[1]: 1 if with seconds, 0 without * strParam[2]: m if allowed to input minutes only, not allowed all other value * @param string strTime value to checked * @param string * @returns false|string false if invalid, otherwise formated value */ isValidTime(strTime, strParam) { if (strParam.length != 3) { // console.log('invalid format specification for time validation [' + strParam + ']!'); return false; } let strSep = strParam.charAt(0); let strSec = strParam.charAt(1); let strMO = strParam.charAt(2); // remove all whitespace strTime = strTime.toString().trim(); if (strTime == '') { return ''; } let [iH, iM, iS] = strTime.split(strSep); if (iM === undefined) { if (strMO != 'm') { return false; } // if only a number is typed in, we interpret it as minutes... iM = iH; iH = 0; } iS = (iS === undefined ? 0 : iS); if (isNaN(iM) || isNaN(iH) || isNaN(iS)) { return false; } if (iM > 59) { iH += (iM - (iM % 60)) / 60; iM = iM % 60; } // ... 23:59 is the end if (iH > 23) { return false; } // simply initialize a new Date-Object and compare all parts... let date = new Date(0, 0, 0, iH, iM, iS); if (iH != date.getHours() || iM != date.getMinutes() || iS != date.getSeconds()) { return false; } // all fine - let's format pretty... strTime = ("00" + iH).slice(-2) + strSep + ("00" + iM).slice(-2); if (strSec != '0') { strTime += strSep + ("00" + iS).slice(-2); } return strTime; } /** * Check for valid integer. * strParam[0]: 'e' if empty value allowed, all other empty value is set to '0' * @param string strInt value to checked * @param string * @returns false|string false if invalid, otherwise formated value */ isValidInteger(strInt, strParam) { // remove all whitespace strInt = strInt.toString().trim(); if (isNaN(strInt) || strInt.indexOf('.') !== -1) { return false; } if (strInt == '' && strParam != 'e') { strInt = '0'; } return strInt; } /** * Check, if input is a valid float. * strParam[1]: 'e' if empty value allowed, all other empty value is set to '0' * strParam[2]: decimal digits * strParam[3]: decimal point * strParam[4]: thousands separator * @param string strCur value to checked * @param string * @returns false|string false if invalid, otherwise formated value */ isValidFloat(strCur, strParam) { let iLength = strParam.length if (iLength != 3 && iLength != 4) { // console.log('invalid format specification for float validation [' + strParam + ']!'); return false; } let strEmpty = strParam.charAt(0); let strDD = strParam.charAt(1); let strDP = strParam.charAt(2); let strTS = (iLength == 3) ? '' : strParam.charAt(3); // remove all whitespace strCur = strCur.toString().trim(); if (strCur == '') { // empty vlues are allowed if (strEmpty == 'e') { return ''; } strCur = '0'; } else { // remove thousands separator and replace decimal point with '.' strCur = strCur.replace(strTS, ""); strCur = strCur.replace(strDP, "."); } if (isNaN(strCur)) { return false; } strCur = Number.parseFloat(strCur).toFixed(strDD); strCur = strCur.replace(".", strDP); strCur = strCur.replace(/\B(?=(\d{3})+(?!\d))/g, strTS); return strCur; } /** * Mark/unmark element as error. * @param bool set true marks error * @param element item to mark */ setError(set, item) { if (set) { item.className = item.className.replace(/Mand/, 'MError'); item.className = item.className.replace(/OK/, 'Error'); this.setFocusItem(item); this.errors++; } else { item.className = item.className.replace(/MError/, 'Mand'); item.className = item.className.replace(/Error/, 'OK'); } } /** * Save invalid item with lowest tabindex to set focus after error message. */ setFocusItem(item) { if (!this.focusTabIndex || this.focusTabIndex > item.tabIndex) { this.focusTabIndex = item.tabIndex; this.focusItem = item; } } }