2 * Utilities and extions to Prototype/Scriptaculous
3 * @file scriptaculous-adapter.js
8 * <a href="http://www.prototypejs.org/api/function" target="_blank">Prototype's Function</a>
12 * Similar to bindAsEventLister, but takes additional arguments.
13 * @function Function.bindEvent
15 Function.prototype.bindEvent = function()
17 var __method = this, args = $A(arguments), object = args.shift();
18 return function(event)
20 return __method.apply(object, [event || window.event].concat(args));
26 * <a href="http://www.prototypejs.org/api/class" target="_blank">Prototype's Class</a>
31 * Creates a new class by copying class definition from
32 * the <tt>base</tt> and optional <tt>definition</tt>.
33 * @function {Class} Class.extend
34 * @param {function} base - Base class to copy from.
35 * @param {optional Array} - Additional definition
36 * @returns Constructor for the extended class
38 Class.extend = function(base, definition)
40 var component = Class.create();
41 Object.extend(component.prototype, base.prototype);
43 Object.extend(component.prototype, definition);
49 * Copyright 2006, Dean Edwards
50 * License: http://creativecommons.org/licenses/LGPL/2.1/
53 var Base = function() {
54 if (arguments.length) {
55 if (this == window) { // cast an object to this class
56 Base.prototype.extend.call(arguments[0], arguments.callee.prototype);
58 this.extend(arguments[0]);
63 Base.version = "1.0.2";
66 extend: function(source, value) {
67 var extend = Base.prototype.extend;
68 if (arguments.length == 2) {
69 var ancestor = this[source];
71 if ((ancestor instanceof Function) && (value instanceof Function) &&
72 ancestor.valueOf() != value.valueOf() && /\bbase\b/.test(value)) {
74 // var _prototype = this.constructor.prototype;
75 // var fromPrototype = !Base._prototyping && _prototype[source] == ancestor;
77 var previous = this.base;
78 // this.base = fromPrototype ? _prototype[source] : ancestor;
80 var returnValue = method.apply(this, arguments);
84 // point to the underlying method
85 value.valueOf = function() {
88 value.toString = function() {
89 return String(method);
92 return this[source] = value;
94 var _prototype = {toSource: null};
95 // do the "toString" and other methods manually
96 var _protected = ["toString", "valueOf"];
97 // if we are prototyping then include the constructor
98 if (Base._prototyping) _protected[2] = "constructor";
100 for (var i = 0; (name = _protected[i]); i++) {
101 if (source[name] != _prototype[name]) {
102 extend.call(this, name, source[name]);
105 // copy each of the source object's properties to this object
106 for (var name in source) {
107 if (!_prototype[name]) {
108 extend.call(this, name, source[name]);
116 // call this method from any other method to invoke that method's ancestor
120 Base.extend = function(_instance, _static) {
121 var extend = Base.prototype.extend;
122 if (!_instance) _instance = {};
123 // build the prototype
124 Base._prototyping = true;
125 var _prototype = new this;
126 extend.call(_prototype, _instance);
127 var constructor = _prototype.constructor;
128 _prototype.constructor = this;
129 delete Base._prototyping;
130 // create the wrapper for the constructor function
131 var klass = function() {
132 if (!Base._prototyping) constructor.apply(this, arguments);
133 this.constructor = klass;
135 klass.prototype = _prototype;
136 // build the class interface
137 klass.extend = this.extend;
138 klass.implement = this.implement;
139 klass.toString = function() {
140 return String(constructor);
142 extend.call(klass, _static);
144 var object = constructor ? klass : _prototype;
145 // class initialisation
146 if (object.init instanceof Function) object.init();
150 Base.implement = function(_interface) {
151 if (_interface instanceof Function) _interface = _interface.prototype;
152 this.prototype.extend(_interface);
156 * Performs a PostBack using javascript.
157 * @function Prado.PostBack
158 * @param event - Event that triggered this postback
159 * @param options - Postback options
160 * @... {string} FormID - Form that should be posted back
161 * @... {optional boolean} CausesValidation - Validate before PostBack if true
162 * @... {optional string} ValidationGroup - Group to Validate
163 * @... {optional string} ID - Validation ID
164 * @... {optional string} PostBackUrl - Postback URL
165 * @... {optional boolean} TrackFocus - Keep track of focused element if true
166 * @... {string} EventTarget - Id of element that triggered PostBack
167 * @... {string} EventParameter - EventParameter for PostBack
169 Prado.PostBack = function(event,options)
171 var form = $(options['FormID']);
172 var canSubmit = true;
174 if(options['CausesValidation'] && typeof(Prado.Validation) != "undefined")
176 if(!Prado.Validation.validate(options['FormID'], options['ValidationGroup'], $(options['ID'])))
177 return Event.stop(event);
180 if(options['PostBackUrl'] && options['PostBackUrl'].length > 0)
181 form.action = options['PostBackUrl'];
183 if(options['TrackFocus'])
185 var lastFocus = $('PRADO_LASTFOCUS');
188 var active = document.activeElement; //where did this come from
190 lastFocus.value = active.id;
192 lastFocus.value = options['EventTarget'];
196 $('PRADO_POSTBACK_TARGET').value = options['EventTarget'];
197 $('PRADO_POSTBACK_PARAMETER').value = options['EventParameter'];
199 * Since google toolbar prevents browser default action,
200 * we will always disable default client-side browser action
202 /*if(options['StopEvent']) */
204 Event.fireEvent(form,"submit");
206 $('PRADO_POSTBACK_TARGET').value = '';
207 $('PRADO_POSTBACK_PARAMETER').value = '';
211 * Prado utilities to manipulate DOM elements.
212 * @object Prado.Element
217 * Set the value of a particular element.
219 * @param {string} element - Element id
220 * @param {string} value - New element value
222 setValue : function(element, value)
225 if(el && typeof(el.value) != "undefined")
230 * Select options from a selectable element.
232 * @param {string} element - Element id
233 * @param {string} method - Name of any {@link Prado.Element.Selection} method
234 * @param {array|boolean|string} value - Values that should be selected
235 * @param {int} total - Number of elements
237 select : function(element, method, value, total)
241 var selection = Prado.Element.Selection;
242 if(typeof(selection[method]) == "function")
244 var control = selection.isSelectable(el) ? [el] : selection.getListElements(element,total);
245 selection[method](control, value);
250 * Trigger a click event on a DOM element.
252 * @param {string} element - Element id
254 click : function(element)
262 * Check if an DOM element is disabled.
263 * @function {boolean} ?
264 * @param {string} element - Element id
265 * @returns true if element is disabled
267 isDisabled : function(element)
269 if(!element.attributes['disabled']) //FF
271 var value = element.attributes['disabled'].nodeValue;
272 if(typeof(value)=="string")
273 return value.toLowerCase() == "disabled";
275 return value == true;
279 * Sets an attribute of a DOM element.
281 * @param {string} element - Element id
282 * @param {string} attribute - Name of attribute
283 * @param {string} value - Value of attribute
285 setAttribute : function(element, attribute, value)
289 if((attribute == "disabled" || attribute == "multiple" || attribute == "readonly" || attribute == "href") && value==false)
290 el.removeAttribute(attribute);
291 else if(attribute.match(/^on/i)) //event methods
295 eval("(func = function(event){"+value+"})");
296 el[attribute] = func;
301 throw "Error in evaluating '"+value+"' for attribute "+attribute+" for element "+element.id;
305 el.setAttribute(attribute, value);
309 * Sets the options for a select element.
311 * @param {string} element - Element id
312 * @param {array[]} options - Array of options, each an array of structure
313 * [ "optionText" , "optionValue" , "optionGroup" ]
315 setOptions : function(element, options)
319 var previousGroup = null;
321 if(el && el.tagName.toLowerCase() == "select")
323 while(el.childNodes.length > 0)
324 el.removeChild(el.lastChild);
326 var optDom = Prado.Element.createOptions(options);
327 for(var i = 0; i < optDom.length; i++)
328 el.appendChild(optDom[i]);
333 * Create opt-group options from an array of options.
334 * @function {array} ?
335 * @param {array[]} options - Array of options, each an array of structure
336 * [ "optionText" , "optionValue" , "optionGroup" ]
337 * @returns Array of option DOM elements
339 createOptions : function(options)
341 var previousGroup = null;
344 for(var i = 0; i<options.length; i++)
346 var option = options[i];
347 if(option.length > 2)
349 var group = option[2];
350 if(group!=previousGroup)
352 if(previousGroup!=null && optgroup!=null)
354 result.push(optgroup);
358 optgroup = document.createElement('optgroup');
359 optgroup.label = group;
360 previousGroup = group;
363 var opt = document.createElement('option');
364 opt.text = option[0];
365 opt.innerHTML = option[0];
366 opt.value = option[1];
368 optgroup.appendChild(opt);
373 result.push(optgroup);
378 * Set focus (delayed) on a particular element.
380 * @param {string} element - Element id
382 focus : function(element)
384 var obj = $(element);
385 if(typeof(obj) != "undefined" && typeof(obj.focus) != "undefined")
386 setTimeout(function(){ obj.focus(); }, 100);
391 * Replace a DOM element either with given content or
392 * with content from a CallBack response boundary
393 * using a replacement method.
395 * @param {string|element} element - DOM element or element id
396 * @param {string} method - Name of method to use for replacement
397 * @param {optional string} content - New content of element
398 * @param {optional string} boundary - Boundary of new content
400 replace : function(element, method, content, boundary)
404 var result = Prado.Element.extractContent(this.transport.responseText, boundary);
408 if(typeof(element) == "string")
411 method.toFunction().apply(this,[element,""+content]);
415 method.toFunction().apply(this,[""+content]);
420 * Appends a javascript block to the document.
422 * @param {string} boundary - Boundary containing the javascript code
424 appendScriptBlock : function(boundary)
426 var content = Prado.Element.extractContent(this.transport.responseText, boundary);
430 var el = document.createElement("script");
431 el.type = "text/javascript";
432 el.id = 'inline_' + boundary;
435 (document.getElementsByTagName('head')[0] || document.documentElement).appendChild(el);
436 el.parentNode.removeChild(el);
440 * Extract content from a text by its boundary id.
441 * Boundaries have this form:
443 * <!--123456-->Democontent<!--//123456-->
445 * @function {string} ?
446 * @param {string} text - Text that contains boundaries
447 * @param {string} boundary - Boundary id
448 * @returns Content from given boundaries
450 extractContent : function(text, boundary)
452 var tagStart = '<!--'+boundary+'-->';
453 var tagEnd = '<!--//'+boundary+'-->';
454 var start = text.indexOf(tagStart);
457 start += tagStart.length;
458 var end = text.indexOf(tagEnd,start);
460 return text.substring(start,end);
463 /*var f = RegExp('(?:<!--'+boundary+'-->)((?:.|\n|\r)+?)(?:<!--//'+boundary+'-->)',"m");
464 var result = text.match(f);
465 if(result && result.length >= 2)
472 * Evaluate a javascript snippet from a string.
474 * @param {string} content - String containing the script
476 evaluateScript : function(content)
480 content.evalScripts();
484 if(typeof(Logger) != "undefined")
485 Logger.error('Error during evaluation of script "'+content+'"');
493 * Set CSS style with Camelized keys.
494 * See <a href="http://www.prototypejs.org/api/element/setstyle" target="_blank">Prototype's
495 * Element.setStyle</a> for details.
497 * @param {string|element} element - DOM element or element id
498 * @param {object} styles - Object with style properties/values
500 setStyle : function (element, styles)
503 // Camelize all styles keys
504 for (var property in styles)
506 s[property.camelize()]=styles[property].camelize();
508 Element.setStyle(element, s);
513 * Utilities for selections.
514 * @object Prado.Element.Selection
516 Prado.Element.Selection =
519 * Check if an DOM element can be selected.
520 * @function {boolean} ?
521 * @param {element} el - DOM elemet
522 * @returns true if element is selectable
524 isSelectable : function(el)
528 switch(el.type.toLowerCase())
533 case 'select-multiple':
542 * Set checked attribute of a checkbox or radiobutton to value.
543 * @function {boolean} ?
544 * @param {element} el - DOM element
545 * @param {boolean} value - New value of checked attribute
546 * @returns New value of checked attribute
548 inputValue : function(el, value)
550 switch(el.type.toLowerCase())
554 return el.checked = value;
559 * Set selected attribute for elements options by value.
560 * If value is boolean, all elements options selected attribute will be set
561 * to value. Otherwhise all options that have the given value will be selected.
563 * @param {element[]} elements - Array of selectable DOM elements
564 * @param {boolean|string} value - Value of options that should be selected or boolean value of selection status
566 selectValue : function(elements, value)
568 elements.each(function(el)
570 $A(el.options).each(function(option)
572 if(typeof(value) == "boolean")
573 option.selected = value;
574 else if(option.value == value)
575 option.selected = true;
581 * Set selected attribute for elements options by array of values.
583 * @param {element[]} elements - Array of selectable DOM elements
584 * @param {string[]} value - Array of values to select
586 selectValues : function(elements, values)
588 var selection = this;
589 values.each(function(value)
591 selection.selectValue(elements,value);
596 * Set selected attribute for elements options by option index.
598 * @param {element[]} elements - Array of selectable DOM elements
599 * @param {int} index - Index of option to select
601 selectIndex : function(elements, index)
603 elements.each(function(el)
605 if(el.type.toLowerCase() == 'select-one')
606 el.selectedIndex = index;
609 for(var i = 0; i<el.length; i++)
612 el.options[i].selected = true;
619 * Set selected attribute to true for all elements options.
621 * @param {element[]} elements - Array of selectable DOM elements
623 selectAll : function(elements)
625 elements.each(function(el)
627 if(el.type.toLowerCase() != 'select-one')
629 $A(el.options).each(function(option)
631 option.selected = true;
638 * Toggle the selected attribute for elements options.
640 * @param {element[]} elements - Array of selectable DOM elements
642 selectInvert : function(elements)
644 elements.each(function(el)
646 if(el.type.toLowerCase() != 'select-one')
648 $A(el.options).each(function(option)
650 option.selected = !options.selected;
657 * Set selected attribute for elements options by array of option indices.
659 * @param {element[]} elements - Array of selectable DOM elements
660 * @param {int[]} indices - Array of option indices to select
662 selectIndices : function(elements, indices)
664 var selection = this;
665 indices.each(function(index)
667 selection.selectIndex(elements,index);
674 * @param {element[]} elements - Array of selectable DOM elements
676 selectClear : function(elements)
678 elements.each(function(el)
680 el.selectedIndex = -1;
685 * Get list elements of an element.
686 * @function {element[]} ?
687 * @param {element[]} elements - Array of selectable DOM elements
688 * @param {int} total - Number of list elements to return
689 * @returns Array of list DOM elements
691 getListElements : function(element, total)
693 var elements = new Array();
695 for(var i = 0; i < total; i++)
697 el = $(element+"_c"+i);
705 * Set checked attribute of elements by value.
706 * If value is boolean, checked attribute will be set to value.
707 * Otherwhise all elements that have the given value will be checked.
709 * @param {element[]} elements - Array of checkable DOM elements
710 * @param {boolean|String} value - Value that should be checked or boolean value of checked status
713 checkValue : function(elements, value)
715 elements.each(function(el)
717 if(typeof(value) == "boolean")
719 else if(el.value == value)
725 * Set checked attribute of elements by array of values.
727 * @param {element[]} elements - Array of checkable DOM elements
728 * @param {string[]} values - Values that should be checked
731 checkValues : function(elements, values)
733 var selection = this;
734 values.each(function(value)
736 selection.checkValue(elements, value);
741 * Set checked attribute of elements by list index.
743 * @param {element[]} elements - Array of checkable DOM elements
744 * @param {int} index - Index of element to set checked
746 checkIndex : function(elements, index)
748 for(var i = 0; i<elements.length; i++)
751 elements[i].checked = true;
756 * Set checked attribute of elements by array of list indices.
758 * @param {element[]} elements - Array of selectable DOM elements
759 * @param {int[]} indices - Array of list indices to set checked
761 checkIndices : function(elements, indices)
763 var selection = this;
764 indices.each(function(index)
766 selection.checkIndex(elements, index);
773 * @param {element[]} elements - Array of checkable DOM elements
775 checkClear : function(elements)
777 elements.each(function(el)
784 * Set checked attribute of all elements to true.
786 * @param {element[]} elements - Array of checkable DOM elements
788 checkAll : function(elements)
790 elements.each(function(el)
797 * Toggle the checked attribute of elements.
799 * @param {element[]} elements - Array of selectable DOM elements
801 checkInvert : function(elements)
803 elements.each(function(el)
805 el.checked != el.checked;
812 * Utilities for insertion.
813 * @object Prado.Element.Insert
815 Prado.Element.Insert =
818 * Append content to element
820 * @param {element} element - DOM element that content should be appended to
821 * @param {element} content - DOM element to append
823 append: function(element, content)
825 $(element).insert(content);
829 * Prepend content to element
831 * @param {element} element - DOM element that content should be prepended to
832 * @param {element} content - DOM element to prepend
834 prepend: function(element, content)
836 $(element).insert({top:content});
840 * Insert content after element
842 * @param {element} element - DOM element that content should be inserted after
843 * @param {element} content - DOM element to insert
845 after: function(element, content)
847 $(element).insert({after:content});
851 * Insert content before element
853 * @param {element} element - DOM element that content should be inserted before
854 * @param {element} content - DOM element to insert
856 before: function(element, content)
858 $(element).insert({before:content});
865 * <a href="http://wiki.script.aculo.us/scriptaculous/show/builder" target="_blank">Scriptaculous' Builder</a>
869 Object.extend(Builder,
872 * Export scriptaculous builder utilities as window[functions]
875 exportTags:function()
877 var tags=["BUTTON","TT","PRE","H1","H2","H3","BR","CANVAS","HR","LABEL","TEXTAREA","FORM","STRONG","SELECT","OPTION","OPTGROUP","LEGEND","FIELDSET","P","UL","OL","LI","TD","TR","THEAD","TBODY","TFOOT","TABLE","TH","INPUT","SPAN","A","DIV","IMG", "CAPTION"];
878 tags.each(function(tag)
880 window[tag]=function()
882 var args=$A(arguments);
884 return Builder.node(tag,null);
886 return Builder.node(tag,args[0]);
888 return Builder.node(tag,args.shift(),args);
894 Builder.exportTags();
898 * <a href="http://www.prototypejs.org/api/string" target="_blank">Prototype's String</a>
901 Object.extend(String.prototype, {
904 * Add padding to string
905 * @function {string} ?
906 * @param {string} side - "left" to pad the string on the left, "right" to pad right.
907 * @param {int} len - Minimum string length.
908 * @param {string} chr - Character(s) to pad
909 * @returns Padded string
911 pad : function(side, len, chr) {
914 var left = side.toLowerCase()=='left';
915 while (s.length<len) s = left? chr + s : s + chr;
920 * Add left padding to string
921 * @function {string} ?
922 * @param {int} len - Minimum string length.
923 * @param {string} chr - Character(s) to pad
924 * @returns Padded string
926 padLeft : function(len, chr) {
927 return this.pad('left',len,chr);
931 * Add right padding to string
932 * @function {string} ?
933 * @param {int} len - Minimum string length.
934 * @param {string} chr - Character(s) to pad
935 * @returns Padded string
937 padRight : function(len, chr) {
938 return this.pad('right',len,chr);
942 * Add zeros to the right of string
943 * @function {string} ?
944 * @param {int} len - Minimum string length.
945 * @returns Padded string
947 zerofill : function(len) {
948 return this.padLeft(len,'0');
952 * Remove white spaces from both ends of string.
953 * @function {string} ?
954 * @returns Trimmed string
957 return this.replace(/^\s+|\s+$/g,'');
961 * Remove white spaces from the left side of string.
962 * @function {string} ?
963 * @returns Trimmed string
965 trimLeft : function() {
966 return this.replace(/^\s+/,'');
970 * Remove white spaces from the right side of string.
971 * @function {string} ?
972 * @returns Trimmed string
974 trimRight : function() {
975 return this.replace(/\s+$/,'');
979 * Convert period separated function names into a function reference.
982 * "Prado.AJAX.Callback.Action.setValue".toFunction()
984 * @function {function} ?
985 * @returns Reference to the corresponding function
987 toFunction : function()
989 var commands = this.split(/\./);
990 var command = window;
991 commands.each(function(action)
993 if(command[new String(action)])
994 command=command[new String(action)];
996 if(typeof(command) == "function")
1000 if(typeof Logger != "undefined")
1001 Logger.error("Missing function", this);
1003 throw new Error ("Missing function '"+this+"'");
1008 * Convert string into integer, returns null if not integer.
1010 * @returns Integer, null if string does not represent an integer.
1012 toInteger : function()
1014 var exp = /^\s*[-\+]?\d+\s*$/;
1015 if (this.match(exp) == null)
1017 var num = parseInt(this, 10);
1018 return (isNaN(num) ? null : num);
1022 * Convert string into a double/float value. <b>Internationalization
1023 * is not supported</b>
1024 * @function {double} ?
1025 * @param {string} decimalchar - Decimal character, defaults to "."
1026 * @returns Double, null if string does not represent a float value
1028 toDouble : function(decimalchar)
1030 if(this.length <= 0) return null;
1031 decimalchar = decimalchar || ".";
1032 var exp = new RegExp("^\\s*([-\\+])?(\\d+)?(\\" + decimalchar + "(\\d+))?\\s*$");
1033 var m = this.match(exp);
1041 var cleanInput = m[1] + (m[2].length>0 ? m[2] : "0") + "." + m[4];
1042 var num = parseFloat(cleanInput);
1043 return (isNaN(num) ? null : num);
1047 * Convert strings that represent a currency value to float.
1048 * E.g. "10,000.50" will become "10000.50". The number
1049 * of dicimal digits, grouping and decimal characters can be specified.
1050 * <i>The currency input format is <b>very</b> strict, null will be returned if
1051 * the pattern does not match</i>.
1052 * @function {double} ?
1053 * @param {string} groupchar - Grouping character, defaults to ","
1054 * @param {int} digits - Number of decimal digits
1055 * @param {string} decimalchar - Decimal character, defaults to "."
1056 * @returns Double, null if string does not represent a currency value
1058 toCurrency : function(groupchar, digits, decimalchar)
1060 groupchar = groupchar || ",";
1061 decimalchar = decimalchar || ".";
1062 digits = typeof(digits) == "undefined" ? 2 : digits;
1064 var exp = new RegExp("^\\s*([-\\+])?(((\\d+)\\" + groupchar + ")*)(\\d+)"
1065 + ((digits > 0) ? "(\\" + decimalchar + "(\\d{1," + digits + "}))?" : "")
1067 var m = this.match(exp);
1070 var intermed = m[2] + m[5] ;
1071 var cleanInput = m[1] + intermed.replace(
1072 new RegExp("(\\" + groupchar + ")", "g"), "")
1073 + ((digits > 0) ? "." + m[7] : "");
1074 var num = parseFloat(cleanInput);
1075 return (isNaN(num) ? null : num);
1079 * Converts the string to a date by finding values that matches the
1080 * date format pattern.
1081 * @function {Date} ?
1082 * @param {string} format - Date format pattern, e.g. MM-dd-yyyy
1083 * @returns Date extracted from the string
1085 toDate : function(format)
1087 return Date.SimpleParse(this, format);
1093 * <a href="http://www.prototypejs.org/api/event" target="_blank">Prototype's Event</a>
1096 Object.extend(Event,
1099 * Register a function to be executed when the page is loaded.
1100 * Note that the page is only loaded if all resources (e.g. images)
1103 * <br />Show an alert box with message "Page Loaded!" when the
1104 * page finished loading.
1106 * Event.OnLoad(function(){ alert("Page Loaded!"); });
1109 * @param {function} fn - Function to execute when page is loaded.
1111 OnLoad : function (fn)
1113 // opera onload is in document, not window
1114 var w = document.addEventListener &&
1115 !window.addEventListener ? document : window;
1116 Event.observe(w,'load',fn);
1120 * Returns the unicode character generated by key.
1121 * @param {event} e - Keyboard event
1123 * @returns Unicode character code generated by the key that was struck.
1125 keyCode : function(e)
1127 return e.keyCode != null ? e.keyCode : e.charCode
1131 * Checks if an Event is of type HTMLEvent.
1132 * @function {boolean} ?
1133 * @param {string} type - Event type or event name.
1134 * @return true if event is of type HTMLEvent.
1136 isHTMLEvent : function(type)
1138 var events = ['abort', 'blur', 'change', 'error', 'focus',
1139 'load', 'reset', 'resize', 'scroll', 'select',
1140 'submit', 'unload'];
1141 return events.include(type);
1145 * Checks if an Event is a mouse event.
1146 * @function {boolean} ?
1147 * @param {string} type - Event type or event name
1148 * @return true if event is of type MouseEvent.
1150 isMouseEvent : function(type)
1152 var events = ['click', 'mousedown', 'mousemove', 'mouseout',
1153 'mouseover', 'mouseup'];
1154 return events.include(type);
1158 * Dispatch the DOM event of a given <tt>type</tt> on a DOM
1159 * <tt>element</tt>. Only HTMLEvent and MouseEvent can be
1160 * dispatched, keyboard events or UIEvent can not be dispatch
1161 * via javascript consistently.
1162 * For the "submit" event the submit() method is called.
1164 * @param {element|string} element - Element id string or DOM element.
1165 * @param {string} type - Event type to dispatch.
1167 fireEvent : function(element,type)
1169 element = $(element);
1170 if(type == "submit")
1171 return element.submit();
1172 if(document.createEvent)
1174 if(Event.isHTMLEvent(type))
1176 var event = document.createEvent('HTMLEvents');
1177 event.initEvent(type, true, true);
1179 else if(Event.isMouseEvent(type))
1181 var event = document.createEvent('MouseEvents');
1182 if (event.initMouseEvent)
1184 event.initMouseEvent(type,true,true,
1185 document.defaultView, 1, 0, 0, 0, 0, false,
1186 false, false, false, 0, null);
1191 // TODO we should be initialising other mouse-event related attributes here
1192 event.initEvent(type, true, true);
1195 element.dispatchEvent(event);
1197 else if(document.createEventObject)
1199 var evObj = document.createEventObject();
1200 element.fireEvent('on'+type, evObj);
1202 else if(typeof(element['on'+type]) == "function")
1203 element['on'+type]();
1210 * <a href="http://www.prototypejs.org/api/date" target="_blank">Prototype's Date</a>
1213 Object.extend(Date.prototype,
1218 * @param {string} format - TODO
1219 * @param {string} data - TODO
1222 SimpleFormat: function(format, data)
1225 var bits = new Array();
1226 bits['d'] = this.getDate();
1227 bits['dd'] = String(this.getDate()).zerofill(2);
1229 bits['M'] = this.getMonth()+1;
1230 bits['MM'] = String(this.getMonth()+1).zerofill(2);
1231 if(data.AbbreviatedMonthNames)
1232 bits['MMM'] = data.AbbreviatedMonthNames[this.getMonth()];
1234 bits['MMMM'] = data.MonthNames[this.getMonth()];
1235 var yearStr = "" + this.getFullYear();
1236 yearStr = (yearStr.length == 2) ? '19' + yearStr: yearStr;
1237 bits['yyyy'] = yearStr;
1238 bits['yy'] = bits['yyyy'].toString().substr(2,2);
1240 // do some funky regexs to replace the format string
1241 // with the real values
1242 var frm = new String(format);
1243 for (var sect in bits)
1245 var reg = new RegExp("\\b"+sect+"\\b" ,"g");
1246 frm = frm.replace(reg, bits[sect]);
1253 * @function {string} ?
1256 toISODate : function()
1258 var y = this.getFullYear();
1259 var m = String(this.getMonth() + 1).zerofill(2);
1260 var d = String(this.getDate()).zerofill(2);
1261 return String(y) + String(m) + String(d);
1270 * @param {string} format - TODO
1271 * @param {string} data - TODO
1274 SimpleParse: function(value, format)
1276 var val=String(value);
1277 format=String(format);
1279 if(val.length <= 0) return null;
1281 if(format.length <= 0) return new Date(value);
1283 var isInteger = function (val)
1285 var digits="1234567890";
1286 for (var i=0; i < val.length; i++)
1288 if (digits.indexOf(val.charAt(i))==-1) { return false; }
1293 var getInt = function(str,i,minlength,maxlength)
1295 for (var x=maxlength; x>=minlength; x--)
1297 var token=str.substring(i,i+x);
1298 if (token.length < minlength) { return null; }
1299 if (isInteger(token)) { return token; }
1311 var year=now.getFullYear();
1312 var month=now.getMonth()+1;
1315 while (i_format < format.length)
1317 // Get next token from format string
1318 c=format.charAt(i_format);
1320 while ((format.charAt(i_format)==c) && (i_format < format.length))
1322 token += format.charAt(i_format++);
1325 // Extract contents of value based on format token
1326 if (token=="yyyy" || token=="yy" || token=="y")
1328 if (token=="yyyy") { x=4;y=4; }
1329 if (token=="yy") { x=2;y=2; }
1330 if (token=="y") { x=2;y=4; }
1331 year=getInt(val,i_val,x,y);
1332 if (year==null) { return null; }
1333 i_val += year.length;
1336 if (year > 70) { year=1900+(year-0); }
1337 else { year=2000+(year-0); }
1341 else if (token=="MM"||token=="M")
1343 month=getInt(val,i_val,token.length,2);
1344 if(month==null||(month<1)||(month>12)){return null;}
1345 i_val+=month.length;
1347 else if (token=="dd"||token=="d")
1349 date=getInt(val,i_val,token.length,2);
1350 if(date==null||(date<1)||(date>31)){return null;}
1355 if (val.substring(i_val,i_val+token.length)!=token) {return null;}
1356 else {i_val+=token.length;}
1360 // If there are any trailing characters left in the value, it doesn't match
1361 if (i_val != val.length) { return null; }
1363 // Is date valid for month?
1366 // Check for leap year
1367 if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
1368 if (date > 29){ return null; }
1370 else { if (date > 28) { return null; } }
1373 if ((month==4)||(month==6)||(month==9)||(month==11))
1375 if (date > 30) { return null; }
1378 var newdate=new Date(year,month-1,date, 0, 0, 0);
1384 * Prado utilities for effects.
1385 * @object Prado.Effect
1390 * Highlights an element
1392 * @param {element} element - DOM element to highlight
1393 * @param {optional object} options - Highlight options
1395 Highlight : function (element,options)
1397 new Effect.Highlight(element,options);