/* Auto form handling etc */ var form = { // set to automatically hide passed elements autohideTimer: 0, singleError: false, errorElements: [], okText: " ", init: function() { var s = byTag("SELECT"); for (var i = 0, l = s.length; i < l; i ++) { if (s[i].disabled) { form.fixDisabled(s[i]); } } }, // form handling setup setup: function(rules, f) { f = $(f); for (var id in rules) { // apply to single element or group of elements (checkboxes / radios) if ($(id) || f.elements[id + "[]"]) { var objs = ($(id)) ? [$(id)] : f.elements[id + "[]"]; for (var q = 0, l2 = objs.length; q < l2; q ++) { objs[q].ruleSet = rules[id].rules; objs[q].errorObj = (rules[id].errorObj) ? rules[id].errorObj : id + "_err"; objs[q].onError = (rules[id].onError) ? rules[id].onError : form.error; objs[q].validateRules = function() { this.errorString = ""; for (var x = 0, l = this.ruleSet.length; x < l; x ++) { if (! form.validateRule(this, this.ruleSet[x])) { //if (this.name.match(/name/)) alert(this.ruleSet[x] + " fail"); return false; } } return true; } // assign for any events if (rules[id].validationEvents) { for (var p = 0, k = rules[id].validationEvents.length; p < k; p ++) { Event.add(objs[q], rules[id].validationEvents[p], function(e) { var obj = Event.target(e); var r = obj.validateRules() ; if (!r && typeof(obj.form.submitted) != "undefined") { obj.onError(); if (form.singleError) { return false; } } else if (r) { obj.onError(); } }, false); } } } } } }, // go through enabling elements for disabled forms enableForm: function(f, obj) { obj.innerHTML = "SAVE"; for (var q = 0, l = f.elements.length; q < l; q ++) { if (f.elements[q].disabled) { this.enableElement(f.elements[q]); } } var d = ["img", "iframe"]; for (var x = 0, y = d.length; x < y; x ++) { var i = byTag(d[x]); for (var q = 0, l = i.length; q < l; q ++) { if (i[q].className == "fixy") { i[q].style.display = "none"; } } } }, // enable a single element enableElement: function(el) { el.disabledState = 1; el.disabled = false; el.className = el.className.replace(/ ?disabled/, ""); }, // setup images over top of disabled elements fixDisabled: function(el) { // *cough* border hide var eTop = position(el, "Top"), eLeft = position(el, "Left"), eWidth = el.offsetWidth, IE = (document.all) ? 1 : 0, y = 0, p = (IE) ? 0 : 2; var y = 0; do { for (var x = 0; x < 2; x ++) { if (x || IE) { var i = create(x ? "img" : "iframe"); i.src = (x) ? "images/clear.gif" : "about:blank"; i.className = "fixy" i.style.left = eLeft + "px"; i.style.top = (eTop + p) + "px"; switch (y) { // right border case 0 : i.style.left = (position(el, "Right") - 20) + "px"; break; // left border case 1 : i.style.width = "3px"; break; // top border case 2 : i.style.height = "2px"; i.style.width = eWidth + "px"; break; // bottom border case 3 : i.style.top = (eTop - 3 + el.offsetHeight) + "px"; i.style.height = "2px"; i.style.width = eWidth + "px"; break; } document.body.appendChild(i); } } y ++; // only ie keeps the borders so need four images if (y > 3 || !IE) { break; } } while (1); if (IE) el.style.visibility = "visible"; }, // check condition is met checkCondition: function(con, obj) { var oStr = (con.obj == 'this') ? "obj" : "$('" + con.obj + "')"; // handle types switch (con.type) { case "length" : eval("var conditionPassed = (" + oStr + ".value.length " + con.rule + ");"); break; default: eval("var conditionPassed = (" + oStr + ".value " + con.rule + " '" + con.value + "');"); } if (! conditionPassed) { var i = $(obj.id + "_err"); if (i) { i.style.display = "none"; } return true; } return false; }, // validate a rule validateRule: function(obj, rule) { // check to make sure the rule condition is met if (rule.condition && form.checkCondition(rule.condition, obj)) { return true; } switch (rule.type) { // check length case "length" : eval("var result = (obj.value.length " + rule.rule + ");"); if (! result) { obj.errorString = form.getErrorStr(rule, "character"); } return result; break; // check for valid email address case "email" : var result = (obj.value.match(/[a-z0-9-]+@[a-z0-9-]{2,}\.[a-z]{2,3}/gi)); if (! result) { if (rule.error) { obj.errorString = rule.error; } else { obj.errorString = "please provide a valid email"; } } return result; break; // check for valid url case "url" : var result = (obj.value.match(/(https?:\/\/)?([a-z0-9-]{2,}\.)?[a-z0-9-]{2,}\.([a-z]{2,})/i)); if (! result) { if (rule.error) { obj.errorString = rule.error; } else { obj.errorString = "please provide a valid url"; } } return result; break; // check for valid email address case "regexp" : var re = new RegExp(rule.rule, "i"); var result = obj.value.match(re); if (! result) { if (rule.error) { obj.errorString = rule.error; } else { obj.errorString = "invalid format"; } } return result; break; // check checkboxes case "checkbox" : // count selected checkboxes var c = 0; for (var x = 0, l = obj.form[obj.name].length; x < l; x ++) { if (obj.form[obj.name][x].checked) { c ++; } } eval("var result = (c " + rule.rule + ");"); if (! result) { obj.errorString = form.getErrorStr(rule, "selection"); } return result; break; // check value case "value" : eval("var result = (obj.value " + rule.rule + " " + rule.value + ");"); if (! result) { if (rule.error) { obj.errorString = rule.error; } else { obj.errorString = "required"; } } return result; break; default: alert("check type " + rule.type + " is not defined"); return false; } return true; }, // get error string for >=<= rule elements getErrorStr: function(rule, type) { if (rule.error) { return rule.error; } else { var m = rule.rule.match(/>=? ?([0-9]+)/); if (m) { if (!parseInt(m[1])) { return "required"; } else { return "at least " + m[1] + " " + type + ((m[1] == 1) ? "" : "s"); } } else { var m = rule.rule.match(/([0-9]+)$/); return "less than " + m[1] + " " + type + ((m[1] == 1) ? "" : "s"); } } }, // default handling of errors error: function() { var id = (this.id) ? this.id : this.name.replace(/\[\]/, ""); var i = $(this.errorObj); if (this.errorString.replace(/\s/, "").length) { if (! i) { i = create("span"); i.id = this.errorObj; this.parentNode.insertBefore(i, this.nextSibling); } i.className = "formError"; i.style.display = ""; i.innerHTML = this.errorString; form.errorElements.push(id + " : " + this.errorString); } else if (i) { i.innerHTML = form.okText; i.className = "formOk"; if (form.autohideTimer) { setTimeout("$('" + id + "_err').style.display = 'none';", form.autohideTimer); } } }, // run checks on form elements runChecks: function(f) { var pass = true, multi = []; form.errorElements = []; for (var q = 0, l = f.elements.length; q < l; q ++) { if (f.elements[q].validateRules) { // make sure multiple radio / checkboxes only run checks once if (f.elements[q].name.match(/\[\]$/)) { // already done if (multi.has(f.elements[q].name)) { continue; } multi.push(f.elements[q].name); } // check rules if (! f.elements[q].validateRules()) { f.elements[q].onError(); pass = false; if (form.singleError) { break; } } } } return pass; }, // handle form (switch submit and images to passable elements) autoHandle: function(e, ret) { var obj = Event.target(e); obj.blur(); var f = obj.form; f.submitted = 1; Event.stop(e); if (form.runChecks(f)) { if (ret) { return true; } var oType = ""; if (obj.type == "submit" || obj.type == "hidden") { oType = obj.type; // IE wont allow type switching for security reasons if (document.all) { var s = create(obj.outerHTML.replace(/type=\"?(submit|image)\"?/, "type=\"hidden\"")); obj.parentNode.replaceChild(s, obj); } else { obj.type = "hidden"; } } f.submit(); if (oType.length) { // IE wont allow type switching for security reasons if (document.all) { obj = create(s.outerHTML.replace(/type=\"?hidden\"?/, "type=\"" + oType + "\"")); s.parentNode.replaceChild(obj, s); } else { obj.type = oType; } } return true; } else { return false; } } }; // setup auto form handling Event.add(window, "load", form.init, false); // setup ajax forms and links Event.add(window, "load", function() { var x = ["form", "a"]; for (var g = 0, l2 = x.length; g < l2; g++) { var els = byTag(x[g]); for (var q = 0, l = els.length; q < l; q ++) { var r = els[q].getAttribute("rel"); if (r) { var m = r.match(/(ajax):(.+)$/); if (m && m[1] == "ajax") { switch (x[g]) { // handle forms case "form" : // override submit els[q].submitCallback = m[2]; els[q].onsubmit = document.forms[q].submit = function() { // run callback try { eval(this.submitCallback + "();"); } catch (e) { if (! String(e).match(/TypeError:.*is not a function/)) { eval(this.submitCallback + ";"); } } return false; } break; // handle links case "a" : // override submit els[q].clickCallback = m[2]; els[q].onclick = function(e) { try{ var f = eval(this.clickCallback); } catch(e) { var f = this.clickCallback; } Ajax.Request(this.href + (this.href.match(/\?/) ? "&ajax=1" : "?ajax=1"), {form:$("caption"), callback:f}); return false; } break; } } } } } }, false);