// assign global object to prostores variable var prostores = window; if (typeof prostores.ProStores == "undefined") prostores.ProStores = {}; prostores.ProStores.namespace = function() { for (var i = 0; i < arguments.length; ++i) { var aParts = arguments[i].split("."); var objCurrentObject = ProStores; // ProStores is implied, so it is ignored if it is included for (var j = (aParts[0] == "ProStores") ? 1 : 0; j < aParts.length; ++j) { objCurrentObject[aParts[j]] = objCurrentObject[aParts[j]] || {}; objCurrentObject = objCurrentObject[aParts[j]]; } } }; // Create the util namespace. ProStores.namespace("util"); /* ----------------------- The following block of code holds functions that centralize common patterns, reduce typing, use optimizatins, or simply make it easier to write javascript. The names of these functions, as well as the variables used within them start with the _ (underscore) to help avoid namespace collisions. -------------------------*/ /* This flag enables/disabled element caching on the _element calls. Default is false, so clients must set to true to take advantage of this. */ ProStores.ElementCacheEnabled = false; /* Convenience function, shorthand for document.getElementById. If ProStores.ElementCacheEnabled is set to true, elements will be cached for future lookups. */ prostores._element = function(_strId) { var el; if (_strId) { if (ProStores.ElementCacheEnabled) { if (!ProStores._elementCache) ProStores._elementCache = new ProStores.util.HashMap(); el = ProStores._elementCache.get(_strId); if (!el) { el = document.getElementById(_strId); if (el) ProStores._elementCache.put(_strId, el); } } else el = document.getElementById(_strId); } return el; } /* _foreach(_list, _fcnInvoke) iterates over an array or list (_list), and invokes the passed-in function (_fcnInvoke) on each iteration with the current element in the list as the first argument and the index within the list as the second argument. The iteration will prematurely break of _fcnInvoke returns false. */ prostores._foreach = function(_list, _fcnInvoke) { var _len = _list.length; for (var _i = 0; _i < _len; _i++) { if (_fcnInvoke(_list[_i], _i) == false) break; } }; /* --------------------------------------------------------------- The following block of code is used to add functionality to some default objects. Common-use functions are added (and documented here) but special-use functions are defined elsewhere. To help with maintenence, other additions to default objects are listed here along with the location of the implementation. ---------------------------------------------------------------- String gets: trim() returns the string with all leading and trailing whitespace removed. LPad(numLength, strPadding) returns the string to padded on the left with RPad(numLength, strPadding) returns the string to padded on the right with // DEFINED ELSEWHERE toJSONString() returns the string as as a JSON string. defined in: AdminCommon/js_ps-json.js */ // Behaves as does java.lang.String.trim() String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); }; String.prototype.LPad = function(numLength, strPadding) { var thisCopy = this; if (strPadding && typeof strPadding == "string" && strPadding.length > 0 && numLength && typeof numLength == "number") { while (thisCopy.length < numLength) thisCopy = strPadding + thisCopy; if (thisCopy.length > numLength) thisCopy = thisCopy.substring(thisCopy.length - numLength); } return thisCopy; }; String.prototype.RPad = function(numLength, strPadding) { var thisCopy = this; if (strPadding && typeof strPadding == "string" && strPadding.length > 0 && numLength && typeof numLength == "number") { while (thisCopy.length < numLength) thisCopy += strPadding; if (thisCopy.length > numLength) thisCopy = thisCopy.substring(0, numLength); } return thisCopy; }; /* Array gets: // DEFINED ELSEWHERE toJSONString() returns the Array as as a JSON string. defined in: AdminCommon/js_ps-json.js Date gets: Constants: MILLIS_IN_SECOND MILLIS_IN_MINUTE MILLIS_IN_HOUR MILLIS_IN_DAY Functions: getDayOfYear() returns the day of the year for the date (1-365) getDaysSince(date) returns the number of days since the argument getHoursSince(date) returns the number of hours since the argument getMinutesSince(date) returns the number of minutes since the argument getSecondsSince(date) returns the number of seconds since the argument getYearsSince(date) returns the number of years since the argument // DEFINED ELSEWHERE toJSONString() returns the date as as a JSON string. defined in: AdminCommon/js_ps-json.js */ Date.MILLIS_IN_SECOND = 1000; Date.MILLIS_IN_MINUTE = Date.MILLIS_IN_SECOND * 60; Date.MILLIS_IN_HOUR = Date.MILLIS_IN_MINUTE * 60; Date.MILLIS_IN_DAY = Date.MILLIS_IN_HOUR * 24; /* Returns the day of the year, from 1-365 */ if (!Date.prototype.getDayOfYear) { Date.prototype.getDayOfYear = function() { var year = this.getFullYear(); return (Date.UTC(year, this.getMonth(), this.getDate()) - Date.UTC(year, 0, 0)) / 86400000; }; Date.prototype.MONTHS = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]; Date.prototype.DAYS = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ]; Date.prototype.format = function(strFormat) { var strOut = ""; if (strFormat) { if (!this.formater) { this.formatter = {}; var year = Number(this.getYear()); if (year < 1900) year += 1900; this.formatter["y"] = String(year); this.formatter["yyyy"] = this.formatter["y"]; this.formatter["yy"] = this.formatter["y"].substring(2, 4); this.formatter["M"] = this.getMonth() + 1; this.formatter["MM"] = String(this.formatter["M"]).LPad(2, "0"); this.formatter["MMM"] = this.MONTHS[this.formatter["M"] - 1]; this.formatter["MMMM"] = this.MONTHS[this.formatter["M"] + 11]; this.formatter["d"] = this.getDate(); this.formatter["dd"] = String(this.formatter["d"]).LPad(2, "0"); this.formatter["H"] = this.getHours(); this.formatter["HH"] = String(this.formatter["H"]).LPad(2, "0"); this.formatter["E"] = this.DAYS[this.formatter["H"] + 7]; this.formatter["EE"] = this.DAYS[this.formatter["H"]]; if (this.formatter["H"] == 0) this.formatter["h"] = 12; else if (this.formatter["H"] > 12) this.formatter["h"] = this.formatter["H"] - 12; else this.formatter["h"] = this.formatter["H"]; this.formatter["hh"] = String(this.formatter["h"]).LPad(2, "0"); if (this.formatter["H"] > 11) this.formatter["a"] = this.formatter["H"] > 11 ? "PM" : "AM"; this.formatter["m"] = this.getMinutes(); this.formatter["mm"] = String(this.formatter["m"]).LPad(2, "0"); this.formatter["s"] = this.getSeconds(); this.formatter["ss"] = String(this.formatter["s"]).LPad(2, "0"); } var i = 0; while(i < strFormat.length) { var c = strFormat.charAt(i); var strNextToken = ""; while((strFormat.charAt(i) == c) && (i < strFormat.length)) strNextToken += strFormat.charAt(i++); strOut += this.formatter[strNextToken] ? this.formatter[strNextToken] : strNextToken; } } return strOut; }; } /* Returns the number of years since the passed-in date */ if (!Date.prototype.getYearsSince) { Date.prototype.getYearsSince = function(date) { return this.getUTCFullYear() - date.getUTCFullYear(); }; } /* Returns the number of days since the passed-in date */ if (!Date.prototype.getDaysSince) { Date.prototype.getDaysSince = function(date) { return Math.floor(this.getTime() / Date.MILLIS_IN_DAY) - Math.floor(date.getTime() / Date.MILLIS_IN_DAY); }; } /* Returns the number of hours since the passed-in date */ if (!Date.prototype.getHoursSince) { Date.prototype.getHoursSince = function(date) { return Math.floor(this.getTime() / Date.MILLIS_IN_HOUR) - Math.floor(date.getTime() / Date.MILLIS_IN_HOUR); }; } /* Returns the number of minutes since the passed-in date */ if (!Date.prototype.getMinutesSince) { Date.prototype.getMinutesSince = function(date) { return Math.floor(this.getTime() / Date.MILLIS_IN_MINUTE) - Math.floor(date.getTime() / Date.MILLIS_IN_MINUTE); }; } /* Returns the number of seconds since the passed-in date */ if (!Date.prototype.getSecondsSince) { Date.prototype.getSecondsSince = function(date) { return Math.floor(this.getTime() / Date.MILLIS_IN_SECOND) - Math.floor(date.getTime() / Date.MILLIS_IN_SECOND); }; } /* Boolean gets: // DEFINED ELSEWHERE toJSONString() returns the Boolean as as a JSON string. defined in: AdminCommon/js_ps-json.js Number gets: // DEFINED ELSEWHERE toJSONString() returns the Number as as a JSON string. defined in: AdminCommon/js_ps-json.js Object gets: // DEFINED ELSEWHERE toJSONString() returns the Object as as a JSON string. defined in: AdminCommon/js_ps-json.js The following block is used for constants that will be used globally */ prostores.JS_TYPE_BOOLEAN = "boolean"; prostores.JS_TYPE_FUNCTION = "function"; prostores.JS_TYPE_NUMBER = "number"; prostores.JS_TYPE_OBJECT = "object"; prostores.JS_TYPE_STRING = "string"; prostores.JS_TYPE_UNDEFINED = "undefined"; /** Below are some useful utility classes: HashMap functions similarly to it's java.util.HashMap equivalent. */ ProStores.util.HashMap = function(){ this.m_storage = {}; }; ProStores.util.HashMap.prototype = { m_storage: null, /* * Removes all entries from the Map. */ clear: function() { for (i in this.m_storage) { if (this.m_storage[i] instanceof ProStores.util.HashMap.prototype.MapEntry) { var strKey = this.m_storage[i].getName(); if (strKey) delete this.m_storage[strKey]; } } }, /* * Returns the MapEntry objects existing in the Map in an Array. */ entries: function() { var aEntries = new Array(); for (i in this.m_storage) { if (this.m_storage[i] instanceof ProStores.util.HashMap.prototype.MapEntry) aEntries.push(this.m_storage[i]); } return aEntries; }, /* * Returns object specified by given key.. */ get: function(strKey) { var objReturn; if (strKey) { var entry = this.m_storage[strKey]; if (entry && entry.getValue() && entry.getName() == strKey) objReturn = entry.getValue(); } return objReturn; }, /* * Returns the keys existing in the Map as an Array object. */ keys: function() { var aKeys = new Array(); var aEntries = this.entries(); _foreach(aEntries, function(item, index) { if (item instanceof ProStores.util.HashMap.prototype.MapEntry) aKeys.push(item.getName()); }); return aKeys; }, MapEntry: function(strName, objValue) { this.m_strName = strName; this.m_objValue = objValue; }, /* * Puts an object into the Map with the specified key. */ put: function(strKey, objValue) { if (strKey) this.m_storage[strKey] = new this.MapEntry(strKey, objValue); }, /* * Deletes the value in the Map and returns the deleted * value if it was deleted. */ remove: function(strKey) { var objReturn = this.get(strKey); if (strKey) delete this.m_storage[strKey]; return objReturn; }, toJSONString: function() { return this.entries().toJSONString(); }, /* * Returns the values existing in the Map in an Array object. */ values: function() { var aValues = new Array(); var aEntries = this.entries(); _foreach(aEntries, function(item, index) { if (item instanceof ProStores.util.HashMap.prototype.MapEntry) aValues.push(item.getValue()); }); return aValues; } }; ProStores.util.HashMap.prototype.MapEntry.prototype = { m_strName: null, m_objValue: null, getName: function() { return this.m_strName; }, getValue: function() { return this.m_objValue; }, toJSONString: function() { var obj = {}; obj[this.getName()] = this.getValue(); return obj.toJSONString(); } }; /* The NVP function serves as a base class to several small key-value pairs. This class provides convenience methods that convert data from one datatype to another */ ProStores.util.NVP = function(strName, objValue) { with (this) { m_strName = strName; m_objValue = objValue; } }; ProStores.util.NVP.prototype = { m_strName: null, m_objValue: undefined, getAsBoolean: function() { var bReturn = false; var objValue = this.getValue(); if (objValue) { if (typeof objValue == JS_TYPE_BOOLEAN) bReturn = objValue; else if (typeof objValue == JS_TYPE_OBJECT && objValue.constructor == Boolean) bReturn = objValue.valueOf(); else if (typeof objValue == JS_TYPE_STRING) bReturn = objValue.toLowerCase() == "true"; } return bReturn; }, getAsDate: function() { var dtReturn = null; var nAsNumber = this.getAsNumber(); if (nAsNumber && !isNaN(nAsNumber)) { dtReturn = new Date(); dtReturn.setTime(Math.floor(nAsNumber)); } return dtReturn; }, getAsNumber: function() { return isNaN(this.getValue()) ? null : Number(this.getValue()); }, getAsString: function() { return String(this.getValue()); }, getName: function() { return this.m_strName; }, getValue: function() { return this.m_objValue; }, setValue: function(objValue) { this.m_objValue = objValue; } };