Essential utility functions

9th January 2014

There are functions that you create that you use all of the time. These functions are invaluable and are usually very small snippets of code. I have put them all together into one easy to use class. To use a method on the class just type 'Util.methodName(parameters)'.

Overview

Method nameParametersReturnsNotes
uniqid   a random id number (alphanumeric) compatible with php uniqid, derived from php.js
each object, function boolean based on success  return false in function to stop iteration
extend obj1, obj2, noOverwrite (optional) obj1 with properties from obj2  
getType obj string denoting type e.g. "number"  
clone obj, deep (optional) a new object with the same data if deep if true, it becomes recursive
filter arr, func a new array with filtered elements can use array.filter instead
find arr, obj, strict the found index or false on failure  strict uses ===
unique arr returns all unique values in arr  
first obj the first value   
arrToObjectKeys arr object with keys from arr values are 'null'
objectKeys obj array of keys can use Object.keys instead
objectValues obj array of values   
firstKey obj first object key (string)  
emptyObject obj boolean   
objectSize obj number of keys  
isA obj, obj2 boolean - objects are same type   
isString obj boolean  
isNumber obj  boolean  
isArray obj boolean  
isObject obj boolean  
isFunction obj boolean  
isBoolean obj boolean  
asBoolean obj boolean 'false', null, 0, NaN is false
isNumeric str boolean  ensures a number or as string
empty obj boolean   
isset obj  boolean undefined or null is false
getFileExt str extension   
br2nl str string  
changeFileExt str string  
escapeRegex str regex safe literal word  
trim str, trimCharLeft, trimCharRight (optional) string defaults: trimCharLeft = ','
basename path string  
zeroFill num, places, fillChar (optional) string defaults: fillChar = '0', places='2'
dateToInput date string HTML5 date input compatible
escapeHTML string html safe string   
randAlpha len string defaults: len = 32
ucwords str string uppercase words, from php.js
parseQueryData str object of key, values  
escapeQueryData object str reverse of above
roundDP num, numDP number defaults: numDP = 2
formatSize size string shows 1 decimal place, 'B', 'KB', 'MB' 
formatDateTime date string format: 'Y-M-d h:i:s'
reverse str string   
quote str string   
unquote str string  reverse of above
backquote str string  
addslashes str string from php.js
toClassName str string   
unbackquote str string  
validVarName str boolean  
varnameToTitle str string  
urlencode str string   
urldecode str string  
ord str number from php.js
chr  code string from php.js 
getDaySuffix dayNum string returns 'st', 'nd', 'rd' or 'th'
unionFuncs func1, func2 ... function join functions together

Javascript

var Util = {
//number methods
uniqid: function() {
function formatSeed(seed, reqWidth) {
seed = parseInt(seed, 10).toString(16);
if (reqWidth < seed.length) {
return seed.slice(seed.length - reqWidth);
}
if (reqWidth > seed.length) {
return Array(1 + (reqWidth - seed.length)).join('0') + seed;
}
return seed;
}

if (!this.uniqidSeed) {
this.uniqidSeed = Math.floor(Math.random() * 0x75bcd15);
}

this.uniqidSeed++;

return formatSeed(parseInt(new Date().getTime() / 1000, 10), 8) + formatSeed(this.uniqidSeed, 5);
},

//array/object methods
each: function(obj, func) {
if (obj) {
if (obj.constructor===[].constructor) {
for (var i=0; i<obj.length; i++) {
if (func(obj[i], i, obj)===false) {
return false;
}
}
} else {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (func(obj[key], key, obj)===false) {
return false;
}
}
}
}
}

return true;
},
extend: function(obj1, obj2, noOverwrite) { //extend obj1 with properties of obj2
obj1 = obj1 || {};
obj2 = obj2 || {};

if (noOverwrite) {
for (var key in obj2) {
if (!obj1.hasOwnProperty(key)) {
obj1[key] = obj2[key];
}
}
} else {
for (var key in obj2) {
obj1[key] = obj2[key];
}
}

return obj1;
},
getType: function(obj) {
if (obj===undefined || obj===null) return "null";

switch (obj.constructor) {
case ([].constructor): return "array";
case ({}.constructor): return "object";
case ((0).constructor): return "number";
case ((function() {}).constructor): return "function";
case (("").constructor): return "string";
case ((true).constructor): return "boolean";
case ((new Date()).constructor): return "date";
case ((new RegExp()).constructor): return "regexp";
}

return "unknown";
},
clone: function(obj, deep) {
switch (Util.getType(obj)) {
case "null": return null;
case "object":
var newObj = {};

if (deep) {
Util.each(obj, function(val, key) {
newObj[key] = Util.clone(val, true);
});
} else {
Util.each(newObj, function(val, key) {
newObj[key] =val;
});
}

return newObj;
case "array":
var newArr = [];

if (deep) {
Util.each(obj, function(val) {
newArr.push(Util.clone(val, true));
});
} else {
Util.each(obj, function(val) {
newArr.push(val);
});
}

return newArr;
case "function":
case "number":
case "string":
case "boolean":
case "date":
case "regexp":
return obj;
}

return null;
},
filter: function(arr, func) {
var filtered = [];

Util.each(arr, function(val) {
if (func(val)!==false) {
filtererd.push(val);
}
});

return filtered;
},
find: function(arr, obj, strict) {
var index = false;

if (strict) {
Util.each(arr, function(obj2, i) {
if (obj===obj2) {
index = i;
return false;
}
});
} else {
Util.each(arr, function(obj2, i) {
if (obj==obj2) {
index = i;
return false;
}
});
}

return index;
},
unique: function(arr) {
var uniqueVals = [];

Util.each(arr, function(val) {
if (Util.find(uniqueVals, val, true)===false) {
uniqueVals.push(val);
}
});

return uniqueVals;
},
first: function(obj) {
if (obj.constructor==[].constructor) {
if (obj.length) {
return obj[0];
}
} else {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
return obj[key];
}
}
}

return null;
},
arrToObjectKeys: function(arr) {
var obj = {};

for (var i=0; i<arr.length; i++) {
obj[arr[i]] = null;
}

return obj;
},
objectKeys: function(obj) {
var keys = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
keys.push(key);
}
}
return keys;
},
objectValues: function(obj) {
var vals = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
vals.push(obj[key]);
}
}
return vals;
},
firstKey: function(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
return key;
}
}

return null;
},
emptyObject: function(obj) {
return Util.firstKey(obj) === null;
},
objectSize: function(obj) {
return Util.objectKeys(obj).length;
},
isA: function(obj, obj2) {
if (Util.isSet(obj)) {
return (obj.constructor === obj2.constructor);
} else {
return !Util.isSet(obj2);
}
},

isString: function(obj) { return Util.isA(obj, "") },
isNumber: function(obj) { return Util.isA(obj, 0) },
isArray: function(obj) { return Util.isA(obj, []) },
isObject: function(obj) { return Util.isA(obj, {}) },
isFunction: function(obj) { return Util.isA(obj, function() {}) },
isBoolean: function(obj) { return Util.isA(obj, true) },

asBoolean: function(obj) {
if (!Util.isset(obj)) return false;

var num = parseFloat(obj);
if (!isNaN(num) && num==0) return false;

if (obj==false) return false;

if (obj.toString().toLowerCase()=="false") return false;

return true;
},

isNumeric: function(str) {
if (Util.isString(str)) {
var num = parseFloat(str);
return !isNaN(num) && str.replace(/\.0+$/,"") === num;
} else if (Util.isNumber(str)) {
return true;
}
},

empty: function(obj) {
return !obj || (obj.length && obj.length==0);
},

isSet: function(obj) {
return (obj!==undefined && !Util.isNull(obj));
},

isset: function(obj) {
return Util.isSet(obj);
},

isNull: function(obj) {
return obj===null;
},
//string methods
getFileExt: function(filename) {
var extPos = filename.lastIndexOf(".");
if (extPos>=0) {
return filename.substring(extPos+1);
} else {
return "";
}
},
br2nl: function(str) {
return str.replace(/\<br\>/g, "\n");
},
changeFileExt: function(filename, newExt) {
var ext = Util.getFileExt(filename);
return filename.substring(0, filename.length-ext.length) + newExt;
},
escapeRegex: function(str) {
return str.replace(/([\[\]\\\^\$\.\|\?\*\+\(\)\{\}])/g, "\\\$1");
},
trim: function(str, trimCharLeft, trimCharRight) {
if (trimCharLeft===undefined) trimCharLeft = ' ';
if (trimCharRight===undefined) trimCharRight = trimCharLeft;

return str.replace(new RegExp("^(" + Util.escapeRegex(trimCharLeft) + ")*|(" + Util.escapeRegex(trimCharRight) + ")*$", "g"), "");
},
basename: function(path) {
return path.replace(/^.*[\/\\]/g, '');
},
zeroFill: function(num, places, fillChar) {
if (places===undefined) places = 2;
if (fillChar===undefined) fillChar = "0";

var numStr = num.toString();

for (var i=numStr.length; i<places; i++) {
numStr = fillChar + numStr;
}

return numStr;
},
dateToInput: function(date) {
return [date.getFullYear(), Util.zeroFill(date.getMonth()+1), Util.zeroFill(date.getDay())].join("-");
},
escapeHTML: function(str) {
return str.replace(/\&/g,'&amp;').replace(/\</g, '&lt;').replace(/\>/g, '&gt;').replace(/\"/g, '&quot;');
},
ALPHANUMERIC: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
randAlpha: function(len) {
len = len || 32;

var temp = [];
for (var i=0; i<len; i++) {
temp.push(Util.ALPHANUMERIC[Math.floor(Math.random()*62)]);
}

return temp.join('');
},
ucwords: function(str) {
return (str + '').replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function(str) {
return str.toUpperCase();
});
},
parseQueryData: function(str) {
var matches = str.split("&");

var params = {};
for (var i=0; i<matches.length; i++) {
var match = matches[i];
var parts = match.split("=");

if (parts.length==2) {
var partName = parts[0];
var partValue = parts[1];

if (partName.match(/\[\]$/)) {
partName = partName.substring(0, partName.length-3);

if (params.hasOwnProperty(partName) && params[partName].constructor === [].constructor) {
params[partName].push(partValue);
} else {
params[partName] = [partValue];
}
} else {
params[partName] = partValue;
}
}
}

return params;
},
escapeQueryData: function(data) {
var groups = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
groups.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
}
}

return groups.join("&");
},
roundDP: function(num, numDP) {
if (numDP === undefined) numDP = 2;
var temp = Math.pow(10, numDP);

return Math.round(num * temp) / temp;
},
formatSize: function(size) {
var str = parseInt(size).toString();

if (str.length>5) {
//show the result in mb
return Util.roundDP(size / 1048576, 1) + "MB";
} else if (str.length>2) {
//show the result in kb
return Util.roundDP(size / 1024, 1) + "KB";
} else {
//show the result in bytes
return size + "B";
}
},
formatDateTime: function(d) {
if (d===undefined) {
d = new Date();
}

return d.getFullYear() + '-' + Util.zeroFill(d.getMonth()+1,2)+'-'+Util.zeroFill(d.getDate(),2)+" "+Util.zeroFill(d.getHours(),2)+":"+Util.zeroFill(d.getMinutes(),2)+":"+Util.zeroFill(d.getSeconds(),2);
},
reverse: function(str) {
return str.split("").reverse().join("");
},
quote: function(str) {
return "'" + Util.unquote(str) + "'";
},
unquote: function(str) {
return Util.trim(str, "'");
},
backquote: function(str) {
return "`" + Util.unbackquote(str) + "`";
},
addslashes: function(str) {
return str.replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
},
toClassName: function(str) {
return str.toLowerCase().replace(/[\s,\-]+/g, "_").replace(/[^a-z0-9\_]/g, "");
},
unbackquote: function(str) {
return Util.trim(str, "`");
},
validVarname: function(str) {
var matches = str.match(/[a-zA-Z_$][0-9a-zA-Z_$]*/);
return matches && matches.length==1;
},
varnameToTitle: function(str) {
//insert spaces at capitals
return Util.trim(Util.capitalCase(str.replace(/[A-Z]/g, " $&")));
},
urlencodeCharacter: function(c) {
return '%' + c.charCodeAt(0).toString(16);
},
urldecodeCharacter: function(str, c) {
return String.fromCharCode(parseInt(c, 16));
},
urlencode: function(s) {
return encodeURIComponent(s).replace(/\%20/g, '+').replace(/[!'()*~]/g, Util.urlencodeCharacter);
},
urldecode: function(s) {
return decodeURIComponent(s.replace(/\+/g, '%20')).replace(/\%([0-9a-f]{2})/g, Util.urldecodeCharacter);
},
ord: function(string) {
var str = string + '', code = str.charCodeAt(0);

if (0xD800 <= code && code <= 0xDBFF) { // High surrogate
var hi = code;
if (str.length === 1) {
return code;
}

var low = str.charCodeAt(1);
return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
}

if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
return code;
}

return code;
},

chr: function(codePt) {
if (codePt > 0xFFFF) {
codePt -= 0x10000;
return String.fromCharCode(0xD800 + (codePt >> 10), 0xDC00 + (codePt & 0x3FF));
}

return String.fromCharCode(codePt);
},
getDaySuffix: function(dayNum) {
dayNum = dayNum.toString();

//teens are all 'th'
if (dayNum.length && (dayNum.length<2 || dayNum[dayNum.length-2]!="1")) {
switch (dayNum[dayNum.length-1]) {
case "1": return "st";
case "2": return "nd";
case "3": return "rd";
}
}

return 'th';
},
unionFuncs: function() {
var args = arguments;

//return a function that calls the functions
return function() {
//combine the functions to be called in order from the arguments
for (var i=0, nextFunc = null; i<args.length; i++) {
nextFunc = args[i];

if (nextFunc) {
nextFunc.apply(this, arguments);
}
}
};
}
};

Comments

This is pretty old now, I would recommend using a library, like lodash.js as a replacement for a lot of the methods above.
Andrew Lowndes - 10th Oct 2016 20:11

Make a comment

Contribute to this article and have your say.