Scriptaculous' Builder
* @namespace Builder
*/
Object.extend(Builder,
{
/**
* Export scriptaculous builder utilities as window[functions]
* @function ?
*/
exportTags:function()
{
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"];
tags.each(function(tag)
{
window[tag]=function()
{
var args=$A(arguments);
if(args.length==0)
return Builder.node(tag,null);
if(args.length==1)
return Builder.node(tag,args[0]);
if(args.length>1)
return Builder.node(tag,args.shift(),args);
};
});
}
});
Builder.exportTags();
/**
* Extension to
* Prototype's String
* @namespace String
*/
Object.extend(String.prototype, {
/**
* Add padding to string
* @function {string} ?
* @param {string} side - "left" to pad the string on the left, "right" to pad right.
* @param {int} len - Minimum string length.
* @param {string} chr - Character(s) to pad
* @returns Padded string
*/
pad : function(side, len, chr) {
if (!chr) chr = ' ';
var s = this;
var left = side.toLowerCase()=='left';
while (s.lengthExample:
*
* "Prado.AJAX.Callback.Action.setValue".toFunction()
*
* @function {function} ?
* @returns Reference to the corresponding function
*/
toFunction : function()
{
var commands = this.split(/\./);
var command = window;
commands.each(function(action)
{
if(command[new String(action)])
command=command[new String(action)];
});
if(typeof(command) == "function")
return command;
else
{
if(typeof Logger != "undefined")
Logger.error("Missing function", this);
throw new Error ("Missing function '"+this+"'");
}
},
/**
* Convert string into integer, returns null if not integer.
* @function {int} ?
* @returns Integer, null if string does not represent an integer.
*/
toInteger : function()
{
var exp = /^\s*[-\+]?\d+\s*$/;
if (this.match(exp) == null)
return null;
var num = parseInt(this, 10);
return (isNaN(num) ? null : num);
},
/**
* Convert string into a double/float value. Internationalization
* is not supported
* @function {double} ?
* @param {string} decimalchar - Decimal character, defaults to "."
* @returns Double, null if string does not represent a float value
*/
toDouble : function(decimalchar)
{
if(this.length <= 0) return null;
decimalchar = decimalchar || ".";
var exp = new RegExp("^\\s*([-\\+])?(\\d+)?(\\" + decimalchar + "(\\d+))?\\s*$");
var m = this.match(exp);
if (m == null)
return null;
m[1] = m[1] || "";
m[2] = m[2] || "0";
m[4] = m[4] || "0";
var cleanInput = m[1] + (m[2].length>0 ? m[2] : "0") + "." + m[4];
var num = parseFloat(cleanInput);
return (isNaN(num) ? null : num);
},
/**
* Convert strings that represent a currency value to float.
* E.g. "10,000.50" will become "10000.50". The number
* of dicimal digits, grouping and decimal characters can be specified.
* The currency input format is very strict, null will be returned if
* the pattern does not match.
* @function {double} ?
* @param {string} groupchar - Grouping character, defaults to ","
* @param {int} digits - Number of decimal digits
* @param {string} decimalchar - Decimal character, defaults to "."
* @returns Double, null if string does not represent a currency value
*/
toCurrency : function(groupchar, digits, decimalchar)
{
groupchar = groupchar || ",";
decimalchar = decimalchar || ".";
digits = typeof(digits) == "undefined" ? 2 : digits;
var exp = new RegExp("^\\s*([-\\+])?(((\\d+)\\" + groupchar + ")*)(\\d+)"
+ ((digits > 0) ? "(\\" + decimalchar + "(\\d{1," + digits + "}))?" : "")
+ "\\s*$");
var m = this.match(exp);
if (m == null)
return null;
var intermed = m[2] + m[5] ;
var cleanInput = m[1] + intermed.replace(
new RegExp("(\\" + groupchar + ")", "g"), "")
+ ((digits > 0) ? "." + m[7] : "");
var num = parseFloat(cleanInput);
return (isNaN(num) ? null : num);
},
/**
* Converts the string to a date by finding values that matches the
* date format pattern.
* @function {Date} ?
* @param {string} format - Date format pattern, e.g. MM-dd-yyyy
* @returns Date extracted from the string
*/
toDate : function(format)
{
return Date.SimpleParse(this, format);
}
});
/**
* Extension to
* Prototype's Event
* @namespace Event
*/
Object.extend(Event,
{
/**
* Register a function to be executed when the page is loaded.
* Note that the page is only loaded if all resources (e.g. images)
* are loaded.
*
Example:
*
Show an alert box with message "Page Loaded!" when the
* page finished loading.
*
* Event.OnLoad(function(){ alert("Page Loaded!"); });
*
* @function ?
* @param {function} fn - Function to execute when page is loaded.
*/
OnLoad : function (fn)
{
// opera onload is in document, not window
var w = document.addEventListener &&
!window.addEventListener ? document : window;
Event.observe(w,'load',fn);
},
/**
* Returns the unicode character generated by key.
* @param {event} e - Keyboard event
* @function {int} ?
* @returns Unicode character code generated by the key that was struck.
*/
keyCode : function(e)
{
return e.keyCode != null ? e.keyCode : e.charCode
},
/**
* Checks if an Event is of type HTMLEvent.
* @function {boolean} ?
* @param {string} type - Event type or event name.
* @return true if event is of type HTMLEvent.
*/
isHTMLEvent : function(type)
{
var events = ['abort', 'blur', 'change', 'error', 'focus',
'load', 'reset', 'resize', 'scroll', 'select',
'submit', 'unload'];
return events.include(type);
},
/**
* Checks if an Event is a mouse event.
* @function {boolean} ?
* @param {string} type - Event type or event name
* @return true if event is of type MouseEvent.
*/
isMouseEvent : function(type)
{
var events = ['click', 'mousedown', 'mousemove', 'mouseout',
'mouseover', 'mouseup'];
return events.include(type);
},
/**
* Dispatch the DOM event of a given type on a DOM
* element. Only HTMLEvent and MouseEvent can be
* dispatched, keyboard events or UIEvent can not be dispatch
* via javascript consistently.
* For the "submit" event the submit() method is called.
* @function ?
* @param {element|string} element - Element id string or DOM element.
* @param {string} type - Event type to dispatch.
*/
fireEvent : function(element,type)
{
element = $(element);
if(type == "submit")
return element.submit();
if(document.createEvent)
{
if(Event.isHTMLEvent(type))
{
var event = document.createEvent('HTMLEvents');
event.initEvent(type, true, true);
}
else if(Event.isMouseEvent(type))
{
var event = document.createEvent('MouseEvents');
if (event.initMouseEvent)
{
event.initMouseEvent(type,true,true,
document.defaultView, 1, 0, 0, 0, 0, false,
false, false, false, 0, null);
}
else
{
// Safari
// TODO we should be initialising other mouse-event related attributes here
event.initEvent(type, true, true);
}
}
element.dispatchEvent(event);
}
else if(document.createEventObject)
{
var evObj = document.createEventObject();
element.fireEvent('on'+type, evObj);
}
else if(typeof(element['on'+type]) == "function")
element['on'+type]();
}
});
/**
* Extension to
* Prototype's Date
* @namespace Date
*/
Object.extend(Date.prototype,
{
/**
* SimpleFormat
* @function ?
* @param {string} format - TODO
* @param {string} data - TODO
* @returns TODO
*/
SimpleFormat: function(format, data)
{
data = data || {};
var bits = new Array();
bits['d'] = this.getDate();
bits['dd'] = String(this.getDate()).zerofill(2);
bits['M'] = this.getMonth()+1;
bits['MM'] = String(this.getMonth()+1).zerofill(2);
if(data.AbbreviatedMonthNames)
bits['MMM'] = data.AbbreviatedMonthNames[this.getMonth()];
if(data.MonthNames)
bits['MMMM'] = data.MonthNames[this.getMonth()];
var yearStr = "" + this.getFullYear();
yearStr = (yearStr.length == 2) ? '19' + yearStr: yearStr;
bits['yyyy'] = yearStr;
bits['yy'] = bits['yyyy'].toString().substr(2,2);
// do some funky regexs to replace the format string
// with the real values
var frm = new String(format);
for (var sect in bits)
{
var reg = new RegExp("\\b"+sect+"\\b" ,"g");
frm = frm.replace(reg, bits[sect]);
}
return frm;
},
/**
* toISODate
* @function {string} ?
* @returns TODO
*/
toISODate : function()
{
var y = this.getFullYear();
var m = String(this.getMonth() + 1).zerofill(2);
var d = String(this.getDate()).zerofill(2);
return String(y) + String(m) + String(d);
}
});
Object.extend(Date,
{
/**
* SimpleParse
* @function ?
* @param {string} format - TODO
* @param {string} data - TODO
* @returns TODO
*/
SimpleParse: function(value, format)
{
var val=String(value);
format=String(format);
if(val.length <= 0) return null;
if(format.length <= 0) return new Date(value);
var isInteger = function (val)
{
var digits="1234567890";
for (var i=0; i < val.length; i++)
{
if (digits.indexOf(val.charAt(i))==-1) { return false; }
}
return true;
};
var getInt = function(str,i,minlength,maxlength)
{
for (var x=maxlength; x>=minlength; x--)
{
var token=str.substring(i,i+x);
if (token.length < minlength) { return null; }
if (isInteger(token)) { return token; }
}
return null;
};
var i_val=0;
var i_format=0;
var c="";
var token="";
var token2="";
var x,y;
var now=new Date();
var year=now.getFullYear();
var month=now.getMonth()+1;
var date=1;
while (i_format < format.length)
{
// Get next token from format string
c=format.charAt(i_format);
token="";
while ((format.charAt(i_format)==c) && (i_format < format.length))
{
token += format.charAt(i_format++);
}
// Extract contents of value based on format token
if (token=="yyyy" || token=="yy" || token=="y")
{
if (token=="yyyy") { x=4;y=4; }
if (token=="yy") { x=2;y=2; }
if (token=="y") { x=2;y=4; }
year=getInt(val,i_val,x,y);
if (year==null) { return null; }
i_val += year.length;
if (year.length==2)
{
if (year > 70) { year=1900+(year-0); }
else { year=2000+(year-0); }
}
}
else if (token=="MM"||token=="M")
{
month=getInt(val,i_val,token.length,2);
if(month==null||(month<1)||(month>12)){return null;}
i_val+=month.length;
}
else if (token=="dd"||token=="d")
{
date=getInt(val,i_val,token.length,2);
if(date==null||(date<1)||(date>31)){return null;}
i_val+=date.length;
}
else
{
if (val.substring(i_val,i_val+token.length)!=token) {return null;}
else {i_val+=token.length;}
}
}
// If there are any trailing characters left in the value, it doesn't match
if (i_val != val.length) { return null; }
// Is date valid for month?
if (month==2)
{
// Check for leap year
if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
if (date > 29){ return null; }
}
else { if (date > 28) { return null; } }
}
if ((month==4)||(month==6)||(month==9)||(month==11))
{
if (date > 30) { return null; }
}
var newdate=new Date(year,month-1,date, 0, 0, 0);
return newdate;
}
});
/**
* Prado utilities for effects.
* @object Prado.Effect
*/
Prado.Effect =
{
/**
* Highlights an element
* @function ?
* @param {element} element - DOM element to highlight
* @param {optional object} options - Highlight options
*/
Highlight : function (element,options)
{
new Effect.Highlight(element,options);
}
};