/** * Copyright 2005 Darren L. Spurgeon * Copyright 2007 Jens Kapitza * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var AjaxJspTag = { Version: '1.3' }; /** * AjaxTags */ 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); } } }; /** * Prefunction Invoke Ajax.Update TAG */ AjaxJspTag.PreFunctionUpdateInvoke = Class.create(); AjaxJspTag.PreFunctionUpdateInvoke.prototype = Object.extend(new AjaxJspTag.Base(), { initialize: function(ajaxupdateData) { this.preFunction = ajaxupdateData.preFunction; if (isFunction(this.preFunction)) { this.preFunction(); } if (this.cancelExecution) { this.cancelExecution = false; return ; } var thisCall = new Ajax.Updater(ajaxupdateData.id,ajaxupdateData.href,{onComplete: ajaxupdateData.postFunction}); } }); /** * UPDATEFIELD TAG */ AjaxJspTag.UpdateField = Class.create(); AjaxJspTag.UpdateField.prototype = Object.extend(new AjaxJspTag.Base(), { initialize: function(url, options) { this.url = url; this.setOptions(options); this.setListeners(); addAjaxListener(this); }, reload: function () { this.setListeners(); }, setOptions: function(options) { this.options = Object.extend({ parameters: options.parameters || '', doPost: options.doPost || false, valueUpdateByName: options.valueUpdateByName || false, eventType: options.eventType ? options.eventType : "click", parser: options.parser ? options.parser : ( options.valueUpdateByName ? new ResponseXmlParser(): 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 (isFunction(this.options.preFunction)) { this.options.preFunction(); } if (this.options.cancelExecution) { this.cancelExecution = false; return ; } // 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: obj.options.doPost ? 'post':'get', evalScripts: true, 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 (isFunction(obj.options.errorFunction)){ obj.options.errorFunction(request,obj.options.parser); } }, onComplete: function(request) { if (isFunction(obj.options.postFunction)) { obj.options.postFunction(); } } }); }, handler: function(request, optionsArr) { // this points to options for (var i=0; i 0) cur[0].className = ''; // add class to selected tab options.source.className = options.currentStyleClass; } }); /** * PORTLET TAG */ AjaxJspTag.Portlet = Class.create(); AjaxJspTag.Portlet.prototype = Object.extend(new AjaxJspTag.Base(), { initialize: function(url, options) { this.url = url; this.setOptions(options); this.setListeners(); if (parseBoolean(this.options.executeOnLoad )) { this.execute(); } if (this.preserveState) this.checkCookie(); if (parseBoolean(this.options.startMinimize)) { this.togglePortlet(); } addAjaxListener(this); // should i reloadAjaxListeners() after execute? }, reload: function () { this.setListeners(); }, setOptions: function(options) { this.options = Object.extend({ parameters: options.parameters || '', target: options.source+"Content", close: options.source+"Close", startMinimize: options.startMinimize || false, refresh: options.source+"Refresh", toggle: options.source+"Size", isMaximized: true, expireDays: options.expireDays || "0", expireHours: options.expireHours || "0", expireMinutes: options.expireMinutes || "0", executeOnLoad: evalBoolean(options.executeOnLoad, true), refreshPeriod: options.refreshPeriod || null, eventType: options.eventType ? options.eventType : "click", parser: options.parser ? options.parser : new ResponseHtmlParser(), handler: options.handler ? options.handler : this.handler }, options || {}); if (parseInt(this.options.expireDays) > 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 (isFunction(this.options.preFunction)){ this.options.preFunction();} if (this.options.cancelExecution) { this.cancelExecution = false; return ; } // 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', evalScripts: true, parameters: params, frequency: freq, onFailure: function(request) { if (isFunction(obj.options.errorFunction)){ obj.options.errorFunction();} }, onComplete: function(request) {}, onSuccess: function(request) { if (isFunction(obj.options.postFunction)) {obj.options.postFunction();} } }); this.isAutoRefreshSet = true; } else { // normal updater this.ajaxUpdater = new Ajax.Updater(this.options.target, this.url, { asynchronous: true, method: 'get', parameters: params, evalScripts: true, onFailure: function(request) { if (isFunction(obj.options.errorFunction)) {obj.options.errorFunction();} }, onComplete: function(request) { if (isFunction(obj.options.postFunction)) {obj.options.postFunction();} } }); } }, 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) { if (this.options.imageMaximize){ $(this.options.toggle).src = this.options.imageMaximize; } this.stopAutoRefresh(); } else { if (this.options.imageMinimize){ $(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); } } }); /** * AUTOCOMPLETE TAG */ 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; }, // onblur hack IE works with FF onBlur: function (event) { // Dont hide the div on "blur" if the user clicks scrollbar if(Element.getStyle(this.update, 'height') != ''){ var x=999999; var y=999999; var offsets = Position.positionedOffset(this.update); var top = offsets[1]; var left = offsets[0]; var data = Element.getDimensions(this.update); var width = data.width; var height = data.height; if (event) { x=event.x-left; y=event.y -top; } if (x > 0 && x < width && y > 0 && y < height ) { this.element.focus(); return; } } // needed to make click events working setTimeout(this.hide.bind(this), 250); this.hasFocus = false; this.active = false; }, getUpdatedChoices: function() { if (isFunction(this.options.preFunction)){ this.options.preFunction();} // preFunction can cancelExecution set this.cancelExecution = true; if (this.options.cancelExecution) { this.cancelExecution = false; this.stopIndicator(); return ; } entry = encodeURIComponent(this.options.paramName) + '=' + encodeURIComponent(this.getToken()); this.options.parameters = this.options.callback ? this.options.callback(this.element, entry) : entry; // parse parameters and do replacements var params = buildParameterString(this.options.defaultParams); if (!isEmpty(params) || (isString(params) && params.length > 0)) { this.options.parameters += '&' + params; } new Ajax.Request(this.url, this.options); }, onComplete: function(request) { var parser = this.options.parser; 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); // 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 ResponseXmlToHtmlListParser(), handler: options.handler ? options.handler : this.handler }, options || {}); }, execute: function(e) { // preFunction moved bevor request now 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: obj.options.parameters, evalScripts: true, preFunction: obj.options.preFunction, parser: obj.options.parser, afterUpdateElement: function(inputField, selectedItem) { obj.options.handler(null, { selectedItem: selectedItem, tokens: obj.options.appendSeparator, target: obj.options.target, inputField: inputField, postFunction: obj.options.postFunction, list:obj.options.parser.getArray(), options: obj.options, autocomplete:aj } ); } } ); }, 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; } } options.selectedIndex = options.autocomplete.index; options.selectedObject = options.list[options.autocomplete.index]; if (isFunction(options.postFunction)) { //Disable onupdate event handler of input field //because, postFunction can change the content of //input field and get into eternal loop. var onupdateHandler = $(options.inputField).onupdate; $(options.inputField).onupdate = ''; options.postFunction(); //Enable onupdate event handler of input field $(options.inputField).onupdate = onupdateHandler; } } }); /** * TOGGLE TAG */ 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(); addAjaxListener(this); }, reload: function () { this.setListeners(); }, setOptions: function(options) { this.options = Object.extend({ parameters: options.parameters || 'rating={ajaxParameter}', parser: options.parser ? options.parser : new ResponseTextParser(), handler: options.handler ? options.handler : this.handler, updateFunction: options.updateFunction || false }, options || {}); this.ratingParameter = AJAX_DEFAULT_PARAMETER; }, 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]; elements[currentIndex].title = ratingToSend; } this.execute(ratingToSend); // set field (if defined) if (this.options.state) { $(this.options.state).value = ratingToSend; } }, execute: function(ratingValue) { if (isFunction(this.options.preFunction)){ this.options.preFunction();} if (this.options.cancelExecution) { this.cancelExecution = false; return ; } // parse parameters and do replacements var ajaxParameters = this.options.parameters || ''; var re = new RegExp("(\\{"+this.ratingParameter+"\\})", 'g'); ajaxParameters = ajaxParameters.replace(re, ratingValue); var params = buildParameterString(ajaxParameters); 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', evalScripts: true, 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 (isFunction(obj.options.errorFunction)){ obj.options.errorFunction();} }, onComplete: function(request) { if (isFunction(obj.options.postFunction)) {obj.options.postFunction();} } }); }, handler: function(request, roptions) { //daten in items var erg = roptions.items[0][0] ; // on/off / 1,2,3 try { this.updateFunction(erg); // TODO: anything? } catch (e) {} // muss nicht forhanden sein }, getToggleStateValue: function(name, results) { for (var i=0; i