AJAX_DEFAULT_PARAMETER = "ajaxParameter"; AJAX_PORTLET_MAX = 1; AJAX_PORTLET_MIN = 2; AJAX_PORTLET_CLOSE = 3; AJAX_CALLOUT_OVERLIB_DEFAULT = "STICKY," + "CLOSECLICK," + "DELAY,250," + "TIMEOUT,5000," + "VAUTO,WRAPMAX,240," + "CSSCLASS,FGCLASS,'olfg',BGCLASS,'olbg',CGCLASS,'olcg'," + "CAPTIONFONTCLASS,'olcap',CLOSEFONTCLASS,'olclo',TEXTFONTCLASS,'oltxt'"; /** * Type Detection */ function isAlien(a) { return isObject(a) && typeof a.constructor != 'function'; } function isArray(a) { return isObject(a) && a.constructor == Array; } function isBoolean(a) { return typeof a == 'boolean'; } function isEmpty(o) { var i, v; if (isObject(o)) { for (i in o) { v = o[i]; if (isUndefined(v) && isFunction(v)) { return false; } } } return true; } function isFunction(a) { return typeof a == 'function'; } function isNull(a) { return typeof a == 'object' && !a; } function isNumber(a) { return typeof a == 'number' && isFinite(a); } function isObject(a) { return (a && typeof a == 'object') || isFunction(a); } function isString(a) { return typeof a == 'string'; } function isUndefined(a) { return typeof a == 'undefined'; } /* ---------------------------------------------------------------------- */ /* Example File From "_JavaScript and DHTML Cookbook" Published by O'Reilly & Associates Copyright 2003 Danny Goodman */ // utility function to retrieve a future expiration date in proper format; // pass three integer parameters for the number of days, hours, // and minutes from now you want the cookie to expire; all three // parameters required, so use zeros where appropriate function getExpDate(days, hours, minutes) { var expDate = new Date(); if (typeof days == "number" && typeof hours == "number" && typeof hours == "number") { expDate.setDate(expDate.getDate() + parseInt(days)); expDate.setHours(expDate.getHours() + parseInt(hours)); expDate.setMinutes(expDate.getMinutes() + parseInt(minutes)); return expDate.toGMTString(); } } // utility function called by getCookie() function getCookieVal(offset) { var endstr = document.cookie.indexOf (";", offset); if (endstr == -1) { endstr = document.cookie.length; } return unescape(document.cookie.substring(offset, endstr)); } // primary function to retrieve cookie by name function getCookie(name) { var arg = name + "="; var alen = arg.length; var clen = document.cookie.length; var i = 0; while (i < clen) { var j = i + alen; if (document.cookie.substring(i, j) == arg) { return getCookieVal(j); } i = document.cookie.indexOf(" ", i) + 1; if (i == 0) break; } return null; } // store cookie value with optional details as needed function setCookie(name, value, expires, path, domain, secure) { document.cookie = name + "=" + escape (value) + ((expires) ? "; expires=" + expires : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : ""); } // remove the cookie by setting ancient expiration date function deleteCookie(name,path,domain) { if (getCookie(name)) { document.cookie = name + "=" + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + "; expires=Thu, 01-Jan-70 00:00:01 GMT"; } } /* ---------------------------------------------------------------------- */ /* End Copyright 2003 Danny Goodman */ function addOnLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { oldonload(); func(); } } } function replaceWithValue(sourceString, regExp, element) { var retString = ""; switch (element.type) { case 'checkbox': case 'radio': case 'text': case 'textarea': case 'password': case 'hidden': case 'select-one': case 'select-multiple': retString = sourceString.replace(regExp, $F(element)); break; default: retString = sourceString.replace(regExp, element.innerHTML); break; } return retString; } /* * Extract querystring from a URL */ function extractQueryString(url) { var ret = (url.indexOf('?') >= 0 && url.indexOf('?') < (url.length-1)) ? url.substr(url.indexOf('?')+1) : ''; return ret; } /* * Trim the querystring from a URL */ function trimQueryString(url) { var ret = url.indexOf('?') >= 0 ? url.substring(0, url.indexOf('?')) : url; return ret; } /* * */ function delimitQueryString(qs) { var ret = ''; if (qs.length > 0) { var params = qs.split('&'); for (var i=0; i 0) ret += ','; ret += params[i]; } } return ret; } function buildParameterString(parameterList) { var ajaxParameters = parameterList || ''; var re = new RegExp("(\\{[^,]*\\})", 'g'); // should retrieve each {} group var results = ajaxParameters.match(re); if (results != null) { for (var r=0; r 0) { var responseNode = responseNodes[0]; var itemNodes = responseNode.getElementsByTagName("item"); for (var i=0; i 0 && valueNodes.length > 0) { var name = nameNodes[0].firstChild.nodeValue; var value = valueNodes[0].firstChild.nodeValue; this.itemList.push(new Array(name, value)); } } } } }); ResponseHtmlParser = Class.create(); ResponseHtmlParser.prototype = Object.extend(new AbstractResponseParser(), { initialize: function() { this.type = "html"; }, load: function(request) { this.content = request.responseText; } }); ResponseXmlToHtmlParser = Class.create(); ResponseXmlToHtmlParser.prototype = Object.extend(new AbstractResponseParser(), { initialize: function() { this.type = "xmltohtml"; }, load: function(request) { this.xml = request.responseXML; this.parse(); }, parse: function() { this.content = ''; var root = this.xml.documentElement; var responseNodes = root.getElementsByTagName("response"); if (responseNodes.length > 0) { var responseNode = responseNodes[0]; var itemNodes = responseNode.getElementsByTagName("item"); for (var i=0; i 0 && valueNodes.length > 0) { var name = nameNodes[0].firstChild.nodeValue; var value = valueNodes[0].firstChild.nodeValue; this.content += '

' + name + '

'; this.content += '
' + value + '
'; } } } } }); ResponseXmlToHtmlListParser = Class.create(); ResponseXmlToHtmlListParser.prototype = Object.extend(new AbstractResponseParser(), { initialize: function() { this.type = "xmltohtmllist"; }, load: function(request) { this.xml = request.responseXML; this.parse(); }, parse: function() { var ul = '
    '; var root = this.xml.documentElement; var responseNodes = root.getElementsByTagName("response"); if (responseNodes.length > 0) { var responseNode = responseNodes[0]; var itemNodes = responseNode.getElementsByTagName("item"); for (var i=0; i 0 && valueNodes.length > 0) { var name = nameNodes[0].firstChild.nodeValue; var value = valueNodes[0].firstChild.nodeValue; ul += '
  • ' + name + '
  • '; } } } ul += '
'; this.content = ul; } }); var AjaxJspTag = { Version: '1.2' } AjaxJspTag.Base = function() {}; AjaxJspTag.Base.prototype = { resolveParameters: function() { // Strip URL of querystring and append it to parameters var qs = delimitQueryString(extractQueryString(this.url)); if (this.options.parameters) { this.options.parameters += ',' + qs; } else { this.options.parameters = qs; } this.url = trimQueryString(this.url); if (this.options.parameters.length > 0 && this.options.parameters.charAt(this.options.parameters.length-1) == ',') { this.options.parameters = this.options.parameters.substr(0,this.options.parameters.length-1); } } } AjaxJspTag.UpdateField = Class.create(); AjaxJspTag.UpdateField.prototype = Object.extend(new AjaxJspTag.Base(), { initialize: function(url, options) { this.url = url; this.setOptions(options); this.setListeners(); }, setOptions: function(options) { this.options = Object.extend({ parameters: options.parameters || '', eventType: options.eventType ? options.eventType : "click", parser: options.parser ? options.parser : new ResponseTextParser(), handler: options.handler ? options.handler : this.handler }, options || {}); }, setListeners: function() { eval("$(this.options.action).on"+this.options.eventType+" = this.execute.bindAsEventListener(this)"); }, execute: function(e) { if (this.options.preFunction != null) this.options.preFunction(); // parse parameters and do replacements var params = buildParameterString(this.options.parameters); // parse targets var targetList = this.options.target.split(','); var obj = this; // required because 'this' conflict with Ajax.Request var setFunc = this.setField; var aj = new Ajax.Request(this.url, { asynchronous: true, method: 'get', parameters: params, onSuccess: function(request) { obj.options.parser.load(request); var results = obj.options.parser.itemList; obj.options.handler(request, {targets: targetList, items: results}); }, onFailure: function(request) { if (obj.options.errorFunction != null) obj.options.errorFunction(request); }, onComplete: function(request) { if (obj.options.postFunction != null) obj.options.postFunction(request); } }); }, handler: function(request, options) { for (var i=0; i 0 || parseInt(this.options.expireHours) > 0 || parseInt(this.options.expireMinutes) > 0) { this.preserveState = true; this.options.expireDate = getExpDate( parseInt(this.options.expireDays), parseInt(this.options.expireHours), parseInt(this.options.expireMinutes)); } this.isAutoRefreshSet = false; }, setListeners: function() { if (this.options.imageClose) { eval("$(this.options.close).on"+this.options.eventType+" = this.closePortlet.bindAsEventListener(this)"); } if (this.options.imageRefresh) { eval("$(this.options.refresh).on"+this.options.eventType+" = this.refreshPortlet.bindAsEventListener(this)"); } if (this.options.imageMaximize && this.options.imageMinimize) { eval("$(this.options.toggle).on"+this.options.eventType+" = this.togglePortlet.bindAsEventListener(this)"); } }, execute: function(e) { if (this.options.preFunction != null) this.options.preFunction(); // parse parameters and do replacements this.resolveParameters(); var params = buildParameterString(this.options.parameters); var obj = this; // required because 'this' conflict with Ajax.Request if (this.options.refreshPeriod && this.isAutoRefreshSet == false) { // periodic updater var freq = this.options.refreshPeriod; this.ajaxPeriodicalUpdater = new Ajax.PeriodicalUpdater(this.options.target, this.url, { asynchronous: true, method: 'get', parameters: params, frequency: freq, onFailure: function(request) { if (obj.options.errorFunction != null) obj.options.errorFunction(request); }, onComplete: function(request) {}, onSuccess: function(request) { if (obj.options.postFunction != null) obj.options.postFunction(request); } }); this.isAutoRefreshSet = true; } else { // normal updater this.ajaxUpdater = new Ajax.Updater(this.options.target, this.url, { asynchronous: true, method: 'get', parameters: params, onFailure: function(request) { if (obj.options.errorFunction != null) obj.options.errorFunction(request); }, onComplete: function(request) { if (obj.options.postFunction != null) obj.options.postFunction(request); } }); } }, checkCookie: function() { // Check cookie for save state var cVal = getCookie("AjaxJspTag.Portlet."+this.options.source); if (cVal != null) { if (cVal == AJAX_PORTLET_MIN) { this.togglePortlet(); } else if (cVal == AJAX_PORTLET_CLOSE) { this.closePortlet(); } } }, stopAutoRefresh: function() { // stop auto-update if present if (this.ajaxPeriodicalUpdater != null && this.options.refreshPeriod && this.isAutoRefreshSet == true) { this.ajaxPeriodicalUpdater.stop(); } }, startAutoRefresh: function() { // stop auto-update if present if (this.ajaxPeriodicalUpdater != null && this.options.refreshPeriod) { this.ajaxPeriodicalUpdater.start(); } }, refreshPortlet: function(e) { // clear existing updater this.stopAutoRefresh(); if (this.ajaxPeriodicalUpdater != null) { this.startAutoRefresh(); } else { this.execute(); } }, closePortlet: function(e) { this.stopAutoRefresh(); Element.remove(this.options.source); // Save state in cookie if (this.preserveState) { setCookie("AjaxJspTag.Portlet."+this.options.source, AJAX_PORTLET_CLOSE, this.options.expireDate); } }, togglePortlet: function(e) { Element.toggle(this.options.target); if (this.options.isMaximized) { $(this.options.toggle).src = this.options.imageMaximize; this.stopAutoRefresh(); } else { $(this.options.toggle).src = this.options.imageMinimize; this.startAutoRefresh(); } this.options.isMaximized = !this.options.isMaximized; // Save state in cookie if (this.preserveState) { setCookie("AjaxJspTag.Portlet."+this.options.source, (this.options.isMaximized == true ? AJAX_PORTLET_MAX : AJAX_PORTLET_MIN), this.options.expireDate); } } }); Ajax.XmlToHtmlAutocompleter = Class.create(); Object.extend(Object.extend(Ajax.XmlToHtmlAutocompleter.prototype, Autocompleter.Base.prototype), { initialize: function(element, update, url, options) { this.baseInitialize(element, update, options); this.options.asynchronous = true; this.options.onComplete = this.onComplete.bind(this); this.options.defaultParams = this.options.parameters || null; this.url = url; }, getUpdatedChoices: function() { entry = encodeURIComponent(this.options.paramName) + '=' + encodeURIComponent(this.getToken()); this.options.parameters = this.options.callback ? this.options.callback(this.element, entry) : entry; if(this.options.defaultParams) this.options.parameters += '&' + this.options.defaultParams; new Ajax.Request(this.url, this.options); }, onComplete: function(request) { var parser = new ResponseXmlToHtmlListParser(); parser.load(request); this.updateChoices(parser.content); } }); AjaxJspTag.Autocomplete = Class.create(); AjaxJspTag.Autocomplete.prototype = Object.extend(new AjaxJspTag.Base(), { initialize: function(url, options) { this.url = url; this.setOptions(options); $(this.options.source).setAttribute("autocomplete", "off"); // create DIV new Insertion.After(this.options.source, '
'); this.execute(); }, setOptions: function(options) { this.options = Object.extend({ divElement: "ajaxAuto_" + options.source, indicator: options.indicator || '', parameters: options.parameters || '', parser: options.parser ? options.parser : new ResponseHtmlParser(), handler: options.handler ? options.handler : this.handler }, options || {}); }, execute: function(e) { if (this.options.preFunction != null) this.options.preFunction(); // parse parameters and do replacements var params = buildParameterString(this.options.parameters); params = params.replace(new RegExp(',', 'g'), '&'); var obj = this; // required because 'this' conflict with Ajax.Request var aj = new Ajax.XmlToHtmlAutocompleter( this.options.source, this.options.divElement, this.url, {minChars: obj.options.minimumCharacters, tokens: obj.options.appendSeparator, indicator: obj.options.indicator, parameters: params, afterUpdateElement: function(inputField, selectedItem) { obj.options.handler(null, { selectedItem: selectedItem, tokens: obj.options.appendSeparator, target: obj.options.target } ); } } ); }, handler: function(request, options) { if (options.target) { if (options.tokens) { if ($(options.target).value.length > 0) { $(options.target).value += options.tokens; } $(options.target).value += options.selectedItem.id; } else { $(options.target).value = options.selectedItem.id; } } } }); AjaxJspTag.Toggle = Class.create(); AjaxJspTag.Toggle.prototype = Object.extend(new AjaxJspTag.Base(), { initialize: function(url, options) { this.url = url; this.setOptions(options); // create message DIV if (this.options.messageClass) { this.messageContainer = new Insertion.Top($(this.options.source), '
'); } this.setListeners(); }, setOptions: function(options) { this.options = Object.extend({ parameters: options.parameters || '', parser: options.parser ? options.parser : new ResponseTextParser(), handler: options.handler ? options.handler : this.handler }, options || {}); }, setListeners: function() { // attach events to anchors var elements = $(this.options.source).getElementsByTagName('a'); for (var j=0; j -1) { if (i <= selectedIndex && i <= currentIndex) Element.addClassName(elements[i], this.options.selectedOverClass); else if (i <= selectedIndex && i > currentIndex) Element.addClassName(elements[i], this.options.selectedLessClass); else if (i > selectedIndex && i <= currentIndex) Element.addClassName(elements[i], this.options.overClass); } else { if (i <= currentIndex) Element.addClassName(elements[i], this.options.overClass); } } }, raterMouseOut: function (e) { // get containing div var container = Event.findElement(e, 'div'); // get list of all anchors var elements = container.getElementsByTagName('a'); // clear message if (this.options.messageClass) { $(container.id+'_message').innerHTML = ''; } // iterate over each anchor and apply styles for (var i=0; i currentIndex) { Element.removeClassName(elements[i], this.options.selectedClass); } } // send AJAX var ratingToSend = elements[currentIndex].title; if (Element.hasClassName(container, 'onoff')) { // send opposite of what was selected var ratings = this.options.ratings.split(','); if (ratings[0] == ratingToSend) ratingToSend = ratings[1]; else ratingToSend = ratings[0]; } this.execute(ratingToSend); // set field (if defined) if (this.options.state) { $(this.options.state).value = ratingToSend; } }, execute: function(ratingValue) { if (this.options.preFunction != null) this.options.preFunction(); // parse parameters and do replacements var params = buildParameterString('rating='+ratingValue); var obj = this; // required because 'this' conflict with Ajax.Request var toggleStateFunc = this.getToggleStateValue; var aj = new Ajax.Request(this.url, { asynchronous: true, method: 'get', parameters: params, onSuccess: function(request) { obj.options.parser.load(request); var results = obj.options.parser.itemList; obj.options.handler(request, {items: results}); }, onFailure: function(request) { if (obj.options.errorFunction != null) obj.options.errorFunction(request); }, onComplete: function(request) { if (obj.options.postFunction != null) obj.options.postFunction(request); } }); }, handler: function(request, options) { // TODO: anything? }, getToggleStateValue: function(name, results) { for (var i=0; i