// form 2.2 // requires dom 3.8, functions 2.0 var elmSwitch = { // checkbox that turns defined elements on or off cls: "elmSwitch", onAttr: "switchOn", // this attribute contains array of attributes that have to be turned on when box is checked offAttr: "switchOff", // this attribute contains array of attributes that have to be turned on when box is unchecked init: function(obj) { var inputField = elm.get(obj); if (inputField.tagName.toLowerCase() == "select") { elmSwitch.runSelect(obj); evt.add(inputField, "change", elmSwitch.runSelect); } if ((inputField.tagName.toLowerCase() == "input") && (inputField.getAttribute("type") == "checkbox")) { elmSwitch.runCheckBox(obj); evt.add(inputField, "click", elmSwitch.runCheckBox); } return true; }, enable: function(obj) { // enables object; may be overriden var elmNode = elm.get(obj); elm.turn(elmNode, "on"); return true; }, disable: function(obj) { // enables object; may be overriden var elmNode = elm.get(obj); elm.turn(elmNode, "off"); return true; }, _disableBlocks: function(blockIdArray) { for (i in blockIdArray) { k = blockIdArray[i]; blockNode = elm.get(k); if (blockNode != null) { elmSwitch.disable(blockNode); } } return true; }, _enableBlocks: function(blockIdArray) { for (i in blockIdArray) { k = blockIdArray[i]; blockNode = elm.get(k); if (blockNode != null) { elmSwitch.enable(blockNode); } } return true; }, runCheckBox: function(obj) { var chkBox = elm.get(obj); var blockIdArray; var blockNode; var i, j, k; if (chkBox.checked) { // turn off blocks from offAttr blockIdArray = variable.parseJsonString(elm.getAttribute(chkBox, elmSwitch.offAttr)); elmSwitch._disableBlocks(blockIdArray); // turn on blocks from onAttr blockIdArray = variable.parseJsonString(elm.getAttribute(chkBox, elmSwitch.onAttr)); elmSwitch._enableBlocks(blockIdArray); } else { // obj unchecked // turn off blocks from onAttr blockIdArray = variable.parseJsonString(elm.getAttribute(chkBox, elmSwitch.onAttr)); elmSwitch._disableBlocks(blockIdArray); // turn on blocks from offAttr blockIdArray = variable.parseJsonString(elm.getAttribute(chkBox, elmSwitch.offAttr)); elmSwitch._enableBlocks(blockIdArray); } return true; }, runSelect: function(obj) { var selectField = elm.get(obj); var blockIdArray; var blockNode; var i, j, k; // assume that it is not multiple select as multiple selects are pure evil for (i = 0; i < selectField.options.length; i++) { // turn on blocks from onAttr blockIdArray = variable.parseJsonString(elm.getAttribute(selectField.options[i], elmSwitch.onAttr)); elmSwitch._disableBlocks(blockIdArray); // turn on blocks from offAttr blockIdArray = variable.parseJsonString(elm.getAttribute(selectField, elmSwitch.offAttr)); elmSwitch._enableBlocks(blockIdArray); } if (selectField.selectedIndex) { // enable and disableBlocks blockIdArray = variable.parseJsonString(elm.getAttribute(selectField.options[selectField.selectedIndex], elmSwitch.onAttr)); elmSwitch._enableBlocks(blockIdArray); blockIdArray = variable.parseJsonString(elm.getJsonAttribute(selectField.options[selectField.selectedIndex], elmSwitch.offAttr)); elmSwitch._disableBlocks(blockIdArray); } return true; } } var fieldChecker = { invalidClass: "invalid", add: function(obj, ruleSet) { // adds fieldChecker functionality to input field. // ruleset is associative array of validation rules, default values and error messages obj = elm.get(obj); if (obj == null) return false; // mark field as not modified obj.fieldChecker_modified = false; // add relevant rules from specified ruleset. obj.fieldChecker_ruleSet = new Array(); var classNames = cls.get(obj); var i; var ruleName; for (i = 0; i < classNames.length; i++) { ruleName = classNames[i]; if ((typeof ruleSet[ruleName] != "undefined") && (ruleSet[ruleName] != null)) { obj.fieldChecker_ruleSet[ruleName] = ruleSet[ruleName]; } } // try to add label if (obj.getAttribute("id") != null) { var labels = document.getElementsByTagName("label"); for (i = 0; i < labels.length; i++) { if (labels[i].getAttribute("for") == obj.getAttribute("id")) { obj.fieldChecker_label = labels[i]; } } } // on focus insert default value, on blur remove it evt.add(obj, "focus", fieldChecker.setDefaultValue); evt.add(obj, "blur", fieldChecker.clearDefaultValue); // check field when user changes content of input field evt.add(obj, "keyup", function(e) { fieldChecker.setModified(e); fieldChecker.check(e); }); evt.add(obj, "blur", function(e) { fieldChecker.setModified(e); fieldChecker.check(e); }); // check field now fieldChecker.check(obj); return true; }, setDefaultValue: function(obj) { if (typeof obj.tagName == "undefined") { // item is not HTML element var e = evt.fix(obj); obj = evt.getTarget(e); } // obj is now HTML element, so we can use it if (obj.fieldChecker_modified) return true; // object's value has been modified so we should not change it if (elm.getValue(obj) == "") { for (rule in obj.fieldChecker_ruleSet) { if (typeof obj.fieldChecker_ruleSet[rule].def != "undefined") { elm.setValue(obj, obj.fieldChecker_ruleSet[rule].def); return true; } } } return true; }, clearDefaultValue: function(obj) { if (typeof obj.tagName == "undefined") { // item is not HTML element var e = evt.fix(obj); obj = evt.getTarget(e); } // obj is now HTML element, so we can use it if (obj.fieldChecker_modified) return true; // object's value has been modified so we should not change it for (rule in obj.fieldChecker_ruleSet) { if (typeof obj.fieldChecker_ruleSet[rule].def != "undefined") { if (elm.getValue(obj) == obj.fieldChecker_ruleSet[rule].def) { elm.setValue(obj, ""); return true; } } } return true; }, setModified: function(obj) { if (typeof obj.tagName == "undefined") { // item is not HTML element var e = evt.fix(obj); obj = evt.getTarget(e); } // obj is now HTML element, so we can use it obj.fieldChecker_modified = true; return true; }, check: function(obj) { // this function checks if field value is valid. // obj can be event targeted to field, or field itself. var passed = false; var ruleName = ""; var target = obj; if (typeof obj.tagName == "undefined") { // item is not HTML element obj = evt.getTrigger(obj); } // obj is now HTML element, so we can check it for (rule in obj.fieldChecker_ruleSet) { // check by fn and exit if invalid if (typeof obj.fieldChecker_ruleSet[rule].fn != "undefined") { if (!obj.fieldChecker_ruleSet[rule].fn(elm.getValue(obj))) { fieldChecker.setInvalid(obj, rule); return false; } } // check by reg and exit if invalid if (typeof obj.fieldChecker_ruleSet[rule].reg != "undefined") { if (elm.getValue(obj).search(obj.fieldChecker_ruleSet[rule].reg) < 0) { fieldChecker.setInvalid(obj, rule); return false; } } } // passed tests, set it valid fieldChecker.setValid(obj); return true; }, setValid: function(obj) { obj.fieldChecker_error = null; cls.remove(obj, fieldChecker.invalidClass); return true; }, setInvalid: function(obj, rule) { if (!obj.disabled && (typeof rule != "undefined") && (rule != null)) { obj.fieldChecker_error = obj.fieldChecker_ruleSet[rule].err; } cls.add(obj, fieldChecker.invalidClass); return true; }, isValid: function(obj) { return cls.has(obj, fieldChecker.invalidClass); }, setLabel: function(obj, label) { obj.fieldChecker_label = label; return true; }, getLabel: function(obj, resultType) { // TODO - modify result by resultType // defined result types: plain, html var result = ""; if (obj.fieldChecker_label) { result = result + obj.fieldChecker_label.innerHTML; result = result.replace(/[:]?\s*$/g,""); result = result.trim(); result = result.removeInlineHtml(); } return result; }, getMessage: function(obj) { // returns error message of the object if any if ((typeof obj.fieldChecker_error != "undefined") && (obj.fieldChecker_error != null)) { var result = obj.fieldChecker_error; var label = fieldChecker.getLabel(obj, "plain"); if (label == "") label = obj.getAttribute("title"); if ((label == "") || (label == null)) label = obj.name; result = result.replace(/\{label\}/g, '"' + label + '"'); result = result.replace(/\{value\}/g, '"' + elm.getValue(obj) + '"'); return result; } return ""; } } var formChecker = { invalidClass: "invalid", invalidMsgTitle: "Warning, some fields are not filled properly", invalidMsgShowFields: false, // show detailed error messges for all fields? add: function(obj, ruleSet) { // adds formChecker functionality to form. // ruleset is associative array of validation rules, default values and error messages obj = elm.get(obj); if (obj == null) return false; // init fieldChecker for each input in form obj.formChecker_fields = new Array(); var inputs = obj.getElementsByTagName("input"); var inputType; for (i = 0; i < inputs.length; i++) { inputType = inputs[i].getAttribute("type"); if ((inputType == "text") || (inputType == "password") || (inputType == "file")) { fieldChecker.add(inputs[i], form_ruleSet); obj.formChecker_fields[obj.formChecker_fields.length] = inputs[i]; } } var textareas = obj.getElementsByTagName("textarea"); for (i = 0; i < textareas.length; i++) { fieldChecker.add(textareas[i], form_ruleSet); obj.formChecker_fields[obj.formChecker_fields.length] = textareas[i]; } evt.add(obj, "submit", formChecker.submit); return true; }, check: function(obj) { // this function checks if all fields in form are valid. // obj can be an event targeted to a form, or the form itself. var i; var passed = true; var ruleName = ""; var target = obj; if (typeof obj.tagName == "undefined") { // item is not HTML element var e = evt.fix(obj); obj = evt.getTarget(e); } // obj is now HTML element, so we can check it obj.formChecker_error = ""; for (i = 0; i < obj.formChecker_fields.length; i++) { if (!obj.formChecker_fields[i].disabled && !fieldChecker.check(obj.formChecker_fields[i])) { passed = false; obj.formChecker_error += fieldChecker.getMessage(obj.formChecker_fields[i]) + "\r\n"; } } if (!passed) { formChecker.setInvalid(obj); return false; } formChecker.setValid(obj); return true; }, setValid: function(obj) { obj.formChecker_error = null; cls.remove(obj, formChecker.invalidClass); return true; }, setInvalid: function(obj, field) { cls.add(obj, formChecker.invalidClass); return true; }, displayMessage: function(obj) { var msg = formChecker.invalidMsgTitle.removeInlineHtml(); if (formChecker.invalidMsgShowFields) { msg += "\r\n" + obj.formChecker_error; } alert(msg); }, submit: function(obj) { // obj could be form or event var e = null; // submit event if (typeof obj.tagName == "undefined") { // item is not HTML element // e = evt.fix(obj); e = obj; obj = evt.getTrigger(e); } // obj is now HTML form element, so we can check it if (!formChecker.check(obj)) { // form invalid, display error messages formChecker.displayMessage(obj); if (e != null) evt.cancel(e); return false; } return true; } } var form_ruleSet = {} // basic private definitions form_ruleSet._df = {}; form_ruleSet._df.specChars = " \!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xD7\xF7"; form_ruleSet._df.alphaLowercaseISO = "\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"; form_ruleSet._df.alphaUppercaseISO = "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDE"; form_ruleSet._df.alphaLowercaseUTF = "\u00E1\u00E9\u0115\u00ED\u00F3\u00FA\u016F\u00FD\u017E\u0161\u010D\u0159\u010F\u0165\u0148" + form_ruleSet._df.alphaLowercaseISO; form_ruleSet._df.alphaUppercaseUTF = "\u00C1\u00C9\u0114\u00CD\u00D3\u00DA\u016E\u00DD\u0160\u017D\u010c\u0158\u010E\u0164\u0147" + form_ruleSet._df.alphaUppercaseISO; form_ruleSet.percentage = { // number - exponential form allowed, unlimited decimal digits reg: new RegExp("^(([0-9]{1,2})|(100{1}))?$"), err: "Field {label} must contain a number from 0 to 100." }; form_ruleSet.number = { // notNegative - positive numbers and zero, exponential form allowed, unlimited decimal digits reg: new RegExp("^([\+\-]?[0-9]{1,}([\.][0-9]{1,})?(e[\+\-]{1}[0-9]{1,2})?)?$"), err: "Field {label} must contain number." }; form_ruleSet.notNegative = { // notNegative - only positive numbers (without zero), exponential form allowed, unlimited decimal digits reg: new RegExp("^([\+]?[0-9]{1,}([\.][0-9]{1,})?(e[\+\-]{1}[0-9]{1,})?)?$"), err: "Field {label} must contain positive number or 0." }; form_ruleSet.positive = { reg: new RegExp("^(([\+]?[0-9]*[1-9]{1}[0-9]*([\.][0-9]{1,})?(e[\+\-]{1}[0-9]{1,})?)|([\+]?[0-9]{1,}([\.][0-9]*[1-9]{1}[0-9]*){1}(e[\+\-]{1}[0-9]{1,})?))?$"), err: "Field {label} must contain number greater than 0." }; form_ruleSet.email = { reg: new RegExp("^([a-zA-Z0-9]+[a-zA-Z0-9\._-]*[a-zA-Z0-9]+@[a-zA-Z0-9]+[a-zA-Z0-9\._-]*[a-zA-Z0-9]+[\.]{1}[a-zA-Z]{2,4})?$"), err: "Field {label} must contain a valid e-mail address." }; form_ruleSet.safeChars = { reg: new RegExp("^[0-9a-zA-Z_]{0,}$"), err: "Field {label} must contain only safe characters." }; form_ruleSet.alphaLowercase = { reg: new RegExp("^.*$"), // reg: new RegExp("^[a-z" + form_ruleSet._df.alphaLowercaseUTF + " ]{1,}$")), err: "Field {label} must contain only lowercase alphabet characters." }; form_ruleSet.alphaUppercase = { reg: new RegExp("^.*$"), // new RegExp("^[A-Z" + form_ruleSet._df.alphaUppercaseUTF + " ]{1,}$")), err: "Field {label} must contain only uppercase alphabet characters." }; form_ruleSet.alpha = { reg: new RegExp("^.*$"), // reg: new RegExp("^[a-zA-Z" + form_ruleSet._df.alphaUppercaseUTF + form_ruleSet._df.alphaLowercaseUTF + " ]{1,}$")), err: "Field {label} must not contain numbers or special characters." }; form_ruleSet.alphanumeric = { reg: new RegExp("^.*$"), // reg: new RegExp("^[a-zA-Z" + form_ruleSet._df.alphaUppercaseUTF + form_ruleSet._df.alphaLowercaseUTF + "0-9 ]{1,}$")) err: "Field {label} must contain only alphanumeric characters." }; form_ruleSet.text = { reg: new RegExp("^.*$"), // reg: new RegExp("^[a-zA-Z" + form_ruleSet._df.alphaUppercaseUTF + form_ruleSet._df.alphaLowercaseUTF + "0-9" + specChars + "]{1,}$")), err: "Field {label} must contain only text." }; form_ruleSet.dynamicParams = { reg: new RegExp("^[ -~" + form_ruleSet._df.alphaUppercaseUTF + form_ruleSet._df.alphaLowercaseUTF + "]{0,}$"), err: "Field {label} must not contain any numbers or special characters except \"-\" or \"~\"." }; form_ruleSet.color = { reg: new RegExp("^([#]{1}[0-9a-fA-F]{6})?$"), err: "Field {label} must contain hexadecimal RGB color definition (for example #336699)." }; form_ruleSet.url = { reg: new RegExp("^(http(s)?://(([a-zA-Z0-9]+([-_.]?[a-zA-Z0-9])*\.([a-zA-Z]){2,4})|(([0-9]){1,3}\.([0-9]){1,3}\.([0-9]){1,3}\.([0-9]){1,3}))(:[0-9]{2,5})?(/([-!_:~&=$?.|;,%a-zA-Z0-9[\\]]|(%[0-9a-fA-F]{2}))*)*)?$"), def: "http://", err: "Field {label} must contain valid URL (for example \"http://www.google.com\")." }; form_ruleSet.telephone = { reg: new RegExp("^[0-9()+-/ ]{0,}$"), err: "Field {label} must contain a valid phone number." }; form_ruleSet.domains = { // general check for the list of domains made problems (MS IE) // the following regular expression were unsuccessfully tried and then commented out: // reg: new RegExp("^(([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*\.[a-zA-Z]{2,4})[,\f\n\r]\n?)*$"), // reg: new RegExp("^(([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[\.]{1}[a-zA-Z]{2,4})([ \f\n\r]*[,]?[ \f\n\r]*)+)*$"), // reg: new RegExp("^(([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[\.]{1}[a-zA-Z]{2,4}(\/{1}[-_~&=\?\.a-zA-Z0-9]*)*)[,]?)*$"), // current solution only checks whether characters are from the valid set // the reg.expr. also contains various white spaces to enable the comfortable editing // ( white space char (\s) did not work) reg: new RegExp("^[0-90-9a-zA-Z\-\_\.\~\&\=\?,\r\n\t\f ]{0,}$"), err: "Field {label} must contain domain names." }; // local specific items. // international, no exponential form - old version without internationalization form_ruleSet.numeric = { reg: new RegExp("^[\+\-]?[0-9 ]{0,}$"), err: "Field {label} must contain domain names." }; form_ruleSet.floatNumber = { // 2 decimal digits reg: new RegExp("^[\+\-]?[0-9]*([.][0-9]*)?$"), err: "Field {label} must contain domain names." }; form_ruleSet.date = { // in format (D)D.(M)M.YYYY reg: new RegExp("^([0-9]{1,2}[.][0-9]{1,2}[.][0-9]{4}){0,1}$"), err: "Field {label} must contain domain names." }; form_ruleSet.required = { fn: function(str) { return (str.search(/\S/) < 0) ? false : true; }, err: "Field {label} must not be empty." }; form_ruleSet.multipleEmails = { // requires checks.email fn: function(str) { if (str == "") return true; var addresses = str.split(','); // Array of Strings var fieldOK = true; // Boolean var rule = form_ruleSet.email; // RegExp var i; // Int var actualAddress; // String for (i = 0; i < addresses.length; i++) { if (addresses[i].trim) actualAddress = addresses[i].trim(); else actualAddress = addresses[i]; fieldOK = fieldOK && ((actualAddress.search(rule) < 0) ? false : true); } return fieldOK; }, err: "Field {label} must contain only valid e-mail addresses separated by commas \",\"." }; form_ruleSet.custom01 = { // checks if some contact info is filled fn: function(str) { // if (str == "") return true; /* var phone = elm.get("order_phone"); var email = elm.get("order_email"); var cell = elm.get("order_cellphone"); if (elm.getValue(phone) != "") return true; if (elm.getValue(email) != "") return true; if (elm.getValue(cell) != "") return true; return false; */ return true; }, err: "Phone or e-mail address must be set." };