/* Javascript functionality common to all files If adding to this, please bear in mind progressive enhancement - test for functionality before using it to avoid errors */ function bookmarkPage(){ //used by "bookmark page" link in page tools if(window.sidebar){ //syntax for FF. 3rd empty string argument is required window.sidebar.addPanel(document.title, location.href,''); }else{ if(window.external){ //syntax for IE window.external.AddFavorite(location.href,document.title); } } } function printPage(){ //used by "print page" link in page tools window.print(); } function findExitRamps(){ //identify any links with an exit ramp aryExtLinks=getElementsByClassName(document,'external'); /* possible HTML is: */ for(i=0;i0){ selectBox.options[i].selected=false; } //record setting of each option in array selectBoxSelected[i]=selectBox.options[i].selected; } } } function toggleRelatedSelects(){ //checks whether "this site only" in site select box is selected //if so, enables audience and area select boxes //if not, disables them var siteSelectBox=document.getElementById('rskey'); var areaSelectBox=getNamedElementId('select','sakey'); var audienceSelectBox=document.getElementById('saudkey'); if(siteSelectBox.options[0].selected==true){ if(areaSelectBox){ areaSelectBox.disabled=false; } if(audienceSelectBox){ audienceSelectBox.disabled=false; } }else{ if(areaSelectBox){ areaSelectBox.disabled=true; } if(audienceSelectBox){ audienceSelectBox.disabled=true; } } return true; } function showHelp(){ //shows or hides the help popup for form field onclick //popup also appears on hover - this is for keyboard users //get a reference to the a tag which was clicked el=this; //switch off any other help popups els=getElementsByClassName(document,'inhelplink'); already_set=false; if(els){ for(var i=0,j=els.length; i0 && currentClass.indexOf(oldValue)!==-1){ //replace it newClass=currentClass.replace(oldValue,newValue); }else{ if(currentClass.indexOf(newValue)==-1){ //newValue not already in the className //add it newClass=currentClass+' '+newValue; }else{ //newValue is already there so keep it as it is newClass=currentClass; } } } setAttributeCrossBrowser(element,'class',newClass); break; default: //this isn't finished - doesn't toggle at the moment, just overwrites setAttributeCrossBrowser(element,attribute,newValue); break; } } function addPrototypeEffects(){ if(prototypeAZFunctions && prototypeAZFunctions.hasPrototype()){ prototypeAZFunctions.addDatePickers(); prototypeAZFunctions.addTimePickers(); prototypeAZFunctions.addExitRamps(); prototypeAZFunctions.addOverlayBackgroundLoader(); prototypeAZFunctions.addPdfBasket(); /*$$('.blind').each(function(el){ el.observe('click',toggleBlinds); }); */ /*something like this new Effect.Move($('event_details'),{ x: 0, y: 0, mode: 'absolute' }); replace the X and Y values with Event.pointerX(event); see http://www.prototypejs.org/api/event/pointerX maybe combine with effect.appear - move it first then make it appear try to make this generic - maybe a class on the link? http://wiki.github.com/madrobby/scriptaculous/effect-appear also have a think about absolutise in prototype */ } } var minOpacity = 0.3; var prototypeAZFunctions = function(){ //anything here is private return{ //anything here is public. Call using prototypeAZFunctions.functionName(); hasPrototype : function(){ return typeof Prototype !== 'undefined'; }, addDatePickers : function(){ $$('.datepicker').each(function(el){ var picker = new Control.DatePicker(el, {datePicker: true, timePicker: false, locale: 'en_GB' }); }); }, addTimePickers : function(){ $$('.timepicker').each(function(el){ var picker = new Control.DatePicker(el, {datePicker: false, timePicker: true, use24hrs:true, locale: 'en_GB' }); }); }, addPdfBasket : function(){ var divName = 'overlay_container'; $$('.pdf_basket').each(function(el){ //this is the element where the response should be directed el.writeAttribute('target_element',divName); //replace the existing link with an AJAX request //not sure about the namespace use here. el.observe('click', prototypeAZFunctions.pdfBasketAjaxUpdater ); }); }, addExitRamps : function(){ var divName = 'overlay_container'; $$('.exit_ramp').each(function(el){ //this is the element where the response should be directed el.writeAttribute('target_element',divName); //replace the existing link with an AJAX request //not sure about the namespace use here. el.observe('click', prototypeAZFunctions.simpleAjaxUpdater ); }); }, addOverlayBackgroundLoader : function(){ //simply detects the presence of an anchor with ID loadUrl containing a URL //and loads it in a div named overlay_background //which is created on the fly var anchor = $('loadUrl'); var outerDiv = document.body.firstDescendant(); if(anchor){ var url = anchor.href; if(url != ''){ var targetName = 'overlay_background'; anchor.remove(); target = new Element('div'); //native JS method here target.setAttribute('id',targetName); document.body.insertBefore(target,outerDiv); var updater = new Ajax.Updater(target,url,{ method: 'get', parameters: {ajaxRequestFromOverlay:true}, onSuccess: function(){prototypeAZFunctions.fadeOutElement(target);} }); } } }, fadeOutElement : function(el){ el.fade({duration:0.5, from:1, to:minOpacity}); document.body.addClassName('faded'); document.body.firstDescendant().addClassName('bottomlayer'); }, fadeOutBackground : function(){ prototypeAZFunctions.fadeOutElement(document.body.firstDescendant()); }, fadeInBackground : function(){ document.body.removeClassName('faded'); document.body.firstDescendant().fade({duration:0.5, from:minOpacity, to:1}); document.body.firstDescendant().removeClassName('bottomlayer'); }, exitRamp : function(){ //make cancel button just empty the overlay $$('div[id="overlay_container"] .cancel').each(function(el){ el.observe('click',function(event){ event.stop(); //fade out the link, then remove it $('overlay_container').fade({duration:1.0, from:1, to:0}); $('overlay_container').remove(); prototypeAZFunctions.fadeInBackground(); }); }); }, simpleAjaxUpdater : function(event){ //pull the necessary information from the updater //this format should be used for all requests which are AJAX enabled //first of all, kill the request event.stop(); var anchor = event.findElement('a'); var targetName = anchor.readAttribute('target_element'); var newWindow = anchor.readAttribute('target'); var params = {}; params['ajaxSource'] = true;//makes webapp believe this is an AJAX request (same syntax as a Spring AJAX request) if(newWindow != ''){ params['newWindow'] = true; } var target; if(!$(targetName)){ target = new Element('div'); //native JS method here target.setAttribute('id',targetName); document.body.appendChild(target); }else{ target = $(targetName); } var updater = new Ajax.Updater(target,anchor.href,{ method: 'get', parameters: params, onSuccess: function(){prototypeAZFunctions.fadeOutBackground();}, onComplete: function(){prototypeAZFunctions.exitRamp();} }); }, pdfBasket : function(){ //make cancel button just empty the overlay $$('div[id="overlay_container"] .close').each(function(el){ el.observe('click',function(event){ event.stop(); //fade out the link, then remove it $('overlay_container').fade({duration:1.0, from:1, to:0}); $('overlay_container').remove(); prototypeAZFunctions.fadeInBackground(); }); }); }, pdfBasketAjaxUpdater : function(event){ //pull the necessary information from the updater //this format should be used for all requests which are AJAX enabled //first of all, kill the request event.stop(); var anchor = event.findElement('a'); var targetName = anchor.readAttribute('target_element'); var newWindow = anchor.readAttribute('target'); var params = {}; params['ajaxSource'] = true;//makes webapp believe this is an AJAX request (same syntax as a Spring AJAX request) if(newWindow != ''){ params['newWindow'] = true; } var target; if(!$(targetName)){ target = new Element('div'); //native JS method here target.setAttribute('id',targetName); document.body.appendChild(target); }else{ target = $(targetName); } var updater = new Ajax.Updater(target,anchor.href,{ method: 'get', parameters: params, onSuccess: function(){prototypeAZFunctions.fadeOutBackground();}, onComplete: function(){prototypeAZFunctions.addPdfBasket();prototypeAZFunctions.pdfBasket();} }); } //not in use yet, untested /* function applyAjaxEvents(){//apply the AJAX events to panels $$('a[id^=ajax]').each(function(el){ el.observe('click',expandCollapse); }); } function addSWFObjects(){ if(hasPrototype){ $$('.swf_player').each(function(el){ swfobject.registerObject(el.id); }); } } */ }; }(); function expandCollapse(event){ //not in use yet //first of all, kill the request event.stop(); //the link which was clicked var anchor = event.element(); //its querystring var qs = anchor.search; //as an associative array var qsParams = qs.toQueryParams(); //the desired action var actionParam = qs.indexOf('expand') != -1 ? 'expand' : 'collapse'; //the panel's itemId var actionParamLength=actionParam.length; var startSearch = qs.indexOf(actionParam+'Panel') + actionParamLength + 5; var panelItemId = qs.substring(startSearch,qs.indexOf('=true',startSearch)); //the desired QS parameter for the server var firstRequestParameter = actionParam + 'Panel' + panelItemId; //actionParam += 'Panel' + qsParams.actionParam; var params = {}; params[firstRequestParameter] = true; params['tileRefresh'] = true; params['tileDefinition'] = 'tiles.panel.decorator'; params['panelItemId'] = panelItemId; params['requestItemKey'] = qsParams.requestItemKey; params['ajaxSource'] = true; //to fool app into thinking this is a Spring AJAX request //try to get link's parent here? might be easier/more portable //console.log('panel' + panelItemId); var updater = new Ajax.Updater('panel' + panelItemId,"",{ onComplete: applyAjaxEvents, method: 'get', parameters: params } ); } function toggleBlinds(event){ var parentEl=event.element(); if(parentEl.id.startsWith('child')){ //we actually want to apply the effect to the named element //in the format child_elementname var childId=parentEl.id.split('_')[1]; var el=$(childId); } if(el){ Effect.toggle(el,'blind'); parentEl.toggleClassName('collapsed'); return false; } } function attachEvents(){ //goes through the document //finds elements which can have enhanced JS functionality //adds that functionality, if supported //find "print page" link linkPrint=document.getElementById('print_page'); if(linkPrint){ if(window.print){ linkPrint.onclick=function(){printPage();}; } } //find "bookmark page" link linkBookmark=document.getElementById('bookmark_page'); if(linkBookmark){ if(window.external || window.sidebar){ linkBookmark.onclick=function(){bookmarkPage();}; } } //necessary as more than one element has name sakey sakey=getNamedElementId('select','sakey'); if(sakey){ sakey.onchange=function(){toggleSelection(sakey);}; } //find site select on advanced search rskey=document.getElementById('rskey'); if(rskey){ rskey.onchange=function(){toggleRelatedSelects();}; } findExitRamps(); prepareHelpLinks(); //now call any additional functions which need to be executed onload //these are defined in site, model or sub-model specific js files //in an array called toCall if(typeof(toCall)=='object'){ for(j=0;j