var exlDebug = false;
$(document).ready(function(){
//prepare searchTile
try{
setupSearch();
}catch(searchErr){
log('search setup failed:'+searchErr);
}
//prepare sort by drop down
try{
setupSortByMenu();
}catch(sortErr){
log('sortBy menu setup failed:'+sortErr);
}
//prepare sort by drop down
try{
setupLanguageMenu();
}catch(langMenuErr){
log('languages menu setup failed:'+langMenuErr);
}
//prepare the eshelf star functionality
try{
setupEshelfStar();
}catch(eshelfStarErr){
log('eShelf star setup failed:'+eshelfStarErr);
}
//prepare the facets list functionality
try{
setupFacets();
}catch(facetsErr){
log('facets setup failed:'+facetsErr);
}
//prepare send-to drop down list functionality
try{
setupSendToMenu();
}catch(sendToErr){
log('sendTo menu setup failed:'+sendToErr);
}
//load default ajax infrastructure
try{
prepareAjax();
}catch(prepAjaxErr){
log('ajax setup failed:'+prepAjaxErr);
}
//prepare tab functionality to track user selection and loading of tab content
try{
prepTabs();
}catch(prepTabsErr){
log('tab setup failed:'+prepTabsErr);
}
//start the prefetch mechanism
try{
prefetchTabContent();
}catch(prefetchTabsErr){
log('tab prefetch failed:'+prefetchTabsErr);
}
try{
hideRecommendTabs();
}catch(hideRecommendTabsErr){
log('hide recommend tab failed:'+hideRecommendTabsErr);
}
});
function
setupSearch(){
// right now, all the search setup consists of setting up the scope dropdown.
// first we hide all the radio buttons - they must be visible initially or else the browser doesn't recognize them and they don't work.
// then tell the list to hide all the options - this is necesary so that when there's no javascript the radio button list is fully visible.
// finally add a handler to the one showing option so that when it's clicked we popup the list.
$('#search_field').focus();
$('.EXLSearchFieldRibbonFormCollectionsList').hide(); //hide it initially
/* var scopeDisplay = $('.EXLSearchFieldRibbonFormSelectedCollection');
if ($(scopeDisplay).text().match(/^[\s]*$/)){
alert('first: ' + $('.EXLSearchFieldRibbonFormCollectionsList label').eq(0).text());
$(scopeDisplay).append('
'+$('.EXLSearchFieldRibbonFormCollectionsList .EXLDynamicSelectBodyRadio > div').eq(0).text()+'');
}
*/
$('.EXLSearchFieldRibbonFormCollectionsList .EXLDynamicSelectBodyRadio > div').click(function(e){
$('.EXLSearchFieldRibbonFormSelectedCollection a').text($(this).text());
$(this).children('input').attr('checked','checked');
$(this).parents('.EXLSearchFieldRibbonFormCollectionsList').hide();
$('.EXLHeaderSearchLimitsFields').removeClass('EXLTemporarilyHideSelects');
});
$('.EXLSearchFieldRibbonFormSelectedCollection a').click(function(e){
e.preventDefault();
var scopeList = $('.EXLSearchFieldRibbonFormCollectionsList');
if (scopeList.is(':hidden')){
scopeList.show();
$('.EXLHeaderSearchLimitsFields').addClass('EXLTemporarilyHideSelects');
}else{
scopeList.hide();
$('.EXLHeaderSearchLimitsFields').removeClass('EXLTemporarilyHideSelects');
}
});
/*$('.EXLDynamicSelectBodyRadioFirst'
).eq(0
).siblings().removeClass('EXLDynamicSelectBodyRadioFirst').addClass('EXLDynamicSelectBodyRadioHideItem'
).andSelf(
).children('input').hide(
).end(
).end(
).end().parents('.EXLDynamicSelectBodyRadio'
).addClass('EXLDynamicSelectBodyRadioHide'
).end().unbind('click').click(scopeClickHandler).removeClass('EXLDynamicSelectBodyRadioTopBorder');*/
}
function scopeClickHandler(e){ //here we handle what to do with the scope dropdown when it's clicked.
e.preventDefault();
var parent = $(this).parents('.EXLDynamicSelectBodyRadio');
if ($(parent).hasClass('EXLDynamicSelectBodyRadioHide')){//if the dropdown list is hidden,
$(parent).removeClass('EXLDynamicSelectBodyRadioHide');// show the list
$(this).siblings().andSelf().unbind('click').click(function(e){ //add click handler to all the list elements
$(this).children('input').attr('checked','checked'); //when one is clicked, make sure his radio button is checked.
e.preventDefault();
$(this).parents('.EXLDynamicSelectBodyRadio').addClass('EXLDynamicSelectBodyRadioHide'); //re-hide the dropdown list
//hide all the other elements. make sure the newly selected element is visible.
//and add the generic click-handler to the visible element that will open the dropdown list next time it is clicked.
$(this).siblings().removeClass(
'EXLDynamicSelectBodyRadioFirst').addClass('EXLDynamicSelectBodyRadioHideItem').end(
).removeClass('EXLDynamicSelectBodyRadioHideItem').removeClass('EXLDynamicSelectBodyRadioTopBorder').addClass('EXLDynamicSelectBodyRadioFirst').unbind('click').click(scopeClickHandler);
});
$('#Selected_Databases-Div').addClass('EXLDynamicSelectBodyRadioTopBorder');
}//else do nothing.. we really shouldn't get here ever.
}
function setupSortByMenu(){
$('.EXLResultsSortBySelected a').click(function (event){
event.preventDefault();
var menu = $(this).parents('.EXLResultsSortBy').find('.EXLResultsSortByMenuShow');
if ($(menu).hasClass('EXLResultsSortByMenuHide')){
$(menu).removeClass('EXLResultsSortByMenuHide');
}else{
$(menu).addClass('EXLResultsSortByMenuHide');
}
});
}
/*function handleSortMenuClick(e){
e.preventDefault();
$(this).unbind('click');
$(this).parents('.EXLResultsSortByMenuHide').removeClass('EXLResultsSortByMenuHide');
$(this).siblings().andSelf().unbind('click').click(function(e){
//e.preventDefault();
$(this).removeClass('EXLSortByLinkHide');
$(this).siblings().not('.EXLSortByLinkHide').find('img').appendTo(this);
$(this).siblings().unbind('click').addClass('EXLSortByLinkHide').parents('.EXLResultsSortByMenuShow').addClass('EXLResultsSortByMenuHide');
//$(this).siblings().unbind('click').addClass('EXLSortByLinkHide').parents('.EXLResultsSortByMenuShow'));
$(this).unbind('click').click(handleSortMenuClick);
});
}*/
function setupLanguageMenu(){
$('#exlidSelectedLanguage').click(function(){
if($('#exlidLanguages').hasClass('EXLLanguageMenuHide')){
$('#exlidLanguages').removeClass('EXLLanguageMenuHide');
}else{
$('#exlidLanguages').addClass('EXLLanguageMenuHide');
}
});
}
function setupFacets(){
$('.EXLFacetsDisplayLess').hide(); //hide the less button in case its visible -- shouldn't be.
$('.EXLAdditionalFacet').hide(); //hide the additional facets -- these should be visible in case of accessibility (a11y) and noscript.
$('.EXLFacetsDisplayMore').show(); // show the more button which should initially be hidden because of a11y and noscript.
$('.EXLFacetsDisplayMore a').click(function(e){ //add onclick for more facets buttons.
$(this).parents('ol').children('.EXLAdditionalFacet').show();
$(this).parents('.EXLFacetsDisplayMore').hide();
$(this).parents('ol').children('.EXLFacetsDisplayLess').show();
e.preventDefault();
});
$('.EXLFacetsDisplayLess a').click(function(e){ //add onclick for less facets buttons.
$(this).parents('ol').children('.EXLAdditionalFacet').hide();
$(this).parents('.EXLFacetsDisplayLess').hide();
$(this).parents('ol').children('.EXLFacetsDisplayMore').show();
e.preventDefault();
});
}
function setupEshelfStar(){
$('.EXLMyShelfStar a').click(function (e){
e.preventDefault();
var link = $(this).get(0);
var img = $(this).children('img').get(0);
var url = $(this).attr('href')+'&exemode=async';
var src = $(img).attr('src');
if (src.indexOf('_off')>0){
$.ajax({url:url, dataType: "html",success: function(responseText){ //try to fire off the ajax call.
eshelfUpdate(link,true);
}});
}else{
$.ajax({url:url,dataType: "html", success:function(responseText){
eshelfUpdate(link,false);
}});
}
});
}
function setupSendToMenu(){
$('.EXLTabHeaderButtonSendToList').hide(); //initially hide the list in case it's visible.
$('.EXLTabHeaderButtonSendTo > a').live('click',function(e){ // live bind any preexisting or newly added Send To menu to open onclick.
e.preventDefault(); // ignore the href of the 'a' tag.
var ol = $(this).siblings('ol');
if (ol.is(':visible')){
ol.hide();
}else{
ol.show();
}
});
$('.EXLTabHeaderButtonSendTo > ol a').live('click', function(e){ //live bind any preexisting or newly added SendTo link to hide the parent again.
$(this).parents('ol').hide();
});
}
function log(msg){
try{
if(console && console.log){
console.log("v3 ui: " + msg);
}
}catch(logerr){
if (exlDebug){
alert(msg);
}
}
}
///////////////////////////
//AJAX utility functions
///////////////////////////
var globalTimeoutMultiplier = 2; //when we hit a slow network, modify the multiplier to slow down timeouts.
var globalTimeoutDefault = 30000; //thirty seconds in ms.
function suggestTimeout(timeout){
if(timeout){
return timeout * globalTimeoutMultiplier;
}else{
if(exlPrefetchConfiguration && exlPrefetchConfiguration.timeout){ //grabs the gateway timeout as default AJAX timeout.
globalTimeoutDefault = (exlPrefetchConfiguration.timeout*1000);//exlPrefetchConfiguration.timeout is specified in seconds
}else{
if (exlDebug){
log('no global timeout was found. using hard-coded default.');
}
}
return globalTimeoutDefault * globalTimeoutMultiplier;
}
}
function handleGlobalTimeoutIncrease(){
globalTimeoutMultiplier *= globalTimeoutMultiplier;
}
function notifyAndAskUserToRetryOrWaitLonger(){
//alert("ajax query timed out!");
}
function notifyAjaxTimeout(){
handleGlobalTimeoutIncrease();
notifyAndAskUserToRetryOrWaitLonger();
}
//when we encounter an error we should have a log if possible.
function generalAjaxError(msg){
logToServer(msg);
}
//fail but don't complain.
function silentAjaxError(msg){
generalAjaxError(msg);
}
//quick attempt to log data to server, short timeout because if it doesn't succeed, it's not the end of the world and why leave connections hanging open for a long time?
function logToServer(msg){
if(msg){
$.ajax({
url: '../log',
data: 'message='+encodeURI(msg.replace(/&/g,', ')),
global: false,
timeout: suggestTimeout(5000)
});
}else{
log('logToServer called with no msg!');
}
}
function gatherPageStatLinks(msg,recordId,indx,linkType){
$.ajax({
url: 'expand.do',
data: 'gatherStatLinks=true&linkType='+linkType+'&indx='+indx+'&recIds='+recordId+'&url='+encodeURIComponent(msg),
global: false,
timeout: suggestTimeout(5000)
});
}
function handleLogging(xmlDoc){
var logText = $(xmlDoc).find('logElement').text();
$('#debugLogFooter').html(logText);
log('new text:'+logText.length);
}
function escapeAjaxCall(url){
//used to solve encoding problems of I18N in IE6&7
return escapeFreeText(escapeFctV(url));
}
//This function is a free-text specific fix that handles I18N problems that might not be handled by the browser. (IE6+7) A more general solution is the escapeURL() function below.
function escapeFreeText(url){
try{
var sets = url.match(/(vl\(freeText[0-9]+\))=([^&]*)/g); //grab the freeText in case it isn't english.
var result = url.toString();
if (sets){
for (var aset = 0; aset < sets.length; aset++){ // iterate and handle one facet value at a time.
var set = sets[aset].match(/(vl\(freeText[0-9]+\))=([^&]*)/);
var key = set[1];
var val = set[2];
//first we do a decode, then the encode, otherwise if anything was already partially encoded it becomes doubly encoded. and we've ruined a perfectly good url.
var tempString = result.replace(RegExp(RegExp.escape(key+'='+val)),key+'='+encodeURIComponent(decodeURIComponent(val)));
result = tempString;
}
}
return result.toString();
}catch(escapingError){
log('possible error escaping FreeText: ' + escapingError.message);
return url;
}
}
//This function is a facet-specific fix that handles I18N problems that might not be handled by the browser. (IE6+7) A more general solution is the escapeURL() function below.
function escapeFctV(url){
try{
var sets = url.match(/fctV=[^&]*/g);//find all facet values.
var result = url;
if (sets){
for (var aset = 0; aset < sets.length; aset++){ // iterate and handle one facet value at a time.
var set = sets[aset].match(/(fctV)=([^&]*)/);
var key = set[1];
var val = set[2];
//first we do a decode, then the encode, otherwise if anything was already partially encoded it becomes doubly encoded. and we've ruined a perfectly good url.
result = result.replace(RegExp(RegExp.escape(key+'='+val)),key+'='+encodeURIComponent(decodeURIComponent(val)));
}
}
return result;
}catch(escapingError){
return url;
}
}
//This function handles I18N problems that might not be handled by the browser.
//There is a very slight risk that two similarly named parameters with similar inputs will cause collisions which is why this function is not being put into use during an sp upgrade.
function escapeURL(url){
try{
var sets = url.match(/[^?&=]+=[^]*/g);//find all url parameters
var result = url;
if(sets){
for (var aset = 0; aset < sets.length; aset++){ // iterate and handle one facet value at a time.
var set = sets[aset].match(/([^?&=]+)=([^&]*)/);
var key = set[1];
var val = set[2];
//first we do a decode, then the encode, otherwise if anything was already partially encoded it becomes doubly encoded. and we've ruined a perfectly good url.
result = result.replace(RegExp(RegExp.escape(key+'='+val)),key+'='+encodeURIComponent(decodeURIComponent(val)));
}
}
return result;
}catch(escapingError){
log('escapeURL failed: '+escapingError);
return url;
}
}
//set Ajax request header: this way, the server will always know that the request is an AJAX request.
//currently the only reason the server cares is when the session times out,
//to know whether to perform an xml redirect, or a classic http redirect.
//NOTE: this provides an extra level of certainty, as a rule jQuery should automatically set the X-Requested-With header.
function setAjaxRequestHeader(xmlhttpreq){
xmlhttpreq.setRequestHeader('EXLRequestType','ajax');
}
//check to see if the response to the ajax call resulted in an xml redirecting to another page
//currently only a session timeout will redirect via xml.
//returns true if the response was an XML redirect
function isAjaxXmlRedirect(xml){
if ($(xml).find('redirectXml').attr('location')){
return true;
}
return false;
}
//if the response to the ajax call resulted in an xml redirecting to another page
//this function will perform the redirect. returns false if no redirect was performed.
function handleAjaxXmlRedirect(xml){
if (isAjaxXmlRedirect(xml)){
log ('redirecting the page.');
window.location = $(xml).find('redirectXml').attr('location');
return true;
}
return false;
}
//simple ajax call, making use of all the defaults
function fetch(url,data,errorHandler){
$.ajax({
url:escapeAjaxCall(url),
data:data,
error: function(request,errorType,exceptionOcurred){
if (errorType=='timeout'){
notifyAjaxTimeout();
}else{
generalAjaxError();
}
},
success: function(data){
parseXmlAndUpdatePage(data);
}
});
}
//this ajax call is for prefetching which needs to behave differently.
//longer timeout, errors and updates should be silent.
function prefetch(url,data,errorHandler,successHandler){
$.ajax({
global: false,
beforeSend: function(request){
if(!isUpdateAllowed()){
return false;
}
setAjaxRequestHeader(request);
},
success: function(data, textStatus){
parseXmlAndUpdatePage(data);
if (successHandler){
successHandler();
}
},
error: function(request,errorType,exceptionOcurred){
if (errorType=='timeout'){
notifyAjaxTimeout();
}else{
silentAjaxError('prefetch failure url: '+url+' data:'+data);
}
if(errorHandler){
errorHandler();
}
},
timeout:suggestTimeout(),
data: data,
url: escapeAjaxCall(url)
});
}
function addToRequestQueue(url,data){
}
function updateElement(id, cdata, timestamp){
try{
var elem = $('#'+id).get(0);
//check to see if the data we have is fresh.
if((!elem.lastUpdate) || (!timestamp) || (elem.lastUpdate < timestamp)){
$(elem).html(cdata); //update the html.
elem.lastUpdate = timestamp; //make sure we stay up-to-date
}else{//better to log info for debugging, we will disable log when not debugging.
log(id + ' not updated, stale data ['+timestamp+']. last updated '+ elem.lastUpdate);
}
}catch(iderr){
log('updateElement failed: id='+id+' timestamp='+timestamp+' cdata='+((cdata!='')?'exists':'absent'));
}
}
/*
function storeElementForDisplay(id,key,cdata,timestamp,prefetched){
var elem = $('#'+id).get(0);
if (elem){
elem.tabs.update(cdata,timestamp,prefetched);
}else{
log('prefetch error id=['+id+'] key=['+key+']- returning elements without keys');
}
}
*/
// add an escape function so that we can easily escape complex recordIds so that they can be found in the page.
RegExp.escape = function(text) {
return text.replace(/[-[\]{}()*+?.,\/\\^$|#\s]/g, "\\$&");
}
//handle an xmlDoc, update each element based on its ID.
function parseXmlAndUpdatePage(xmlDoc){
try{
handleLogging(xmlDoc);
if (isAjaxXmlRedirect(xmlDoc)){
handleAjaxXmlRedirect(xmlDoc);
}else{
$(xmlDoc).find('element').each(function(){
var elm = $(this);
var id = $(elm).attr('id');
var key = $(elm).attr('key');
var timestamp = $(elm).attr('timestamp');
var cdata = $(elm).text();
var recId = $(elm).attr('recordId');
var tab = $(elm).attr('key');
var rid = RegExp.escape(recId);
var recordHandle = $('#'+rid).get(0);
var tabContainer = $('#'+id).get(0);
var alternateTabContainer = $(recordHandle).parents('.EXLResult').find('.EXLContainer-'+tab).get(0);
if (tabContainer){
if (tabContainer.tabUtils){
var recIdNode = $(tabContainer).parents('.EXLResult').find('.EXLRecordId').get(0);
if (recIdNode && recId == recIdNode.id){ //make sure we're dealing with the same recordId
tabContainer.tabUtils.update(cdata,timestamp);
}else{
if (alternateTabContainer){
alternateTabContainer.tabUtils.update(cdata,timestamp);
}else{
log('curiosity: tabContainer Id ('+id+') was valid but recordId ('+recId+') indicated a different container which could not be located (for tab: '+tab+')');
}
}
}else{
updateElement(id,cdata,timestamp);
}
}else{
log('potential id match problem.');
if (recordHandle){
if (alternateTabContainer){
alternateTabContainer.tabUtils.update(cdata,timestamp);
}else{
log('missing container!! (for tab: '+tab+')');
}
}else{
log('receiving data for irrelevant recordId? ('+recId+')');
}
}
});
}
}catch(errExc){
log('Error parsing requested data: '+errExc);
}
parseXmlAndHandleModificationsOnly(xmlDoc);
}
function parseXmlAndHandleModificationsOnly(xmlDoc){ //returns true if there were modifications
var result = false;
$(xmlDoc).find('modification').each(function(){
var elem = $(this);
var id = $(elem).attr('id');
var timestamp = $(elem).attr('timestamp');
var cdata = $(elem).text();
if(id && cdata){
updateElement(id,cdata,timestamp);
}
result = true;
});
return result;
}
function resetAjaxDefaults(){
$.ajaxSetup({
dataFilter: function(data,type){
//if we have problems where the error page is returned, this is where to check if we got messed up data!
return data;
},
dataType: "xml",
// global: 'true',
// ifModified: 'false',
timeout:suggestTimeout(), // go with default.
success: function(data, textStatus){
parseXmlAndUpdatePage(data);
},
type: 'GET',
async: true,
beforeSend: function(xhr){
setAjaxRequestHeader(xhr);
}
});
}
function prepareAjax(){
resetAjaxDefaults();
//prepare a loading icon..
$('#loading').hide().css('height','40px').css('width','120px').css('background','orange').css('color','white').css(
'padding-top','20px').css('padding-left','30px');
$("#loading").bind("ajaxSend", function(){
$(this).slideDown();
}).bind("ajaxStop", function(){
$(this).fadeOut('slow');
});
}
function TabState(){
return {status: exlTabState.UNFETCHED, timestamp: 0};
}
/*
function TabSetState(){
return {
'detailsTab': new TabState(),
'tagreviewsTab': new TabState(),
'onlineTab': new TabState(),
'moreTab': new TabState(),
'requestTab': new TabState(),
'locationsTab': new TabState(),
'recommendTab': new TabState()
};
}*/
function TabSet(idx,id,tabContent,recordId,tabType){
return {
index: idx,
id:id,
tabContent:tabContent,
recordId: recordId,
key: tabType,
state: new TabState(),
update: function (cdata,timestamp){ //put pre/fetched info in a particular tab slot.
//if(key){//make sure we're referring to a specific tab -- otherwise we should probably call the regular updateElement.
var tab = this.state;
//if (tab.timestamp<=timestamp){//making sure this cdata is newer than anything we already have.
tab.status = exlTabState.FETCHED;
tab.timestamp = timestamp;
this.showTab(cdata);
//}else{
// log("["+this.id +"]: timestamp ["+timestamp+"] of new data is stale: "+tab.timestamp);
//}
//}else{
// log("["+this.id +"]: can't update without key: "+cdata);
//}
},
showTab: function (cdata){ //show a tab that has info to show (ie. is in a FETCHED or PREFETCHED state.)
if(cdata){
$(this.tabContent).html(cdata);
applySubmitHandlingToTabForms(this.tabContent);
}
},
clearTab: function (){
$(this.tabContent).html(
'
');
},
displayTabError: function (){
$(this.tabContent).html(''+exlTabLoadErrorMessage+'
');
},
isTabReady: function (){
return (this.state.status==exlTabState.FETCHED);
},
showTabWhenReady: function(tabUrl){
if (this.isTabReady()){ //if it's already here, show it.
this.showTab();
$.ajax({
url: 'expand.do?prefetchedClick=true&tabs='+this.key+'&recIds='+this.recordId+'&indx='+tabUrl.substring(tabUrl.indexOf('indx=')+"indx=".length,tabUrl.indexOf('indx=')+"indx=".length+1),
global: false,
timeout: suggestTimeout(5000)
});
}else{
if (this.state.status == exlTabState.UNFETCHED){//if we haven't tried to fetch it, load it now!
this.loadTab(tabUrl);
}
}
},
loadTab: function(tabUrl,refreshRequestTab){
var thisTabSet = this;
if(!tabUrl){
tabUrl = "expand.do?gathStatTab=true&renderMode=prefetchXml&tabs="+this.key+"&recIds="+this.recordId+"&recIdxs="+this.index+"&elementId="+this.id;
if (refreshRequestTab){
tabUrl += "&resetRequestTabForm=reset";
}
}else{
tabUrl = tabUrl.replace(/display\.do/,"expand.do").replace(/renderMode=poppedOut/,'renderMode=prefetchXml');
if (!isFullDisplay()){
tabUrl = tabUrl.replace(/displayMode=full/,'displayMode=brief');
}
}
$.ajax({url:escapeAjaxCall(tabUrl),
error: function(){
//in the event of error, mark the tab as unfetched.
log('fetch tab failed, id='+thisTabSet.id);
thisTabSet.state.status = exlTabState.UNFETCHED;
thisTabSet.displayTabError();
},
success: function(data, textStatus){
//parse the xml for the data relevant to us.
var gotUpdate = false;
$(data).find('element[id='+thisTabSet.id+']').each(function(index){
thisTabSet.update($(this).text(),$(this).attr('timestamp'),false);
gotUpdate = true;
});
var gotModifications = parseXmlAndHandleModificationsOnly(data);
if (!gotModifications && !gotUpdate){
//check to see if we are being redirected for a sessionTimeout.
if (isAjaxXmlRedirect(data)){
handleAjaxXmlRedirect(data);
}
log('requested tab load failed! id='+thisTabSet.id);
thisTabSet.displayTabError();
}
handleLogging(data);
if (exlDebug){
$('body').append($('').text($(data).text().replace(/\n/g,'')).append('
'));
}
}
});
this.state.status = exlTabState.REQUESTED;
},
disableTab: function(){
var tab = $('#'+this.id).hide().parents('.EXLResult').find('.EXLResultTab a[href*='+this.key+']').parents('li').hide().addClass('EXLResultTabDisabled').get(0);
if($(tab).hasClass('EXLResultSelectedTab')){
$(tab).removeClass('EXLResultSelectedTab');
$(tab).parents('.EXLTabsRibbon').addClass('EXLTabsRibbonClosed');
}
},
refresh: function(){
refreshTab(this);
},
delayTab: function(){ /* for use in lightboxing a slow to respond tab */
$(this.tabContent).find('.EXLTabContent').prepend(''+exlDelayTabProcessingYourRequest+'
').parents('.EXLResultTabContainer').append('
');
}/*,
getTabs: function(filterState){ //retrieve all the tabs in the tabSet whose status is the same as filterState. if no filterState, return list of tabs.
var result = [];
var i = 0;
for(var tab in this.state){
if((!filterState) || this.state[tab].status == filterState){
result[i] = tab;
i++;
}
}
return result;
},
getUnfetchedTabs: function(){
return this.getTabs(exlTabState.UNFETCHED);
}
*/
};
}
function refreshTab(element,refreshRequestTab){
try{
var container = $(element).parents('.EXLResultTabContainer').get(0);
container.tabUtils.state.status = exlTabState.UNFETCHED;
container.tabUtils.loadTab(null,true);
}catch(err){
log('refresh failed! ('+err+')');
}
}
function TabFetchController(){
return {
requestTab: function (idx,id,key){
}
};
}
var exlTabState = {
UNFETCHED : 1,
REQUESTED : 2,
PREQUESTED : 2, //deprecated
PREFETCHED : 4, //deprecated
FETCHED : 4
}
//here we get the tabs ready so that prefetching will function properly.
function prepTabs(){
//handle the default setup for each tab.
$('.EXLContainer-viewOnlineTab').each(function(i){
var recordId = $(this).parents('.EXLResult').find('.EXLResultRecordId').attr('id');
var tabType = 'viewOnlineTab';
this.tabUtils = new TabSet(i,this.id,this,recordId,tabType); //this sets all the default info for each tab, so that prefetch will be able to populate it properly.
if (exlPrefetchConfiguration.loadedTab && tabType == exlPrefetchConfiguration.loadedTab){//special case for pre-opened tab in full display
this.tabUtils.state.status = exlTabState.FETCHED;
}
});
$('.EXLContainer-requestTab').each(function(i){
var recordId = $(this).parents('.EXLResult').find('.EXLResultRecordId').attr('id');
var tabType = 'requestTab';
this.tabUtils = new TabSet(i,this.id,this,recordId,tabType); //this sets all the default info for each tab, so that prefetch will be able to populate it properly.
if (exlPrefetchConfiguration.loadedTab && tabType == exlPrefetchConfiguration.loadedTab){//special case for pre-opened tab in full display
this.tabUtils.state.status = exlTabState.FETCHED;
}
});
$('.EXLContainer-locationsTab').each(function(i){
var recordId = $(this).parents('.EXLResult').find('.EXLResultRecordId').attr('id');
var tabType = 'locationsTab';
this.tabUtils = new TabSet(i,this.id,this,recordId,tabType); //this sets all the default info for each tab, so that prefetch will be able to populate it properly.
if (exlPrefetchConfiguration.loadedTab && tabType == exlPrefetchConfiguration.loadedTab){//special case for pre-opened tab in full display
this.tabUtils.state.status = exlTabState.FETCHED;
}
});
$('.EXLContainer-detailsTab').each(function(i){
var recordId = $(this).parents('.EXLResult').find('.EXLResultRecordId').attr('id');
var tabType = 'detailsTab';
this.tabUtils = new TabSet(i,this.id,this,recordId,tabType); //this sets all the default info for each tab, so that prefetch will be able to populate it properly.
if (exlPrefetchConfiguration.loadedTab && tabType == exlPrefetchConfiguration.loadedTab){//special case for pre-opened tab in full display
this.tabUtils.state.status = exlTabState.FETCHED;
}
});
$('.EXLContainer-tagreviewsTab').each(function(i){
var recordId = $(this).parents('.EXLResult').find('.EXLResultRecordId').attr('id');
var tabType = 'tagreviewsTab';
this.tabUtils = new TabSet(i,this.id,this,recordId,tabType); //this sets all the default info for each tab, so that prefetch will be able to populate it properly.
if (exlPrefetchConfiguration.loadedTab && tabType == exlPrefetchConfiguration.loadedTab){//special case for pre-opened tab in full display
this.tabUtils.state.status = exlTabState.FETCHED;
}
});
$('.EXLContainer-recommendTab').each(function(i){
var recordId = $(this).parents('.EXLResult').find('.EXLResultRecordId').attr('id');
var tabType = 'recommendTab';
this.tabUtils = new TabSet(i,this.id,this,recordId,tabType); //this sets all the default info for each tab, so that prefetch will be able to populate it properly.
if (exlPrefetchConfiguration.loadedTab && tabType == exlPrefetchConfiguration.loadedTab){//special case for pre-opened tab in full display
this.tabUtils.state.status = exlTabState.FETCHED;
}
});
$('.EXLContainer-moreTab').each(function(i){
var recordId = $(this).parents('.EXLResult').find('.EXLResultRecordId').attr('id');
var tabType = 'moreTab';
this.tabUtils = new TabSet(i,this.id,this,recordId,tabType); //this sets all the default info for each tab, so that prefetch will be able to populate it properly.
if (exlPrefetchConfiguration.loadedTab && tabType == exlPrefetchConfiguration.loadedTab){//special case for pre-opened tab in full display
this.tabUtils.state.status = exlTabState.FETCHED;
}
});
//handle the close-tab button.
$('.EXLTabHeaderButtonCloseTabs').live('click',function(e){ //live click binding for when the the tabHeader is reloaded from the server.
e.preventDefault();
var result = $(this).parents('.EXLResult');
closeAllTabsForResult(result);
$(result).find('.EXLTabsRibbon').addClass('EXLTabsRibbonClosed').find('.EXLResultSelectedTab').removeClass('EXLResultSelectedTab');
});
//handle the default behavior for each tab.
$('.EXLViewOnlineTab a').click(function(e){
selectAndLoadTab(e,this,'viewOnlineTab');
});
$('.EXLDetailsTab a').click(function(e){
selectAndLoadTab(e,this,'detailsTab');
});
$('.EXLRequestTab a').click(function(e){
selectAndLoadTab(e,this,'requestTab');
});
$('.EXLLocationsTab a').click(function(e){
selectAndLoadTab(e,this,'locationsTab');
});
$('.EXLRecommendTab a').click(function(e){
selectAndLoadTab(e,this,'recommendTab');
});
$('.EXLMoreTab a').click(function(e){
selectAndLoadTab(e,this,'moreTab');
});
$('.EXLReviewsTab a').click(function(e){
selectAndLoadTab(e,this,'tagreviewsTab');
});
//todo: make sure the full tab that is loaded on page-load will be marked as FETCHED so it isn't overwritten my prefetching.
}
function closeAllTabsForResult(result){
$(result).find('.EXLResultTabContainer').hide();
}
function ajaxSubmitForm(form){
$(form).ajaxSubmit({success:function(data,status){
parseXmlAndUpdatePage(data,true);
}});
}
function ajaxSubmitParentForm(element){
ajaxSubmitForm($(element).parents('form').get(0));
}
function applySubmitHandlingToTabForms(tabContent){
$(tabContent).find('form').unbind('submit').submit(function(e){
e.preventDefault();
ajaxSubmitForm(this);
return false;
});
}
function
selectAndLoadTab(event, element, tabType)
{
var tabsContainer = $(element).parents('.EXLSummary').find('.EXLContainer-'+tabType).get(0);
if(tabsContainer && $(element).attr('target')!='_blank'){
event.preventDefault();
if(tabsContainer.tabUtils.state.status
function switchAndLoadTab(event, element, tabType, url, originalTabType){
var tabsContainer = $(element).parents('.EXLResult').find('.EXLContainer-'+tabType).get(0);
tabsContainer.tabUtils.clearTab(tabType);
$(tabsContainer).siblings('.EXLContainer-'+originalTabType).hide().end().show();
$(element).parents('.EXLResult').find('.EXLResultSelectedTab').removeClass('EXLResultSelectedTab');
var tabTypeClass = '.EXL' + tabType.charAt(0).toUpperCase() + tabType.substring(1);// build the correct tab class name
$(element).parents('.EXLResult').find(tabTypeClass).addClass('EXLResultSelectedTab');
if(url){
if (!isFullDisplay()){
if (url.indexOf('displayMode=') < 0){
url += "&displayMode=brief";
}else{
url = url.replace(/displayMode=full/g,'displayMode=brief');
}
}else{
if (url.indexOf('displayMode=') < 0){
url += "&displayMode=full";
}else{
url = url.replace(/displayMode=brief/g,'displayMode=full');
}
}
fetch(url,function(){//try to reload the tab, in event of failure, try to switch back to previous tab.
alert('An error occured on the server. Please try again later.');
if(originalTabType){
switchAndLoadTab(event,element,originalTabType);
}
});
}
}
function prefetchTabContent(){
//which tabs to prefetch
var tabs2Prefetch = ['detailsTab'];//,'tagreviewsTab','locationsTab','moreTab','requestTab'];
//build the prefetch url
if(exlPrefetchConfiguration && exlPrefetchConfiguration.enabled == 'true'){
if (exlPrefetchConfiguration.loadedTab){//special ce-opened tab in full display
for (var atab in tabs2Prefetch){
if (exlPrefetchConfiguration.loadedTab == tabs2Prefetch[atab]){
var indx = tabs2Prefetch.indexOf(exlPrefetchConfiguration.loadedTab);
if (indx >=0){
tabs2Prefetch.slice(indx,indx);//remove the currently loaded tab from the prefetch regimen.
}
}
}
}
var data = '';
var bulkCounter = 0;
var ids2Prefetch = [];
var prefetchUrl = '';
$('.EXLResultRecordId').each(function(i){
if (i>=exlPrefetchConfiguration.current){
if (bulkCounter<exlPrefetchConfiguration.bulkSize){
if (prefetchUrl!=''){ //don't add the first ids because they will be added automatically via the base url. (see below)
data += '&recIds='+ this.id + '&recIdxs=' + i + '&elementId=' + i;
}
ids2Prefetch[ids2Prefetch.length] = this.id;
bulkCounter++;
//mark each of the tab containers as requested.
$(this).parents('.EXLResult').find('.EXLResultTabContainer').each(function(){
for (var atab in tabs2Prefetch){
try{
if (tabs2Prefetch[atab] == this.tabUtils.key){
//mark the tab requested -- otherwise if the user clicks before the tab finishes loading, we will hit the server a second (unnecesary) time.
this.tabUtils.state.status = exlTabState.REQUESTED;
//you need to manufacture the classname to grab the correct tab link.
var tabTypeClass = '.EXL' + this.tabUtils.key.charAt(0).toUpperCase() + this.tabUtils.key.substring(1) + ' a';// build the correct tab class name
if(prefetchUrl == ''){ //only need to process here if we are on the first tab to prefetch of the first record to prefetch.
var tempUrl = $(this).parents('.EXLResult').find(tabTypeClass).attr('href') + '&prefetch=true';
//we're only interested in the query part of the URL
var afterQuestionMark = tempUrl.indexOf('?')+1;
prefetchUrl = tempUrl.substring(afterQuestionMark);
prefetchUrl = prefetchUrl.replace('gathStatTab=true&','');
//drop the doc param which will otherwise force the query to work for only the first record.
prefetchUrl = prefetchUrl.replace(RegExp('doc='+this.tabUtils.recordId+'\&'),'');
// loop through and add all prefetchTabs except the current tab which was already added in the base url,
// so we don't accidentally cycle through a prefetched tab twice.
for (var atab2 in tabs2Prefetch){
if(tabs2Prefetch[atab2]!=this.tabUtils.key){
data += '&tabs='+tabs2Prefetch[atab2];
}
}
}
//this.tabUtils.loadTab(prefetchUrl);
}
}catch(err){
log('prefetch status update error: '+err);
}
}
});
}
}
});
exlPrefetchConfiguration.current+=bulkCounter;
//combine the prefetchUrl and data into one query.
data = (prefetchUrl + '&' + data);
//modify the link to work with prefetch.
data = data.replace(/renderMode=poppedOut/,'renderMode=prefetchXml');
if (!isFullDisplay()){ //handle the special case where we're prefetching from the full display.
data = data.replace(/displayMode=full/,'displayMode=brief');
}
if (bulkCounter>0){
log('prefetching '+bulkCounter+' record(s).');
//prefetch those tabs.
prefetch('expand.do',escapeURL(data),function(){
log('prefetch error, undoing REQUESTED status for these ids:'+ids2Prefetch+' with these tabs:'+tabs2Prefetch);
for (var anId in ids2Prefetch){
$('#'+anId).parents('.EXLResult').find('.EXLResultTabContainer').each(function(){
for (var atab in tabs2Prefetch){
if (atab == this.tabUtils.key){
this.tabUtils.state.status = exlTabState.UNFETCHED;
}
}
});
}
},function(){
//mark tabs successfully prefetched!
for (var anId in ids2Prefetch){
$('#'+ids2Prefetch[anId]).parents('.EXLResult').find('.EXLResultTabContainer').each(function(){
for (var atab in tabs2Prefetch){
try{
if (tabs2Prefetch[atab] == this.tabUtils.key){
this.tabUtils.state.status = exlTabState.FETCHED;
}
}catch(err){
log('prefetch success ('+this.id+':'+tabs2Prefetch[atab]+') status update failed: '+err);
}
}
});
}
try{
if (exlPrefetchConfiguration.repeat == 'true'){ //only continue to prefetch if repeat is turned on.
prefetchTabContent();
}
}catch(prefetchErr){
log('continued prefetch failed.');
}
});
}else{
log('no records to prefetch.')
}
}
}
function disableTab(element, tabType){
$('#elementId').addClass('EXLResultsTabDisabled');
//TODO: get this function right, so it will be useful to tab developers.
}
function eshelfCreate(element, recordId,remote,scopes,index){
updateBasket(recordId,true,remote,scopes,index);//calling ajax funcion from common.js to add to eshelf
eshelfUpdate(element,true);
return false;
}
function eshelfRemove(element, recordId,remote,scopes,index){
updateBasket(recordId,false,remote,scopes,index);//calling ajax funcion from common.js to remove from eshelf
eshelfUpdate(element,false);
return false;
}
function eshelfUpdate(element,inBasket){
var objResult = $(element).parents('.EXLResult');
var objMyShelfAdd=objResult.find('.EXLButtonSendToMyShelfAdd');
var objMyShelfRemove=objResult.find('.EXLButtonSendToMyShelfRemove');
var link = $(objResult).find('.EXLMyShelfStar a').get(0);
var img = $(link).children('img').get(0);
var src = $(img).attr('src');
try{
if(inBasket){
objMyShelfRemove.show();
objMyShelfAdd.hide();
$(img).attr('src',src.replace(/_off/,'_on'));
$(link).attr('href',$(link).attr('href').replace('fn=create','fn=remove'));
}else{
objMyShelfRemove.hide();
objMyShelfAdd.show();
$(img).attr('src',src.replace(/_on/,'_off'));
$(link).attr('href',$(link).attr('href').replace('fn=remove','fn=create'));
}
}catch(upderr){
log('failed to update basket interface: ' +upderr);
}
}
function ineshelfInit(recordId, basketIn){
if(recordId=='') return;
var element= $('#'+recordId);
var objSummary = $(element).parents('.EXLResult');
var objMyShelfAdd=objSummary.find('.EXLButtonSendToMyShelfAdd');
var objMyShelfRemove=objSummary.find('.EXLButtonSendToMyShelfRemove');
if(basketIn=='on'){
objMyShelfAdd.hide();
objMyShelfRemove.show();
}else{
objMyShelfAdd.show();
objMyShelfRemove.hide();
}
}
/**
* Push document bookemark to a remote systm e.g. connotea
*/
function pushto(value,index,fromEshelf, recordId){
var labelID = 'label_eshelf'+index;
if(value!='create' && value!='remove'){
openWindow('PushToAction.do?indx='+index+'&doc='+recordId+'&recId='+recordId+'&docs='+recordId+'&pushToType='+value+'&fromEshelf='+fromEshelf,value,'width = 600, height = 500, resizable=1,scrollbars=1');
}
}
/**
*report to bibTip that record was clicked in case it was not reported before for this record.
*/
function reportBibTip(recId){
var url = 'expand.do?renderMode=prefetchXml&tabs=recommendTab&recIds='+recId+'&reportBibTip=true&prefetch=true';
if (isFullDisplay()){
url = url + '&displayMode=full';
}
prefetch(url);
}
function isFullDisplay(){
return $('.EXLFullView').size() > 0;
}
function checkRecommendations() {
var url = 'expand.do?renderMode=prefetchXml&tabs=recommendTab&prefetch=false¶m=preLoad&checkRecommendation=true';
if (isFullDisplay()){
url = url + '&displayMode=full';
}
$('.EXLResultRecordId').each(function(i){
url += '&recIds='+ this.id + '&recIdxs=' + i + '&elementId=' + i;
});
prefetch(url);
}
function checkRecommendation(recId, tab, fromEshelf) {
if (tab != 'recommendTab') {
var url = 'expand.do?renderMode=prefetchXml&prefetch=false&tabs=recommendTab&checkRecommendation=true&recIds='+recId +'&recIdxs=0';
if (isFullDisplay()){
url = url + '&displayMode=full';
}
if (fromEshelf == 'true') {
url = url + '&fromEshelf=true';
}
prefetch(url);
}
else {
$('#exlidResult0-RecommendTab').show();
}
}
function hideRecommendTabs() {
$('.EXLRecommendTab').addClass('EXLRecommendTabDisable');
}
//fix for 8889
function hideRecommendTab(index, title)
{
var recommendTab = $('#exlidResult'+index+'-RecommendTab');
if (recommendTab) {
$(recommendTab).addClass('EXLRecommendTabDisable')
$(recommendTab).children('a').get(0).title = title;
}
}
function showRecommendTab(index,title)
{
var recommendTab = $('#exlidResult'+index+'-RecommendTab').removeClass('EXLRecommendTabDisable');
var tabsContainer = $(recommendTab).parents('.EXLResult').find('.EXLContainer-recommendTab').get(0);
tabsContainer.tabUtils.state.status = exlTabState.UNFETCHED;
if (recommendTab) {
$(recommendTab).children('a').get(0).title = title;
}
}
function
callExtensionsService(docs){
var url = "extensions.do?service_name=pc_citation";
url=url+docs;
if (isFullDisplay()){
url = url + '&displayMode=full';
}
fetch(url);
}