/***************************************************************************** * Add a browser-independent inner_height method to the window object *****************************************************************************/ window.inner_height = function() { if ( window.innerHeight ) { return window.innerHeight; } if ( document.documentElement && document.documentElement.clientHeight ) { return document.documentElement.clientHeight; } if ( document.body && document.body.clientHeight ) { return document.body.clientHeight; } return null; }; /***************************************************************************** * general_ready() - $().ready(...) function which will be executed for every * display page. *****************************************************************************/ function general_ready() { //------------------------------------------------------------------------ // verify that the browser can process ajax requests //------------------------------------------------------------------------ if ( $('meta[@name=check-ajax]').length > 0 ) { ajax_enable(); } //------------------------------------------------------------------------ // Deactivate form submission buttons once a form is submitted, and show // loading feedback graphic. //------------------------------------------------------------------------ $('#msp-searchform input[@type="submit"]').click( function(e) { var button = $(this); var label = $(button).attr('value'); if ( label.search('Search|Display Indexes') > -1 ) { window.setTimeout( function() { $(button).attr('disabled', true); $(button).addClass('loading'); $(button).css( 'background-position', '2px center' ); }, 100 ); // The 100ms delay allows the form to be submitted in IE. return true; } return true; } ); // In Firefox, if the user Backs up to the search page after the button // was disabled, it'll still be disabled. Firefox provides an event to // detect when a page was reloaded from the memory cache; we can use that // event to re-enable the buttons. // IE 6 doesn't seem to have this problem; when the user backs up the // buttons are enabled again. if ( $.browser.mozilla ) { window.addEventListener('pageshow', function(e) { // e.persisted is false when the page is initially loaded, // and true when it is loaded from cache. if ( e.persisted == false ) { return; } $('#msp-searchform input[@type="submit"]').each( function() { var label = $(this).attr('value'); if ( label.search('Search|Display Indexes') > -1 ) { $(this).removeAttr('disabled'); $(this).removeClass('loading'); } } ); }, false ); } //------------------------------------------------------------------------ // Stop enter key in some forms and textboxes from submitting the form //------------------------------------------------------------------------ $('.no_submit_with_enter_key').keypress( function(e) { if ( e.keyCode == 13 ) { return false; } return true; } ); //------------------------------------------------------------------------ // Simulate :first-child in IE 6 for a few styles //------------------------------------------------------------------------ if ( $.browser.msie ) { var version=parseFloat(navigator.appVersion.split("MSIE")[1]); if (version < 7) { $('#annotation-links a:first-child').css({ 'border-left': 'none', 'padding-left': 0 }); $('#header-buttons-upper a:first-child').css({ 'border-left': 'none' }); $('#header-buttons-lower a:first-child').css({ 'border-left': 'none' }); $('#header-dbchange a:first-child').css({ 'border-left': 'none' }); } } //------------------------------------------------------------------------ // Set up Titles Display Behaviors //------------------------------------------------------------------------ if ( $('#titles-records').length > 0 ) { titles_display_setup(); } //------------------------------------------------------------------------ // Attach click events to bib record checkboxes //------------------------------------------------------------------------ if ( $('.bibrecord-checkbox').length > 0 ) { $('.bibrecord-checkbox').click( function(e) { return titles_checkbox_handler(e); } ); } //------------------------------------------------------------------------ // Attach click event to citman clear selected results button //------------------------------------------------------------------------ $('#citman-clear-selected').click( function(e) { return citman_clear_selected(e); } ); //------------------------------------------------------------------------ // In Subject Seach Mode, MSP button submits form on Tools pages // but only if there is a toolSubject input. //------------------------------------------------------------------------ $('#msp-link-tools').click( function() { if ( $('input[@name="toolSubject"]').length > 0 ) { var input = document.createElement('INPUT'); input.setAttribute('type', 'hidden'); input.setAttribute('name', 'Main Search Page'); input.setAttribute('value', 1); $('#main-form').append(input); $('#main-form').submit(); return false; } else { return true; } } ); //------------------------------------------------------------------------ // In Ovid Classic Mode, Tools button submits form on Tools pages //------------------------------------------------------------------------ $('#tools-return').click( function() { var input = document.createElement('INPUT'); input.setAttribute('type', 'hidden'); input.setAttribute('name', 'Tools'); input.setAttribute('value', 1); $('#main-form').append(input); $('#main-form').submit(); return false; } ); //------------------------------------------------------------------------ // Add select all to search history //------------------------------------------------------------------------ $('#searchhistory-selectall').click( function() { if ($(this).attr('checked')) { $('.searchhistory-row input[@type=checkbox]').each( function() { $(this).attr('checked', true); }); } else { $('.searchhistory-row input[@type=checkbox]').each( function() { $(this).attr('checked', false); }); } } ); //------------------------------------------------------------------------ // Click handler for individual sets in the search history to // deselect select all if one is deselected //------------------------------------------------------------------------ $('.searchhistory-row input[@type=checkbox]').click( function() { if (! $(this).attr('checked') ) { var select_all =$('#searchhistory-selectall').get(0); $(select_all).attr('checked', false); } } ); //------------------------------------------------------------------------ // Initialize Search Aids if visible //------------------------------------------------------------------------ if ( $('#searchaid').length > 0 ) { display_search_aid_expand(); display_search_aid_terms(search_terms); search_aid_narrow(); } //------------------------------------------------------------------------ // Initialize annotation links //------------------------------------------------------------------------ init_annotation_links(); //------------------------------------------------------------------------ // Field guide embedded element height //------------------------------------------------------------------------ if ( $('#fieldguide-embedded').length > 0 ) { var fieldguide_resize = function() { var window_height = window.inner_height(); var fieldguide_top = $('#fieldguide-embedded').get(0).offsetTop; var footer_height = $('#footer-copyright').get(0).clientHeight; if ( window_height ) { var new_height = window_height - fieldguide_top - footer_height - 80; // margins, padding, etc $('#fieldguide-embedded').css( 'height', new_height+'px' ); } }; fieldguide_resize(); $(window).resize( function() { fieldguide_resize() } ); } //------------------------------------------------------------------------ // ETocs Management Site //------------------------------------------------------------------------ // This is very similar to the Field guide above; both use an IFRAME // to embed an external site within a standard page. // We should probably write a function factory that will create a resize // function for a specific iframe id, so we can use it anyplace we need // a full-height iframe. if ( $('#etocs-management-site').length > 0 ) { var iframe_resize = function() { var window_height = window.inner_height(); var iframe_top = $('#etocs-management-site').get(0).offsetTop; var footer_height = $('#footer-copyright').get(0).clientHeight; if ( window_height ) { var new_height = window_height - iframe_top - footer_height - 80; // margins, padding, etc $('#etocs-management-site').css( 'height', new_height+'px' ); } }; iframe_resize(); $(window).resize( function() { iframe_resize() } ); } //------------------------------------------------------------------------ // External Links //------------------------------------------------------------------------ // This is very similar to the Field guide above; both use an IFRAME // to embed an external site within a standard page. // We should probably write a function factory that will create a resize // function for a specific iframe id, so we can use it anyplace we need // a full-height iframe. if ( $('#embedded-frame').length > 0 ) { var iframe_resize = function() { var window_height = window.inner_height(); var iframe_top = $('#embedded-frame').get(0).offsetTop; var footer_height = $('#footer-copyright').get(0).clientHeight; if ( window_height ) { var new_height = window_height - iframe_top - footer_height - 80; // margins, padding, etc $('#embedded-frame').css( 'height', new_height+'px' ); } }; iframe_resize(); $(window).resize( function() { iframe_resize() } ); } //------------------------------------------------------------------------ // Setup timer to prevent timeouts as long as the browser window is open. //------------------------------------------------------------------------ if ( $('meta[@name=heartbeat-interval]').length > 0 ) { var meta = $('meta[@name=heartbeat-interval]').get(0); var interval = $(meta).attr('content'); if ( interval > 1000 ) { window.setTimeout( send_heartbeat, interval ); } } //------------------------------------------------------------------------ // Display and retrieve similar articles //------------------------------------------------------------------------ if ( $('#top-similar').length > 0 ) { $('#top-similar').css( 'display', 'block' ); top_similar_retrieve(); } //------------------------------------------------------------------------ // Open help links in a popup //------------------------------------------------------------------------ if ( $('.help-link').length > 0 ) { $('.help-link').click( function(e) { return open_help_window(e); } ); } //------------------------------------------------------------------------ // Journal Category Browsing //------------------------------------------------------------------------ if ( $('#browsecat > ul').length > 0 ) { $('#browsecat > ul').Treeview({ speed: "fast" }); if ( $('#browsecat div.descriptions').length > 0 ) { $('#browsecat li span').mouseover( function() { var recnum = $(this).attr('id'); $('#browsecat div.descriptions').css( 'display', 'none' ); $('#browsecat div#desc-' + recnum).css( 'display', 'block' ); } ); } } //------------------------------------------------------------------------ // MARC Record Download //------------------------------------------------------------------------ if ( $('#MARC-table').length > 0 ) { if ( $.browser.msie ) { $('#MARC-table table tbody tr').mouseover( function() { $(this).css( { 'background-color': 'rgb(200,229,170)' } ); } ); $('#MARC-table table tbody tr').mouseout( function() { $(this).css( { 'background-color': 'transparent' } ); } ); } // Add checkbox selection event tracking, because we don't update // the MARC downloads page when the user clicks on the Download // button, and that causes the SELECT input to get out-of-sync. var R_min = null; var R_max = null; $('#MARC-table input:checkbox[@name="R"]').each( function(i) { var index = parseInt( $(this).attr('value') ); if ( R_min == null || R_min > index ) { R_min = index; } if ( R_max == null || R_max < index ) { R_max = index; } } ); var dl_button = $('input.standard-button[@name="MARC Download"]'); var start = R_min; var count = (R_max - R_min + 1); $('#MARC-table input[@type=checkbox]').click( function(e) { checkbox_state_change( e.target, start, count, dl_button ); return true; } ); } //------------------------------------------------------------------------ // Editable Tips //------------------------------------------------------------------------ if ( $('#msp_ad').length > 0 && $('#msp_ad #edit').length > 0 ) { $('#msp_ad p').click( function(e) { var text = $('#msp_ad p').html(); $('#msp_ad #edit textarea').get(0).value = text; $('#msp_ad p').hide(); $('#msp_ad #edit').show(); } ); $('#msp_ad #edit button').click( function(e) { var text = $('#msp_ad #edit textarea').get(0).value; $('#msp_ad p').html( text ); $('#msp_ad #edit').hide(); $('#msp_ad p').show(); } ); } //------------------------------------------------------------------------ // Define more behaviors here //------------------------------------------------------------------------ } /***************************************************************************** * openWeblink(url, target) - open a new window for external sites *****************************************************************************/ function openWeblink(url, target) { var width; var height; if ( window.screen ) { width = window.screen.availWidth; height = window.screen.availHeight; } else { width = 1024; height = 768; } // Reduce by 60% width = width * 0.60; height = height * 0.60; var newWindow; newWindow = window.open(url, target, 'width='+width+'height='+height+',status,resizable,titlebar,toolbar,scrollbars'); newWindow.focus(); } /***************************************************************************** * login_ready() - ready function for login page *****************************************************************************/ function login_ready() { // Give the ID box the focus $('INPUT[@NAME="ID"]').focus(); // Center the login box var window_width = document.documentElement.clientWidth; var m_left = ( window_width - 550 ) / 2; if ( m_left > 0 ) { $('div.login-container').css( 'margin-left', m_left + 'px' ); $('div.login-container').css( 'width', '550px' ); } } /***************************************************************************** * index_browse_ready() - ready function for Index Browse display *****************************************************************************/ function index_browse_ready() { // The default rendering of the grid is left to right, top to bottom. // We want to convert it to top to bottom, left to right, so it's more // natural to scan through. index_reorder('one-time'); $(window).resize( function() { index_reorder('resize') } ); // We can adjust if the browser window size changes, but unfortunately // there is no resize event when the text size changes. /* Commented out because it does not noticably improve navigation latency // Add AJAX behavior to Back/Forward buttons $('.index-navbuttons/input:submit').click( function(e) { return index_navigate(e); } ); */ // IE6 doesn't support :hover styles on DIV elements. The code below // could simulate the :hover style in main.css for .index-grid-entry // but it doesn't work very well; it's not the same as a true :hover. // Also, the click event on the label is simulated. // TODO: check $.browser.version for IE7, which shouldn't need // any of this. The version property is available in jquery 1.1.3. // WARNING: IE7's implementation of :hover is buggy and slow if ( $.browser.msie ) { $('#index-grid .index-grid-entry').mouseover( function() { $(this).css( { 'overflow': 'auto', 'height': '3.5em', 'min-height': '3.5em', 'background-color': 'rgb(200,229,170)' } ); } ); $('#index-grid .index-grid-entry').mouseout( function() { $(this).css( { 'overflow': 'hidden', 'height': '3.5em', 'min-height': '3.5em', 'background-color': 'transparent' } ); } ); // Fix for issue #51: // unable to check the check boxes next to terms in IE 6.0 // TODO: change code to use $.browser.version from jquery 1.1.3+ var version=parseFloat(navigator.appVersion.split("MSIE")[1]); if (version < 7) { var cbxIsClicked = false; $('input[@type=checkbox]').click( function() { cbxIsClicked = true; } ); $('#index-grid .index-grid-entry').click( function() { if (cbxIsClicked) { cbxIsClicked = false; return true; } var cbx = $('input[@type=checkbox]', this).get(0); if ( $(cbx).attr('checked') ) { $(cbx).removeAttr('checked'); } else { $(cbx).attr('checked', true); } } ); } // version } } /***************************************************************************** * index_reorder(reason) - Re-order the items in the Index Browse grid so they * go top to bottom, left to right instead of the normal * float ordering of left to right, top to bottom. * Maybe someday there will be a new float value for this. * * To improve performance in IE, which fires resize events constantly while * the window is being resized, this method will start a timer and only call * the real reordering method when the timer expires. Each resize event will * restart the timer. * * The reason argument lets the function know if it is being called due to * a resize event or not. We don't want to use the timer if we're not in a * resize event, because we'll get stuck in a loop setting the timer every * 500ms. (index_reorder is called from within index_reorder_grid()). * * Also, the reorder_prev_width value is used to work around an IE 6/7 bug. * IE will keep firing resize events because it thinks the body element is * changing size, even when it doesn't, because we're running through the * index_reorder_grid() code. This puts IE into a neverending loop as well. * *****************************************************************************/ var reorder_timer = null; var reorder_prev_width = 0; function index_reorder(reason) { if ( reorder_timer != null ) { window.clearTimeout( reorder_timer ); reorder_timer = null; } if ( reason == 'one-time' ) { index_reorder_grid(); } else if ( reason == 'resize' ) { if ( reorder_prev_width != document.documentElement.clientWidth ) { reorder_timer = window.setTimeout( index_reorder_grid, 500 ); } } } function index_reorder_grid() { if ( reorder_timer != null ) { window.clearTimeout( reorder_timer ); reorder_timer = null; } reorder_prev_width = document.documentElement.clientWidth; var items = $('.index-grid-entry'); // Apply the default style to the grid so we have a fixed starting point. items.css( { 'float': 'left', 'margin-top': 0, 'margin-left': 0 } ); $('#index-body').css( { 'width': 'auto' } ); // Get some layout metrics about the grid var grid_width = $('#index-grid').get(0).clientWidth; var grid_height = $('#index-grid').get(0).clientHeight; var body_width = $('#index-body').get(0).clientWidth; var body_height = $('#index-body').get(0).clientHeight; var item_width = items.get(0).offsetWidth; var item_height = items.get(0).offsetHeight; var num_items = items.length; // Calculate the desired number of columns and rows var num_columns = Math.floor( grid_width / item_width ); var items_per_column = Math.ceil( num_items / num_columns ); // Calculate new layout metrics var grid_borders = body_width - grid_width; var new_body_width = num_columns * item_width + grid_borders; var new_grid_height = items_per_column * item_height; // Columns after the first one will be pushed upward by vertical_return, // and pushed to the right by margin_left var vertical_return = -1 * new_grid_height; for ( col_num=0; col_num < num_columns; col_num++ ) { var top_item_num = col_num * items_per_column; if ( col_num > 0 ) { // Push column up to the top of the grid $(items[top_item_num]).css( 'margin-top', vertical_return + 'px' ); } var margin_left = col_num * item_width; // Each item needs to be pushed to the right. Turn off floating // at the same time. for ( item_num=0; item_num < items_per_column; item_num++) { var index = top_item_num + item_num; if ( index < items.length ) { $(items[top_item_num + item_num]).css( { 'margin-left': margin_left + 'px', 'float': 'none' } ); } } } // For IE, force the body and grid tightly against the items. $('#index-body').css( { 'width': new_body_width + 'px' } ); $('#index-grid').css( { 'height': new_grid_height + 'px' } ); } /***************************************************************************** * index_navigate() - navigate forward and back in index grid via AJAX *****************************************************************************/ function index_navigate(e) { var btn = e.target; var btn_name = $(btn).attr('name'); var ax_url = $("#base_ui_callback_url").attr("href") + '&Navigate+Index=' + encodeURIComponent(btn_name) + '&SELECT=' + $('#SELECT').attr('value'); $('input:checkbox[@name="R"]').each( function(i) { if ( $(this).attr('checked') ) { ax_url = ax_url + '&R=' + $(this).attr('value'); } } ); // Show the loading graphic just to the left of the mouse click, // but stay on the button var x_pos = e.pageX - $(btn).get(0).offsetLeft; if ( x_pos > 8 ) { x_pos = x_pos - 8; } $(btn).addClass('loading'); $(btn).css( 'background-position', x_pos + 'px center' ); $.ajax( { 'type': 'GET', 'url': ax_url, 'dataType': 'json', 'success': function(obj) { if ( obj.grid ) { $('#index-header').html(obj.header); $('#index-grid').html(obj.grid); $('#index-footer').html(obj.footer); index_reorder('one-time'); } else { $('#index-grid').html(obj.msg); } }, 'error': function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } }, 'complete': function(xmlhttp, success_msg) { $(btn).removeClass('loading'); } } ); return false; } /******************************************************************* *This function would be invoked on Document.Ready by OvidDatabase.pm file *******************************************************************/ function databaselist_ready() { databaselist_set_submit_state(); $("input[@type='checkbox']", this).click( function() { databaselist_set_submit_state(); } ); } function databaselist_set_submit_state() { if ( $('#main-form input:checkbox[@checked]').length > 0 ) { $('#database-submit').removeAttr('disabled'); } else { $('#database-submit').attr('disabled', true); } } /******************************************************************* * Setup javascript behaviors for titles displays *******************************************************************/ var abs_view_all_queue = { timer: null, wait_for_click: null, rate: 500, at_a_time: 5, reset: function() { if ( this.timer != null ) { window.clearTimeout(this.timer); timer = null; } wait_for_click = null; }, start: function(buttons, rate, at_a_time) { this.wait_for_click = buttons; this.rate = rate; this.at_a_time = at_a_time; abs_view_all_queue.dispatch(); }, dispatch: function() { var self = abs_view_all_queue; if ( self.wait_for_click == null || self.wait_for_click.length == 0 ) { return; } var currently_loading = $('.titles-ab').filter('.loading').get(); if ( currently_loading == null || currently_loading.length < 5 ) { var num_to_click = self.at_a_time; if ( currently_loading != null ) { num_to_click = self.at_a_time - currently_loading.length; } for (var i=0; i < num_to_click; i++ ) { var button = self.wait_for_click.shift(); if ( button != null ) { $(button).click(); } } } self.timer = window.setTimeout( function() { abs_view_all_queue.dispatch() }, self.rate ); } }; function titles_display_setup() { // View Titles display abstracts inline var abs_buttons = $('.titles-inline-abstract/input:submit'); if ( abs_buttons.length > 0 ) { $(abs_buttons).click( function(e) { return view_inline_abstract(e); } ); $(abs_buttons).filter('.standard-button') .removeClass('standard-button') .addClass('titles-inline-abstract-closed'); } else { $('.titles-ab').css('display', 'block'); } // Set up Titles display header tools $('.titlesheader-functionblock-right').css( 'visibility', 'visible' ); var fbr = $('.titlesheader-functionblock-right'); if ( abs_buttons.length > 0 ) { $('input:checkbox', fbr).click( function(e) { set_show_all_abstracts( $(this).attr('checked') ? 1 :0, this.value ); abs_view_all_queue.reset(); if ( e.target.checked ) { // Click on the closed abstracts abs_view_all_queue.start( $(abs_buttons).filter('.titles-inline-abstract-closed').get(), 1000, 4 ); } else { // Click on the open abstracts abs_view_all_queue.start( $(abs_buttons).filter('.titles-inline-abstract-open').get(), 100, 20 ); } return true; } ); } $('select[@name=sort_by]', fbr).change( function() { titles_display_reload(); return true; } ); $('select[@name=results_per_page]', fbr).change( function() { titles_display_reload(); return true; } ); } /******************************************************************* * set_show_all_abstracts - set ShowAllAbstracts flag on the server *******************************************************************/ function set_show_all_abstracts(value, dlname) { $.ajax( { 'type': 'GET', 'url': $("#base_ui_callback_url").attr("href"), 'data': { 'Show All Abstracts': dlname + '|' + value }, 'dataType': 'text', 'success': function(msg) { console.debug( "success: " + msg ); }, 'error': function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } }, 'complete': function(xmlhttp, msg) { try { console.debug( "complete: " + msg ); } catch (e) { } } } ); return true; } /******************************************************************* * titles_checkbox_handler - click handler for citation checkboxes *******************************************************************/ function titles_checkbox_handler(e) { var dblist = $('#SELECT').attr('value'); dblist = dblist.substring(0, dblist.indexOf('|')); var checked; if ( e.target.checked ) { checked = 'Y'; } else { checked = 'N'; } titles_submit_citation_selection(dblist, e.target.value, checked); return true; } // This function is separated out in case we decide to call it from // other contexts. For example, a click handler could be attached to // the record numbers under #citman-selected-details, which shows // the details in a pop-up and offers the ability to deselect the // citation. function titles_submit_citation_selection(dblist, index, checked) { var url = $('#base_ui_callback_url').attr('href') + '&Citation+Selection=' + encodeURIComponent(dblist) + '|' + encodeURIComponent(index) + '|' + encodeURIComponent(checked); $.ajax( { 'type': 'GET', 'url': url, 'dataType': 'json', 'beforeSend': function() { // Disable the Results Manager submit buttons // until the selections are made $('.citman-container .citman-actions input.gbutton').attr('disabled', true); $('.citman-container .citman-actions input.gbutton').css('cursor', 'wait'); }, 'success': function(obj) { if ( obj.details != null ) { $('#citman-selected-details').html(obj.details); } else { alert("msg: " + obj.msg); } }, 'error': function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } }, 'complete': function(xmlhttp, success_msg) { // Re-enable the Results Manager submit buttons $('.citman-container .citman-actions input.gbutton').removeAttr('disabled'); $('.citman-container .citman-actions input.gbutton').css('cursor', 'pointer'); } } ); } /******************************************************************* * citman_clear_selected - handler for results manager clear selected * results button *******************************************************************/ function citman_clear_selected(event) { var dlist = $('#SELECT').attr('value'); dlist = dlist.substring(0, dlist.indexOf('|')); var url = $('#base_ui_callback_url').attr('href') + '&Clear+Selected+Results=' + encodeURIComponent(dlist); $.ajax( { 'type': 'GET', 'url': url, 'dataType': 'html', 'success': function(resp) { // empty the list of selected items in the results manager $('#citman-selected-details').html(''); // clear the checkboxes on the results display $('.bibrecord-checkbox[@checked]'). each(function() { $(this).attr('checked', false); }); // clear any error from the results display // in case it's one about too many results being selected $('.error').css('display','none'); }, 'error': function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } }, 'complete': function(xmlhttp, success_msg) { } } ); return false; } /******************************************************************* * view_inline_abstract(e) - On titles display, retrieve abstract * using background Ajax method. *******************************************************************/ function view_inline_abstract(e) { var btn = e.target; var parent_div = $(btn).parent(); var abs_div = $('.titles-ab', parent_div); // Ignore if the abstract is loading if ( $(abs_div).is('.loading') ) { return false; } var fbr = $('.titlesheader-functionblock-right'); var view_all_cbx = $('input:checkbox', fbr); // Hide abstract if it's already visible if ( $(abs_div).children().length > 0 ) { $(btn).removeClass('titles-inline-abstract-open'); $(btn).addClass('titles-inline-abstract-closed'); $(abs_div).html(''); $(abs_div).css( 'display', 'none' ); return false; } var btn_name = $(btn).attr('name'); var ax_url = $("#base_ui_callback_url").attr("href") + '&Get+Abstract=' + encodeURIComponent(btn_name); $(abs_div).addClass('loading'); $(abs_div).css( 'display', 'block' ); $.ajax( { 'type': 'GET', 'url': ax_url, 'dataType': 'json', 'success': function(obj) { if ( obj.abstracts ) { $(abs_div).html( obj.abstracts[0].abst ); } else { $(abs_div).html( obj.msg ); } }, 'error': function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } }, 'complete': function(xmlhttp, success_msg) { $(abs_div).removeClass('loading'); $(btn).removeClass('titles-inline-abstract-closed'); $(btn).addClass('titles-inline-abstract-open'); } } ); return false; } /******************************************************************* * titles_display_reload - refresh browser to Titles Display using * Sort By and Results Per Page SELECT element values *******************************************************************/ function titles_display_reload() { var fbr = $('.titlesheader-functionblock-right'); var field_code; var sort_by = $('select[@name=sort_by]', fbr); if ( sort_by.length > 0 ) { field_code = sort_by.get(0).value; } var page_size = $('select[@name=results_per_page]', fbr).get(0).value; var url = $('#base_ui_callback_url').attr('href') + '&Titles+Display=current||' + encodeURIComponent(page_size); if ( field_code ) { url = url + '&Sort+By=' + encodeURIComponent(field_code); } window.location = url; } /******************************************************************* * search_aid_expand() - initialize the search aid expand section *******************************************************************/ function search_aid_expand() { var resultset_num = $('#searchaid_set').text(); if ( !resultset_num ) { return; } var ax_url = $("#base_ui_callback_url").attr("href") + '&Get+SearchAid+Expand=1' + '&R=' + $("#searchaid_set").text(); $.ajax({type: "GET", url: ax_url, dataType: "html", beforeSend: function() { $("#searchaid-expand").append( '
 
'); }, success: function(resp) { $("#searchaid-expand-loading").remove(); $("#searchaid-expand").append(resp); display_search_aid_expand(); }, error: function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } $("#searchaid-expand-loading").remove(); $("#searchaid-expand").append(error_msg); } }); } /******************************************************************* * display_search_aid_expand() - show or hide the search_aid_expand section *******************************************************************/ function display_search_aid_expand() { // hide this section unless it actually contains any // expansion tools if ($("#searchaid-expand-related").length > 0) { $("#searchaid-expand").css('display','block'); } else { $("#searchaid-expand").css('display','none'); } } /******************************************************************* * search_aid_terms() - initialize the search aid terms section *******************************************************************/ function search_aid_terms() { var resultset_num = $('#searchaid_set').text(); if ( !resultset_num ) { return; } var ax_url = $("#base_ui_callback_url").attr("href") + '&Get+Search+Terms=1' + '&R=' + $("#searchaid_set").text(); $.ajax({type: "GET", url: ax_url, dataType: "json", beforeSend: function() { $("#searchaid-terms").addClass("searchaid-loading"); }, success: function(resp) { if (resp.result.indexOf('OK') >= 0) { display_search_aid_terms(resp.terms); } else { $("#searchaid-terms").html(resp.reason); } $("#searchaid-terms").removeClass("searchaid-loading"); }, error: function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } $("#searchaid-terms").removeClass("searchaid-loading"); $("#searchaid-terms").html(error_msg); } }); } // search_terms is set in the Search Aid html var search_terms; /******************************************************************* * display_search_aid_terms() - display the search aid terms section *******************************************************************/ function display_search_aid_terms(terms) { var html = '"; $("#searchaid-terms").html(html); $(".searchaid-terms-list").click( function() { $(this).toggleClass('searchaid-terms-list-open'); $(this).toggleClass('searchaid-terms-list-closed'); $('.searchaid-terms-sub',this).toggle(); }); var current_height = $('#searchaid-terms').height(); if ( current_height > 200 ) { $('#searchaid-terms').css('height', '200px'); } } // keep track of the # of requests for narrower terms issued so far var narrow_requests = 0; /******************************************************************* * search_aid_narrow() - initialize the search aid narrow section *******************************************************************/ function search_aid_narrow(request_num) { // don't bother with this if we don't have a search set // or for searches with 0 results var resultset_num = $('#searchaid_set').text(); var resultset_size = $('#searchaid_set_size').text(); if ( !resultset_num || !resultset_size || resultset_size == '0' ) { return; } // searchaid-narrow section is hidden by default, so unhide it if // we're actually going to try to populate it $('#searchaid-narrow').css( 'display', 'block' ); if (! request_num) { request_num=0; } var ax_url = $("#base_ui_callback_url").attr("href") + '&Get+SearchAid+Narrow=1' + '&R=' + $("#searchaid_set").text() + '&RequestNum=' + request_num; $.ajax({type: "GET", url: ax_url, dataType: "json", beforeSend: function() { $("#searchaid-narrow").addClass('loading'); }, success: function(resp) { // hide the entire section unless the request // succeeded if (resp.result == 'FAIL') { $("#searchaid-narrow").hide(); // if we got any results, display them } else if ( resp.result == 'PARTIAL' || resp.result == 'FULL' ) { display_aid_narrow(resp,resultset_num); } // if we have partial results request some more if (resp.result == 'PARTIAL') { // issue recursive request, upping the request number search_aid_narrow(++narrow_requests); } else { $("#searchaid-narrow").removeClass('loading'); } }, error: function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } // we get an error if the call is interupted because the user // has requested another page. ultimately it would be nice // to differentiate interrupted requests from errors, but // for now, just remove the loading icon $("#searchaid-narrow").removeClass('loading'); } }); } /******************************************************************* * display_aid_narrow() - populates the terms section of the Search * Aid narrow section *******************************************************************/ function display_aid_narrow(resp,resultset_num) { var num_fields = resp.aids.length; // just hide the aid if we don't have any valid fields if (num_fields == 0) { $("#searchaid-narrow").hide(); return; } // if this is the first time through, append the // hints and the enclosing ul for the fields if ($("#searchaid-narrow-fields-list").length == 0) { $("#searchaid-narrow-fields") .html('
' + resp.hints + '
'); } var new_html; var term_url = $("#base_ui_callback_url").attr("href") + '&Narrow+Search=' + resultset_num + '|'; // iterate through the search aid fields and add the field and // add or update the list of terms for each field to the display for (var i=0; i 0) { // if this is the first time through, append the // enclosing elements for the fields if ($("#" + field_id).length == 0 ) { new_html = $("#searchaid-narrow-fields-list") .append( '
  • ' + aid.name + '' + '
  • '); } var term_list = ''; // iterate through the terms for the field creating // li elements to hold them for (var j=0; j' + term.Term + ''; // don't show the hit counts if they're estimated // or deferred if ( ( ! resp.estimated ) && ( ! resp.deferred ) ) { term_list = term_list + ' (' + term.HitCount + ')' } term_list = term_list + ''; } // update the term list for the field with the latest set of terms $("#" + field_id + " ul.searchaid-narrow-sub").html(term_list); } else { // if a field previously had terms shown but upon final // calculation all terms have been removed, we need // to remove the field from the display $("#" + field_id).remove(); } } // if this was the first time through, add the click handlers // for the term elements if (new_html) { $(".searchaid-narrow-term").click( function() { $(this).toggleClass('searchaid-narrow-open'); $(this).toggleClass('searchaid-narrow-closed'); $('.searchaid-narrow-sub',this).toggle(); }); // prevent a click on the link from propagating to the enclosing // li so that it doesn't toggle list closed $(".searchaid-narrow-term a.tlink").bind("click", function(event){ event.stopPropagation(); }); } else if ($(".searchaid-narrow-term").length == 0) { // we didn't get any valid terms so hide the aid $("#searchaid-narrow").hide(); } return; } /******************************************************************* * utility function for scrolling to a specific element * calculating the offset including the coordinates of the * offsetParent - for most elements the offsetParent will be the body *******************************************************************/ function scroll_to_id(id) { var element = $('#'+id).get(0); if (element) { var xCoord = 0; var yCoord = 0; do { xCoord += element.offsetLeft; yCoord += element.offsetTop; } while (element = element.offsetParent); window.scrollTo(xCoord,yCoord); } } /******************************************************************* * open_annotation_window(e) * * If the annotation icon link uses target='_blank', open a new * window and return false to cancel the event. Otherwise, return * true so the browser will do it's normal behavior. * * When opening a new window, only allow one, named annotation and * referenced in AnnotationWindow. If the window is already open, * change its location and bring it to the front. Otherwise, create * a new window. *******************************************************************/ var AnnotationWindow = null; var AnnotationWindowReady = null; var AnnotationWindowLink = null; function open_annotation_window(e) { var link = $(e.target).parent(); if ( $(link).attr('target') == '_blank' ) { var left = 200; var top = 200; if ( AnnotationWindow == null || AnnotationWindow.closed ) { AnnotationWindow = window.open( $(link).attr('href'), 'annotation', 'resizable=yes,' + 'scrollbars=yes,' + 'dependent=yes,' + 'status=yes,' + 'left=' + left + ',' + 'top=' + top + ',' + 'width=700,' + 'height=480' ); } else { AnnotationWindow.focus(); $(AnnotationWindow.document.body).html(''); AnnotationWindow.location = $(link).attr('href'); } // Monitor AnnotationWindow, and update icon when it // closes. AnnotationWindowLink = $(link).get(0); window.setTimeout( wait_for_annotation_window, 250 ); return false; } return true; } function wait_for_annotation_window() { if ( AnnotationWindow == null ) { window.setTimeout( wait_for_annotation_window, 250 ); return; } window.setTimeout( check_annotation_window, 250 ); } function check_annotation_window() { if ( AnnotationWindow != null && !(AnnotationWindow.closed) ) { window.setTimeout( check_annotation_window, 250 ); return; } var href = $(AnnotationWindowLink).attr('href'); var match_array = /(?:Annotate|View.Annotation)=([^&;]+)/.exec(href); var annotation_id = match_array[1]; var ax_url = $("#base_ui_callback_url").attr("href") + '&Get+Annotation+Link=' + annotation_id; $.ajax( { 'type': 'GET', 'url': ax_url, 'dataType': 'json', 'success': function(obj) { if ( obj.link ) { var elem = $(AnnotationWindowLink).parent().get(0); $(elem).attr( { className: obj.link.div_class, title: obj.link.div_title } ); $('a', elem).attr( 'href', obj.link.a_href ); $('a img', elem).attr( { alt: obj.link.img_alt, src: obj.link.img_src } ); } else { alert( "Error: " + obj.msg ); } }, 'error': function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } } } ); } function init_annotation_links() { $('div.has-annotation a').click( function(e) { return open_annotation_window(e); } ); $('div.can-annotate a').click( function(e) { return open_annotation_window(e); } ); } /******************************************************************* * send_heartbeat() - sends a request to keep the session from * timing out. If the request returns OK, set the timer again. * If the request returns DELAYEXCEEDED, let the user know their * session is going to time out. * If the request is successful but does not returns something else, * tell the user that the session ended. * If the request is not successful, try again in five minutes. * If the failure is a network problem, the repeat attempt should * catch the session before it ends. If the RDC is down, five * minutes should be enough to prevent a flood of heartbeats. *******************************************************************/ function send_heartbeat() { var meta = $('meta[@name=heartbeat-interval]').get(0); var interval = $(meta).attr('content'); if ( interval < 1000 ) { return; } var page_id_list = $('meta[@name=OvidPageId]'); var page_id = ''; if ( page_id_list.length > 0 ) { for (var i=0; i< page_id_list.length; i++ ) { page_id = page_id + '&PAGE_ID=' + $(page_id_list[i]).attr('content'); } } var ax_url = $("#base_ui_callback_url").attr("href") + '&Heartbeat=1' + page_id; $.ajax( { 'type': 'GET', 'url': ax_url, 'dataType': 'json', 'success': function(obj) { var now = new Date; if ( obj.status == 'OK' ) { window.setTimeout( send_heartbeat, interval ); } else if ( obj.status == 'DELAYEXCEEDED' ) { alert( obj.msg + "\n" + now ); } else { // Timeout or ovidweb failure alert( obj.msg + "\n" + now ); } }, 'error': function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } // Network failure or ovidweb too busy to respond window.setTimeout( send_heartbeat, 300000 ); } } ); } /****************************************************************************** * top_similar_retrieve() - populate the #top-similar box on * citation displays ******************************************************************************/ function top_similar_retrieve() { var record_id = $('#top-similar-source').attr('value'); var list_elem = $('#top-similar ul').get(0); var ax_url = $("#base_ui_callback_url").attr("href") + '&Get+Top+Similar=' + record_id; $('#top-similar #container').addClass("loading"); $('#top-similar #container').css('background-position', 'top left'); $.ajax( { 'type': 'GET', 'url': ax_url, 'dataType': 'json', 'success': function(obj) { if ( obj.records ) { for ( var i=0; i" + obj.records[i].link + ""); } } else { $(list_elem).append("
  • " + obj.msg + "
  • "); } }, 'error': function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch (e) { } }, 'complete': function(xmlhttp, success_msg) { $('#top-similar #container').removeClass("loading"); var current_height = $('#top-similar #container').height(); if ( current_height > 200 ) { $('#top-similar #container').css('height', '200px'); } } } ); } /****************************************************************************** * open_help_window() ******************************************************************************/ var HelpWindow = null; function open_help_window(e) { var link = $(e.target); if ( $(link).attr('target') == '_blank' ) { var left = 200; var top = 200; var width = 920; var height = 600; if ( HelpWindow == null || HelpWindow.closed ) { if ( window.screen.width > 1024 ) { width = 1024; } else if ( window.screen.width > 920 ) { width = 920; } else if ( window.screen.width > 0 ) { width = window.screen.width; } if ( window.screen.height > 0 ) { height = Math.floor( window.screen.height * 0.80 ); } left = Math.floor( ( window.screen.width - width ) / 2 ); top = Math.floor( ( window.screen.height - height ) / 2 ); HelpWindow = window.open( $(link).attr('href'), 'OvidHelp', 'resizable=yes,' + 'scrollbars=yes,' + 'dependent=yes,' + 'status=yes,' + 'left=' + left + ',' + 'top=' + top + ',' + 'width=' + width + ',' + 'height=' + height ); } else { HelpWindow.focus(); HelpWindow.location = $(link).attr('href'); } return false; } return true; } /****************************************************************************** * ajax_enable * set a flag on the server indicating that we can process an ajax request ******************************************************************************/ function ajax_enable() { var axurl = $("#base_ui_callback_url").attr("href") + '&Ajax+Enable=1'; // While we're at it, collect some metrics about the browser if ( window.screen ) { axurl = axurl + '&screen=' + window.screen.width + 'x' + window.screen.height + 'x' + window.screen.colorDepth; } if ( window.navigator ) { axurl = axurl + '&cookie=' + (window.navigator.cookieEnabled ? 'yes' : 'no'); } $.ajax({type: "GET", url: axurl, dataType: "html"}); } /***************************************************************************** * setup_RSS_popup() - $().ready(...) function which will be executed for * RSS pop up. *****************************************************************************/ function setup_RSS_popup() { $("a[@name=rss_popup]").click( function(e) { if ($("#RSSoptions").css("visibility") == 'visible') { hide_RSS_options(); } var url = $(this).attr("href"); show_RSS_subscribe_options(e.pageX, e.pageY, url); return false; }); $("input[@name=submit:rss_popup]").click( function() { show_RSS_subscribe_options('','','',1); return false; } ); $("input[@name=submit:Cancel|2]").click( function() { hide_RSS_subscribe_options(); return false; } ); } function hide_RSS_subscribe_options() { $("#RSSsubscribeOptions").css({ 'visibility': "hidden" }); } function show_RSS_subscribe_options(xcoord, ycoord, url, new_win) { if (new_win) { var rss_reader_id = $("select[@name=subscribe_option]").val(); var rss_subscriber = $( ("#" + rss_reader_id) ).attr("href"); var rss_subscribe_link = $("input[@name=link_pop_up]").val(); rss_subscriber = rss_subscriber ? rss_subscriber + rss_subscribe_link : rss_subscribe_link; openWeblink(rss_subscriber); hide_RSS_subscribe_options(); return false; } else { if ( $.browser.msie && window.navigator.appVersion.indexOf('MSIE 6') > 0 ) { $("select[@name=subscribe_option]").children("option").each( function() { if ( $(this).html() == "Current Browser" ) { $(this).remove(); } }); } var left = xcoord + 'px'; var top = ycoord + 'px'; $("input[@name=link_pop_up]").val(url); $("#RSSsubscribeOptions").css({ 'visibility': 'visible', 'left': left, 'top': top}); } } /****************************************************************************** * checkbox_state_change - used to notify the UI that checkboxes that are * normally controlled with a SELECT parameter are changing state even though * the page is not reloading and there is no opportunity for the UI to update * the SELECT parameter. ******************************************************************************/ function checkbox_state_change( checkbox, start, count, action_button ) { var dblist = $('#SELECT').attr('value'); dblist = dblist.substring(0, dblist.indexOf('|')); var checked; if ( checkbox.checked ) { checked = 'Y'; } else { checked = 'N'; } var index = checkbox.value; var url = $('#base_ui_callback_url').attr('href') + '&Checkbox+State+Change=' + encodeURIComponent(dblist) + '|' + encodeURIComponent(index) + '|' + encodeURIComponent(checked) + '&start=' + start + '&count=' + count; $.ajax( { 'type': 'GET', 'url': url, 'dataType': 'json', 'beforeSend': function() { if ( action_button ) { $(action_button).attr('disabled', true); $(action_button).css('cursor', 'wait'); } }, 'success': function(obj) { if ( obj.selection != null ) { $('#SELECT').attr('value', obj.selection ) } else { alert("msg: " + obj.msg); } }, 'error': function(xmlhttp, error_msg, exception) { try { console.error( xmlhttp, error_msg, exception ); } catch(e) { } }, 'complete': function(xmlhttp, success_msg) { if ( action_button ) { $(action_button).removeAttr('disabled'); $(action_button).css('cursor', 'pointer'); } } } ); } /****************************************************************************** * ******************************************************************************/