/** * Parses a passed in value and returns the boolean equivalent * @param {Number, Boolean, String} value The value to parse into a Boolean. */ var parseBool = function(value) { var boolVal = false; switch (typeof(value)) { case 'number': case 'boolean': boolVal = value; break; case 'string': if (value) { var num = parseInt(value); if (isNaN(num)) { boolVal = (value.toLowerCase() == "false" || value.toLowerCase == "off" ? false : Boolean(value)); } else { boolVal = num; } } else { boolVal = false; } break; } return boolVal; } Object.extend(Form.Element, { /** * Sets a form element's value * * @param {Object, String} element The form element to set * @param {Any} value The value to set on the form element * @return {Boolean} Whether or not the set succeeded. */ setValue: function(element, value) { element = $(element); var method = element.tagName.toLowerCase(); return Form.Element.ValueSetters[method](element, value); } }); /** * @classDescription Provides methods to extract the current value from a form element. * @constructor */ Form.Element.ValueSetters = { /** * Returns an array of the text value or checked status of a form element as appropriate to the element type. * @name Form.Element.ValueSetters.input() * @param {Object} element Element object or id to get the value of. * @return {Array} Returns the value of the element as an array (e.g. ['elementName', 'elementValue']). */ input: function(element, value) { switch (element.type.toLowerCase()) { case 'submit': case 'hidden': case 'password': case 'text': return Form.Element.ValueSetters.textarea(element, value); case 'checkbox': case 'radio': return Form.Element.ValueSetters.inputSelector(element, value); } return false; }, /** * Returns an array of the name and value of the element (e.g. ['elementName', 'elementValue']). * @name Form.Element.ValueSetters.inputSelector() * @param {Object} element Element object or id to get. * @return {Array} Returns an array of the name and value of the element (e.g. ['elementName', 'elementValue']). */ inputSelector: function(element, value) { element.checked = parseBool(value); return true; }, /** * Returns an array of the name and value of a textarea element (e.g. ['elementName', 'elementValue']). * @name Form.Element.ValueSetters.textarea() * @param {Object} element Element object or id to get. * @return {Array} Returns an array of the name and value of the element (e.g. ['elementName', 'elementValue']). */ textarea: function(element, value) { element.value = value; return true; }, /** * Returns an array of the names and values of all selected elements (e.g. ['elementName', 'selectedValue1', 'selectedValue2']). * @name Form.Element.ValueSetters.select() * @param {Object} element Element object or id to get. * @return {Array} Returns an array of the names and values of all selected elements (e.g. ['elementName', 'selectedValue1', 'selectedValue2']). */ select: function(element, value) { return Form.Element.ValueSetters[element.type == 'select-one' ? 'selectOne' : 'selectMany'](element, value); }, /** * Returns an array of the name and value of a single select element (e.g. ['elementName', 'selectedValue']). * @name Form.Element.ValueSetters.selectOne() * @param {Object} element Element object or id to get. * @return {Array} Returns an array of the name and value of a single select element (e.g. ['elementName', 'selectedValue']). */ selectOne: function(element, value) { var optArr = $A(element.options); var selIdx = optArr.pluck("value").indexOf(value); if (selIdx >= 0) { element.selectedIndex = selIdx; } else { // try the text instead selIdx = optArr.pluck("text").indexOf(value); element.selectedIndex = selIdx; } return (selIdx >= 0); }, /** * Returns an array of the names and values of all selected elements (e.g. ['elementName', 'selectedValue1', 'selectedValue2']). * @name Form.Element.ValueSetters.selectMany() * @param {Object} element Element object or id to get. * @return {Array} Returns an array of the names and values of all selected elements (e.g. ['elementName', 'selectedValue1', 'selectedValue2']). */ selectMany: function(element, value) { valueArray = (value != null ? $A(value) : null); $A(element.options).each( function(option) { option.selected = (valueArray != null ? valueArray.include(option) : false); } ); return true; } } /** * Shorthand version of Form.Element.setValue */ var $FS = Form.Element.setValue; /** * Extension of the Error class to include the prototype inspect() method. */ Object.extend(Error.prototype, { inspect: function() { return this.name + ": " + this.message; } } ); /** * @classDescription Subclass of Error thrown specifically for errors being sourced * from server-side processing of ajax requests. */ Ajax.ServerError = Class.create(); Ajax.ServerError.prototype = { initialize: function(message) { this.name = "Ajax.ServerError"; this.message = message; } } Object.extend(Ajax.ServerError.prototype, Error.prototype); /** * Internal variable used to recall the user-specified callback in an async * ajax request. */ Ajax._currentCallback = null; /** * Internal function that is always used as the direct callback to ajax requests. This * gives the internal Ajax code a chance to deal with responses before handing them off * to the client callback routine. */ Ajax._intCallback = function(req) { var err = null; if (req.responseText.indexOf("Global Variables:") >= 0 || req.responseText.indexOf("503: server error") >= 0) { err = new Ajax.ServerError(req.responseText); } if (Ajax._currentCallback) { Ajax._currentCallback(req, err); } else { if (err) { throw err; } else { return req; } } } /** * Convenience method of submitting AJAX requests. * @param {String} url The URL to call. If a ? is present, the call will be made via get; otherwise, post * @param {Function} [callbackFunc] The funcation to call once the request has been completed. The function should have * a single argument that takes the XmlHttpRequest object. If omitted, the request will be performed synchronously. * @param {Object, String} [parameters] Optionally set field/value assignments here in javascript object form (associative array). */ Ajax.submitRequest = function(url, callbackFunc, parameters, failureHandler) { if (parameters && !parameters.substr) { parameters = $H(parameters).toQueryString(); } // recall the passed-in callback function for use later (or else null if sync call) Ajax._currentCallback = callbackFunc; /* note that the _intCallback function is passed on. The client callback will be called * from within _intCallback. */ var req = new Ajax.Request(url, { method: (url.indexOf("?") >= 0 ? "get" : "post"), asynchronous: (callbackFunc != null), parameters: (parameters || ""), onSuccess: Ajax._intCallback, onFailure: (failureHandler || Ajax.failureHandler) }).transport; /* * if sync, call _intCallback now. */ if (!callbackFunc) { return Ajax._intCallback(req); } else { return req; } } /** * Super-lame default failure handler. Should really only happen if unit cannot be contacted. * @param {Object} request */ Ajax.failureHandler = function(request) { alert(/* xlate:897162 */"failure!"/* xlate:end */); } Object.extend(Object.prototype, { /** * Creates a deep copy of this object. * @return {Object} A deep copy of this object. */ clone: function() { var ret = {}; for (prop in this) { var type = typeof(this[prop]); if (type.toLowerCase() == "object") { ret[prop] = this[prop].clone(); } else { ret[prop] = this[prop]; } } return ret; }, /** * Absorb will pull properties from the passed-in Object into this Object. There are * two modes: * * If allProperties is false (default), only the properties that are common in this Object * and the passed-in Object will be merged. * * If allProperties is true, all of the properties from the passed-in Object will be merged * into this Object. * * Examples: * * Common setup: * var a = {foo: 1, boo: "hi"}; * var b = {foo: 2, bar: "blah"}; * * Example 1: allProperties is false * a.absorb(b); * * Result: a == {foo: 2, boo: "hi"} * * Example 2: allProperties is true * a.absorb(b, true); * * Result: a == {foo: 2, boo: "hi", bar: "blah"} * * @param {Object} sourceObject The Object whose values will be absorbed into this Object. * @param {Boolean} [allProperties] Whether or not to merge all of the properties from the passed-in Object. */ absorb: function(sourceObject, allProperties) { if (sourceObject) { var src = (allProperties ? sourceObject : this); for (prop in src) { if (sourceObject[prop] != undefined) { this[prop] = sourceObject[prop]; } } } } }); Object.extend(Array.prototype, { /** * Creates a deep copy of this array. * @return {Array} A deep copy of this array. */ clone: function() { return this.collect( function(value) { return (value.clone? value.clone() : value); } ); }, /** * Merges (ignores duplicates) the values in the passed-in array with the values in this array. * The change happens in-place instead of creating a new array. The return is * an array of the values that were added. * * @param {Object} array The array to merge values from. Duplicates will be discarded. * @return {Array} The array elements from the parameter that were actually added to this array. */ merge: function(array) { var addedValues = []; var mergeObj = {}; var mergeObj = this.inject( {}, function(map, value) { map[value] = ""; return map; } ); mergeObj = array.inject( mergeObj, function(map, value) { if (!map[value]) { addedValues.push(value); map[value] = ""; } return map; } ); this.length = 0; var arrVals = $H(mergeObj).keys(); for (var i=0; i < arrVals.length; i++) { this[i] = arrVals[i]; } return addedValues; }, /** * Returns an array that contains all of the elements of this array except * for elements that are duplicates of other elements. */ dedupe: function() { return this.inject( [], function(arr, value) { if (arr.indexOf(value) == -1) { arr.push(value); } return arr; } ) } }); Object.extend(Element, { /** * Sets the .disabled value of the target element and all valid * children of that element. * @param {Object} targetElement The top-most element to set * @param {Boolean} enable Whether to enable or disable these elements. */ setEnabled: function(targetElement, enable) { targetElement = $(targetElement); if (targetElement && targetElement.getElementsByTagName) { Element._EnableToggle(targetElement, enable); var tagArr = $A(['DIV', 'SPAN', 'TABLE', 'TBODY', 'TH', 'THEAD', 'TR', 'TD', 'LABEL', 'INPUT', 'SELECT', 'IMG']); tagArr.each( function(tag) { $A(targetElement.getElementsByTagName(tag)).each( function(subElem) { Element._EnableToggle(subElem, enable); } ); } ); } }, /** * private */ _EnableToggle: function(targetElement, enable) { targetElement.disabled = !enable; if(targetElement.tagName == "INPUT" && targetElement.type == "text") { if (enable) { Element.classNames(targetElement).remove("disabledTextBox"); } else { Element.classNames(targetElement).add("disabledTextBox"); } } } }); Object.extend(Element, { /** * Allows script code to generate a UI event that will force any * event handlers to be run. * @param {Object} The target DOM element upon which to fire the event * @param {String} eventType The type of event to fire. See code for the list. * @param {Object} [eventParams] Optionally the event object can be extended with the properties * in this Object. */ fireEvent: function(targetElement, eventType, eventParams) { targetElement = $(targetElement); var generalType = "Events"; switch (eventType) { case 'abort': case 'blur': case 'change': case 'error': case 'focus': case 'load': case 'reset': case 'resize': case 'scroll': case 'select': case 'submit': case 'unload': generalType = "HTMLEvents"; break; case 'click': case 'mousedown': case 'mousemove': case 'mouseout': case 'mouseover': case 'mouseup': generalType = "MouseEvents"; break; case 'DOMActivate': case 'DOMFocusIn': case 'DOMFocusOut': case 'keydown': case 'keypress': case 'keyup': generalType = "UIEvents"; break; } if (document.createEvent) { var evObj = document.createEvent(generalType); evObj.initEvent(eventType, true, false); if (eventParams && typeof(eventParams) == "object") { Object.extend(evObj, eventParams); } targetElement.dispatchEvent(evObj); } else if (document.createEventObject) { var evObj = document.createEventObject("on" + eventType); if (eventParams && typeof(eventParams) == "object") { Object.extend(evObj, eventParams); } targetElement.fireEvent("on" + eventType, evObj); } else { throw "Error: Could not manually fire event. Be sure you are using IE 6+ or Firefox"; } } } ); Object.extend(Event, { /** * Allows the programmer to register the same observer method to multiple elements * for the same event at once * @param {Object, String, Array} elements One or more elements to observe * @param {String} name The event name to listen for * @param {Function} observer The function to call * @param {Boolean} [useCapture] If true, handles event in capture phase; otherwise in bubbling phase */ observeMultiple: function(elements, name, observer, useCapture) { if (!(elements instanceof Array)) { elements = [elements]; } elements.each( function(element) { Event.observe(element, name, observer, useCapture); } ); } } ); /** * Private */ globalEval = function() { return eval(arguments[0]); } Object.extend(window, { /** * Private */ loadedScripts: {}, /** * Private */ scriptLoaded: function(scriptName) { return window.loadedScripts[scriptName] != null; }, /** * Dynamically loads and parses a javascript file from the specified URL. * @param {Object} url The URL of the script file */ loadScript: function(url) { if (!window.scriptLoaded(url)) { var req = Ajax.submitRequest(url); if (req.responseText) { globalEval(req.responseText); window.loadedScripts[url] = url; } } } } ); /** * A Set is a Java-like collection that limits the values inside to a unique list. * In order to create a Set, use $S around an array: var set = $S([]); The only * real difference between a Set and an array is the implementation of push(), which * will check for duplicates and return a bool indicating whether the push was successful * or not. All other options for adding elements to the array are still open for duplication */ var Set = { /** * Override of Array's push method. Will only add the passed-in arguments if they do * not already exist in the array. Returns true only if all passed-in elements are * added successfully. * * @param {Any} arguments One or more elements to add to the Set. */ push: function() { var ret = true; if (arguments.length) { for (var i=0; i < arguments.length; i++) { var element = arguments[i]; if (this.indexOf(element) == -1) { this[this.length] = element; } else { ret = false; } } } return ret; } }; /** * Creates a Set by wrapping around an array. * * @param {Array} arr The array to make a Set. * @return {Set} The created Set */ var $S = function(arr) { var retArr = (arr || []); Object.extend(retArr, Set); return retArr; } Object.extend(String.prototype, { ltrim: function() { var whitespace = " \t\n\r"; var len = this.length; var idx = 0; for (idx = 0; idx < len; ++idx) { if (whitespace.indexOf(this.charAt(idx)) == -1) { break; } } var returnString = this.substring(idx); return returnString; }, rtrim: function() { var whitespace = " \t\n\r"; for (var idx = this.length - 1; idx >= 0; --idx) { if (whitespace.indexOf(this.charAt(idx)) == -1) { break; } } return this.substring(0, idx+1); }, trim: function() { temp = this; temp = temp.ltrim(); temp = temp.rtrim(); return temp; } } ); /* Ajax.Serializer = Class.create(); Object.extend(Ajax.Serializer.prototype, { functionList: $A([]), addCall: function(asyncFunction, callbackFunction) { functionList.push({call: asyncFunction, callback: callbackFunction}); }, start(): function() { } } ); */