// ******************************* VALIDATE.JS ****************************** // * // * Description: Client-side JavaScript functions - form validation // * // * To include in HTML file use: // * // * // * // * -------------------------------------------------------------------------- function GiveAlert(Message, fld) { if(fld) { fld.focus(); if(fld.select && typeof(fld.select) == "function") // Text field? fld.select(); } alert(Message); return false; } // // Check if a number is a valid hex number // function IsHex(Value,AlertOn) { // Default value var AlertOn = (AlertOn == null) ? 0 : AlertOn; var ValueIsHex = Value.match(/^[0-9a-f]+$/i); if (!ValueIsHex && AlertOn) { alert ("Value " + Value + " is not a valid hex number"); } return ValueIsHex; } // // Check if a number is a valid digit number // function IsDigit(Value,AlertOn) { // Default value var AlertOn = (AlertOn == null) ? 0 : AlertOn; ValidChars = "0123456789"; var ValueIsDigit = true; // check for valid charaters for (var i = 0 ; i <= Value.length; i ++ ) { var ValueChar = Value.charAt(i); if (ValidChars.indexOf(ValueChar) == -1 ) { ValueIsDigit = false; } } if (!ValueIsDigit && AlertOn) { alert ("Value " + Value + " is not a valid digit number"); } return ValueIsDigit; } // // Check if a number is a valid integer // function isInt (str) { var i = parseInt (str); if (isNaN (i)) return false; i = i . toString (); if (i != str) return false; return true; } // // Check if a field value is a valid integer // Uses GiveAlert in case of errors // function isIntId(fld_id) { var fld = document.getElementById(fld_id); if(!fld) // Programming error return GiveAlert("No such field: " + fld_id, fld); if(!isInt(fld.value)) // User-input error return GiveAlert("The value " + fld.value + " is not a valid integer", fld); return true; } // isWithinRange() // Function that checks that input value is within a valid range and // gives an error if not. // @fld_id is the name of the field. It's value is used as input in the // check. It's also used to set focus if an error occurs. // @MinVal is included in the valid range. If empty, assumed to be 0 // @MaxVal is included in the valid range. If empty, assumed to be 65535 // @start_text and @end_text are used if an error occurs. The error // will look as follows: // "The value of " + start_text + " is restricted to " + MinVal + " - " + MaxVal + end_text function isWithinRange(fld_id, MinVal, MaxVal, start_text, end_text) { // Default values var minval = (MinVal == null) ? 0 : MinVal; var maxval = (MaxVal == null) ? 65535 : MaxVal; var val; if(!start_text) { start_text = fld_id; // What else to do? } if(!end_text) { end_text = ""; } var fld = document.getElementById(fld_id); if(!fld) // Programming error return GiveAlert("No such field: " + fld_id, fld); val = fld.value; if(val.length == 0) // User-input error return GiveAlert("The value of " + start_text + " cannot be empty", fld); // isNaN() works on a string, so don't parseInt(fld.value) // before calling this function, or isNaN() won't be able // to detect e.g. "1K", since parseInt() will parse this // string as '1' first. if(isNaN(val) || val < minval || val > maxval) { return GiveAlert("The value of " + start_text + " is restricted to " + minval + " - " + maxval + end_text, fld); } else { return true; } } // // Input check for MAC address. Returns false if it isn't a valid MAC address else true // function IsMacAddress(Value,AlertOn) { // Default value var AlertOn = (AlertOn == null) ? 0 : AlertOn; // Split the max address up in 6 part ( Allowed format is 00-11-22-33-44-55 or 001122334455 if (Value.indexOf("-") != -1 ) { var MACAddr = Value.split("-"); if(MACAddr.length == 6) { for (var i = 0; i < MACAddr.length; i++) { if (MACAddr[i].length > 2) { if (AlertOn ) {alert ("MAC address contains more than 2 digits")}; return false; } else { if (!IsHex(MACAddr[i],AlertOn)) return false; } } } else { if (AlertOn ) { alert ("MAC should have 6 digit groups")}; return false; } } else{ if (Value.length != 12 ) { if (AlertOn ) { alert ("MAC address must be 12 characters long")}; return false; } if (!IsHex(Value,AlertOn)) return false; } return true; } function IsValidMacAddress(f) { var ret; if(typeof(f) == "string") f = document.getElementById(f); if(!(ret = IsMacAddress(f.value, 1))) f.select(); return ret; } // isIpStr() // Function that checks that input value is a valid IP string (xxx.xxx.xxx.xxx). // @fld_id: is the name of the field. It's value is used as input in the // check. It's also used to set focus if an error occurs. // @is_mask: Set to true if the input must be a mask, i.e. all-ones on the left and all-zeros on the right of the boundary. // @start_text: In case of an error, focus is set to @fld_id and one of the following strings is shown: // "The value of " + start_text + " is not a valid IP address.\nValid IP strings have the format 'xxx.xxx.xxx.xxx' where 'xxx' is a number between 0 and 255." // "The value of " + start_text + " is not a valid IP mask.\nValid IP masks have the format 'xxx.xxx.xxx.xxx' where 'xxx' is a number between 0 and 255." // @allow_what. Used only if @is_mask is false. 'Enumeration' of which IP addresses (x.y.z.w) are allowed. // @allow_what || Allow x > 223 | Allow x == 127 | Allow 0.x.x.x | Allow 0.0.0.0 // ---------------||---------------|----------------|---------------|-------------- // Undefined or 0 || No | No | No | Yes // 1 || No | No | No | No // 2 || Yes | Yes | Yes | Yes // The main validation parts function _isValidIpStr(val, is_mask, allow_what) { var error = false; if(val.length == 0) { // User-input error error = true; } else { var myReg; var show_error = false; myReg = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/; if(myReg.test(val)) { if(RegExp.$1 > 255 || RegExp.$2 > 255 || RegExp.$3 > 255 || RegExp.$4 > 255) { // At least one of ip1, ip2, ip3, or ip4 is not in interval 0-255. error = true; } else if(is_mask) { // Check that the mask is contiguous var ip_as_int = (RegExp.$1 << 24) | (RegExp.$2 << 16) | (RegExp.$3 << 8) | RegExp.$4; var zero_found = false, i; for(i = 31; i >= 0; i--) { if((ip_as_int & (1 << i)) == 0) { // Cleared bit was found. zero_found = 1; } else if(zero_found) { // Set bit was found and cleared bit was previously found => Error error = true; break; } } } else { if(allow_what == 0 || allow_what == 1) { // Disallow x > 223, x == 127, and 0.x.x.x if(RegExp.$1 == 127 || RegExp.$1 > 223) { // ip1 indicates loopback (127), a multicast address (224-239), or an experimental address (240-255). error = true; } else if(RegExp.$1 == 0 && (RegExp.$2 != 0 || RegExp.$3 != 0 || RegExp.$4 != 0)) { // Class 0 is not allowed error = true; } else if(allow_what == 1 && RegExp.$1 == 0 && RegExp.$2 == 0 && RegExp.$3 == 0 && RegExp.$4 == 0) { // 0.0.0.0 is not allowed error = true; } } } } else { // Didn't match regexp error = true; } } return !error; } // Shorthand function function _isValidIpAddress(val) { return _isValidIpStr(val, false, 1); } function isIpStr(fld_id, is_mask, start_text, allow_what) { if(!allow_what || allow_what < 0) { // In case allow_what is undefined allow_what = 0; } else if (allow_what > 2) { allow_what = 2; } var fld = document.getElementById(fld_id); if(!fld) // Programming error return GiveAlert("No such field: " + fld_id, fld); var isok = _isValidIpStr(fld.value, is_mask, allow_what); if(!isok) { if(is_mask) { GiveAlert("The value of " + start_text + " is not a valid IP mask.\n\n" + "A valid IP mask is a dotted decimal string ('x.y.z.w'), where\n" + " 1) x, y, z, and w are decimal numbers between 0 and 255,\n" + " 2) when converted to a 32-bit binary string and read from left to right,\n"+ " all bits following the first zero must also be zero.", fld); } else { if(allow_what == 0 || allow_what == 1) { GiveAlert("The value of " + start_text + " must be a valid IP address in dotted decimal notation ('x.y.z.w').\n\n" + "The following restrictions apply:\n" + " 1) x, y, z, and w must be decimal numbers between 0 and 255,\n" + " 2) x must not be 0" + (allow_what == 0 ? " unless also y, z, and w are 0" : "") + ",\n" + " 3) x must not be 127, and\n" + " 4) x must not be greater than 223.", fld); } else { GiveAlert("The value of " + start_text + " must be a valid IP address in dotted decimal notation ('x.y.z.w'),\n" + "where x, y, z, and w are decimal numbers between 0 and 255.", fld); } } } else { // Get rid of insignificant preceding zeros - if any. // Well, in fact, if a string is preceded by a zero, then it's perceived as an octal number (e.g. parseInt("010") == 8)!! fld.value = parseInt(RegExp.$1) + "." + parseInt(RegExp.$2) + "." + parseInt(RegExp.$3) + "." + parseInt(RegExp.$4); } return isok; } function isIpAddr(fld, text) { return isIpStr(fld, false, text, 1); } function isIpNet(fld, text) { return isIpStr(fld, false, text, 1); } function isIpMask(fld, text) { return isIpStr(fld, true, text, 1); } function IpRangeDiff(ip1, ip2) { var i, diff; ip1 = ip1.split('.'); ip2 = ip2.split('.'); for(diff = i = 0; i < ip1.length; i++) { var d1 = parseInt(ip1[i]) - parseInt(ip2[i]); diff <<= 8; diff += d1; } return diff; } function IpLarger(ip1, ip2) // ip1 > ip2 { var res = IpRangeDiff(ip1, ip2) > 0; return res; } function IpSmaller(ip1, ip2) // ip1 < ip2 { var res = IpRangeDiff(ip1, ip2) < 0; return res; } function IpRangeOverlapping(range1, range2) { var x1, x2, y1, y2; range1 = range1.split('-'); range2 = range2.split('-'); x1 = range1[0]; x2 = range1[1]; y1 = range2[0]; y2 = range2[1]; if(IpLarger(y1, x2) || // y1 > x2 || y2 < x1 IpSmaller(y2, x1)) return false; return true; } function isValidIpRange(f, fname) { if(typeof(f) == "string") f = document.getElementById(f); var ipAddr = f.value.split("-"); if(ipAddr.length != 2) return GiveAlert(fname + " must contain two IP address separated by a \"-\"", f); if(!_isValidIpAddress(ipAddr[0])) return GiveAlert("First IP address in " + fname + " is invalid", f); if(!_isValidIpAddress(ipAddr[1])) return GiveAlert("Second IP address in " + fname + " is invalid", f); if(IpLarger(ipAddr[0], ipAddr[1])) return GiveAlert("Second IP address must be larger than first", f); return true; } function isEmpty(errmsg, f) { if(typeof(f) == "string") f = document.getElementById(f); if(f && f.value.length == 0) return !GiveAlert(errmsg, f); } function trimInput(f) { if(typeof(f) == "string") f = document.getElementById(f); if(f) { var str = f.value; str = str.replace(/^\s+/, ""); str = str.replace(/\s+$/, ""); f.value = str; } return f; } function _isValidHostname(hostname) { while(hostname.length > 0) { var part = hostname.match(/^[A-Za-z0-9][-A-Za-z0-9]*/); if(!part) return false; if(hostname.match(/^\d+$/)) return false; hostname = part.input.substr(part[0].length); if(hostname.length == 0) return true; if(hostname.charAt(0) != '.') return false; hostname = hostname.slice(1); } return false; } function isValidHostOrIP(f, errmsg) { if(typeof(f) == "string") f = document.getElementById(f); if(isEmpty(f, errmsg)) return false; if(!_isValidHostname(f.value) && !_isValidIpStr(f.value, false, 1)) return GiveAlert(errmsg, f); return true; } // Checks whether testStr only contains of characters in containStr function onlyContains(teststr, containstr) { var testStr=teststr; var containStr=containstr; for(var i=0;i maxlen) return GiveAlert(what + " must not exceed " + maxlen + " characters", field); for (var i = 0; i < badchars.length; i++) if (field.value.indexOf(badchars.charAt(i)) != -1) return GiveAlert(what + " contains one or more illegal characters", field); return true; }