// Invalid/missing elements are highlighted using // this background colour: var MJS_COLOUR_ERROR = '#ffdddd'; // Indexes into validation param hash for each validated element, // first general ones, then those specifi to type: var MJS_TYPE = 0; var MJS_NAME = 1; // display name var MJS_REQUIRED = 2; var MJS_REGEXP = 3; var MJS_name = 4; // 'real' name var MJS_TEXT_MIN = 4; var MJS_TEXT_MAX = 5; var MJS_TEXT_REQ_IF = 6; var MJS_TEXTAREA_REQ_IF = 4; var MJS_SEL_IGNORE_FIRST = 3; // Select element has hint as first option - // ignore when looking for value var MJS_SEL_REQ_IF = 4; var MJS_DATE_REQ_IF = 3; var MJS_DATE_RANGE_START = 4; var MJS_DEFAULT_REQ_IF = 3; var MOCA_REGEXP_all = ''; var MOCA_REGEXP_words = /^[a-z 0-9]+$/i; var MOCA_REGEXP_alphanumeric = /^[a-z0-9_]+$/i; var MOCA_REGEXP_filename = /^[a-z0-9_.]+$/i; var MOCA_REGEXP_email = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/; var MOCA_REGEXP_phone = /^[0-9 +\(\)-]{7,}$/; var MOCA_REGEXP_integer = /^[0-9]+$/; var MOCA_REGEXP_hex = /^[0-9a-f]+$/i; var MOCA_REGEXP_number = /^[0-9.,-]+$/; var MOCA_REGEXP_float = /^[0-9.]+$/; var MOCA_REGEXP_cc = /^\d{4}(-| )?\d{4}(-| )?\d{4}(-| )?\d{4}$/; var MOCA_REGEXP_cc_exp = /^\d{2}\/\d{2}$/; var MOCA_REGEXP_date = /^(\d{2})-(\d{2})-(\d{4})$/; var MOCA_REGEXP_time = /^[0-9]+:[0-9]+$/; var MOCA_REGEXP_expiry = /^\d+\s+(week|day|month|year)s?$/i; var MOCA_REGEXP_names = /^[ a-z0-9_&@()'.,";~-]{0,255}$/i; var MOCA_REGEXP_simple_names = /^[ a-z,0-9"'.-]{0,255}$/i; var MOCA_REGEXP_labels = /^[ $#a-z0-9_&%\/@()'."+!,:;~?>-]{0,255}$/i; var MOCA_REGEXP_data = /^[a-z#?0-9_&%@()-;:,'~".!+\n\r ]{0,1024}$/i; var MOCA_REGEXP_url = /^[a-z=0-9_&@%-:\/;,'".~!+?+]{0,255}$/i; var MOCA_REGEXP_keywords = /^[a-z0-9, '-]+$/i; function MocaForm(fields){ this.fields = fields; // All MocaFields {name:[prop,prop,prop,etc],...} this.values = {}; // Cache of processed element values this.els = {}; // Cache of element refs this.name = ''; // current actual name value this.field = []; // Current MocaField (being validated) this.element = null; // Currently element this.value = ''; // Current element value } MocaForm.prototype = { MJS_T: 'text', // == EL_ID_TEXT MJS_TA: 'textarea', MJS_S: 'select', MJS_RG: 'radio', MJS_C: 'checkbox', MJS_CG: 'checkboxgroup', MJS_D: 'date', MJS_P: 'password', MJS_H: 'hidden', MJS_L: 'label', required_if: {}, require:function(fields,preserve){ var flds = fields.splice ? fields : [fields]; if(!preserve){ for(var f in this.fields){ f[MJS_REQUIRED] = false; } } for(var i=0; ithis.field[MJS_TEXT_MAX]){ return this.max_error(); } break; case this.MJS_P: // password req_if_ord = MJS_TEXT_REQ_IF; var val = this.values[f] = this.value = $.trim(this.element.value); if(this.field[MJS_REQUIRED] && !val){ return this.req_error(); } if(val && this.field[MJS_REGEXP]){ if(!this.field[MJS_REGEXP].test(val)){ return this.val_error(); } } if(this.field[MJS_TEXT_MIN] && val.lengththis.field[MJS_TEXT_MAX]){ return this.max_error(); } break; case this.MJS_TA: // textarea req_if_ord = MJS_TEXTAREA_REQ_IF; var val = this.values[f] = this.value = $.trim(this.element.value); if(this.field[MJS_REQUIRED] && !val){ return this.req_error(); } if(val && this.field[MJS_REGEXP]){ if(!this.field[MJS_REGEXP].test(val)){ return this.val_error(); } } break; case this.MJS_S: // select req_if_ord = MJS_SEL_REQ_IF; idx = this.element.selectedIndex; if(this.field[MJS_REQUIRED]){ if((idx == -1) || (!idx && this.field[MJS_SEL_IGNORE_FIRST])){ return this.sel_error(); } } this.value = this.values[f] = $('#mf_select_'+f).val(); break; case this.MJS_RG: // radio group if(this.field[MJS_REQUIRED]){ var val = false; var chk = document.getElementsByName('mf_'+ this.MJS_RG + '_' + f ); for (var i = 0; i < chk.length; i++){ if (chk[i].checked) {val = chk[i].value;break;} } if(!val){ this.element = chk; return this.grp_error(); } } break; case this.MJS_CG: // checkbox group if(this.field[MJS_REQUIRED]){ this.values[f] = []; // don't really need these otherwise var chk = document.getElementsByName('mf_'+ this.MJS_CG + '_' + f + '[]'); for (var i = 0; i < chk.length; i++){ if (chk[i].checked) {this.values[f].push(chk[i].value);} } if(!this.values[f].length){ this.element = chk; return this.grp_error(); } } break; case this.MJS_C: // checkbox if(this.element.checked){ this.value = this.values[f] = this.element.value; } else{ if(this.field[MJS_REQUIRED]){ return this.chk_error(); } } break; case this.MJS_D: // date req_if_ord = MJS_DATE_REQ_IF; var val = $.trim(this.element.value); this.values[f] = this.value = val = val.replace(/^\s+|\s+$/g,''); if(val){ if(!MOCA_REGEXP_date.test(val)){return this.val_error();} if(start_date = this.field[MJS_DATE_RANGE_START]){ if(sval = $('#mf_'+ this.field[MJS_TYPE] + '_' + start_date).val()){ var sD,eD; if(bits = MOCA_REGEXP_date.exec(sval)){ sD = new Date(bits[3],bits[2]-1,bits[1]); } if(bits = MOCA_REGEXP_date.exec(val)){ eD = new Date(bits[3],bits[2]-1,bits[1]); } if(sD && eD){ // If not true will get caught above if(sD >= eD){ return this.range_error(sD,eD); } } } } } else { if(this.field[MJS_REQUIRED]){return this.chk_error();} } break; } if(this.field[req_if_ord] && !this.value){ // eg: this.required_if['component_key'] = 'has_component' this.required_if[f] = this.field[req_if_ord]; } } if(this.required_if){ for(var f in this.required_if){ if(this.values[this.required_if[f]]){ this.field = this.fields[f]; this.element = this.els[f]; this.that = this.fields[this.required_if[f]]; return this.req_if_error(); } } } return true; }, req_error:function(){ return this.error(this.field[MJS_NAME] + ' is a required field'); }, val_error:function(){ return this.error('"' + this.value + '" is not a valid value for the ' + this.field[MJS_NAME] + ' field'); }, min_error:function(){ return this.error('Your ' + this.field[MJS_NAME] + ' value must be at least ' + this.field[MJS_TEXT_MIN] + ' characters in length'); }, max_error:function(){ return this.error('Your ' + this.field[MJS_NAME] + ' value must be less than ' + this.field[MJS_TEXT_MAX] + ' characters in length'); }, sel_error:function(){ return this.error('You must select a value from the ' + this.field[MJS_NAME] + ' list to continue'); }, grp_error:function(){ return this.error('You must select a value for ' + this.field[MJS_NAME] + ' to continue'); }, chk_error:function(){ return this.error('You must tick the ' + this.field[MJS_NAME] + ' checkbox to continue'); }, req_if_error:function(){ var verbed = this.field[MJS_TYPE]==this.MJS_C || this.field[MJS_TYPE]==this.MJS_S ? 'selected' : 'entered'; return this.error('You must provide a value for ' + this.field[MJS_NAME] + ' if ' + this.that[MJS_NAME] + ' is ' + verbed); }, range_error:function(s,e){ return this.error('You have entered an invalid date range:
('+s.mocaToString() + ' to '+e.mocaToString()+')'); }, error:function(str){ if(this.field[MJS_TYPE] != this.MJS_RG && this.field[MJS_TYPE] != this.MJS_CG){ var bg = this.element.style.backgroundColor; this.element.style.backgroundColor = MJS_COLOUR_ERROR; var revert = function(){this.style.backgroundColor=bg;}; this.element.onclick = revert; this.element.onkeydown = revert; this.element.focus(); } mocaAlert(str); } }; function formError(el_id,msg){ // formError('element_id','error_msg' [, 'title', 'functionOnDismiss']); // Class function - first arg must be element_id, // second is alert message, third is alert title, // fourth is function to be executed on alert // dismissal. Only the first two are mandatory var title = arguments[2] ? arguments[2] : ''; var func = arguments[3] ? arguments[3] : null; var el = document.getElementById(el_id); var bg = el.style.backgroundColor; el.style.backgroundColor = MJS_COLOUR_ERROR; var revert = function(){this.style.backgroundColor=bg;}; el.onclick = revert; el.onkeydown = revert; el.focus(); mocaAlert(msg,title,func); return false; }