// ******************************* 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;
}