Drupal.settings.views = Drupal.settings.views || {'ajax_path': 'views/ajax'}; Drupal.behaviors.quicktabs = function (context) { $('.quicktabs_wrapper:not(.quicktabs-processed)', context).addClass('quicktabs-processed').each(function(){ Drupal.quicktabs.prepare(this); }); }; Drupal.quicktabs = Drupal.quicktabs || {}; Drupal.quicktabs.ajax = {}; Drupal.quicktabs.scripts = {}; Drupal.quicktabs.css = {}; // setting up the inital behaviours Drupal.quicktabs.prepare = function(el) { var i = 0; // el.id format: "quicktabs-$qtid" var qtid = el.id.substring(el.id.indexOf('-') +1); var $ul = $(el).find('ul.quicktabs_tabs:first'); $ul.find('li a').each(function(){ this.myTabIndex = i++; this.qtid = qtid; $(this).unbind('click').bind('click', quicktabsClick); }); // Search for the active tab. var $active_tab = $(el).children('.quicktabs_tabs').find('li.active a'); if ($active_tab.hasClass('qt_tab') || $active_tab.hasClass('qt_ajax_tab')) { $active_tab.trigger('click'); } else { // Click on the first tab. $(el).children('.quicktabs_tabs').find('li.first a').trigger('click'); } return false; } // constructor for an individual tab Drupal.quicktabs.tab = function (el) { this.element = el; this.tabIndex = el.myTabIndex; this.qtid = el.qtid; var qtKey = 'qt_' + this.qtid; var i = 0; for (var key in Drupal.settings.quicktabs[qtKey].tabs) { if (i == this.tabIndex) { this.tabObj = Drupal.settings.quicktabs[qtKey].tabs[key]; this.tabKey = key; } i++; } this.tabpage_id = 'quicktabs_tabpage_' + this.qtid + '_' + this.tabKey; this.container = $('#quicktabs_container_' + this.qtid); this.tabpage = this.container.find('#' + this.tabpage_id); // The 'this' variable will not persist inside of the options object. var tab = this; this.options = { success: function(response) { return tab.success(response); }, complete: function(response) { return tab.complete(); } } } // ajax callback for non-views tabs Drupal.quicktabs.tab.prototype.success = function(response) { this.container.append(Drupal.theme('quicktabsResponse', this, response.data.content)); $.extend(true, Drupal.settings, response.data.js_css.js_settings); Drupal.quicktabs.ajax.scripts(response.data.js_css.js_files); Drupal.quicktabs.ajax.css_files(response.data.js_css.css_files); Drupal.attachBehaviors(this.container); } // function to call on completed ajax call // for non-views tabs Drupal.quicktabs.tab.prototype.complete = function() { // stop the progress bar this.stopProgress(); } Drupal.quicktabs.tab.prototype.stopProgress = function () { if (this.progress.element) { $(this.progress.element).remove(); } $(this.element).removeClass('progress-disabled').attr('disabled', false); } Drupal.quicktabs.tab.prototype.startProgress = function () { var progressBar = new Drupal.progressBar('qt-progress-' + this.element.id, null, null, null); progressBar.setProgress(-1, Drupal.t('Loading')); this.progress = {}; this.progress.element = $(progressBar.element).addClass('qt-progress qt-progress-bar'); this.container.prepend(this.progress.element); } Drupal.quicktabs.tab.prototype.quicktabsAjaxView = function() { // Create an empty div for the tabpage. The generated view will be inserted into this. var tab = this; tab.container.append(Drupal.theme('quicktabsResponse', this, null)); var target; target = $('#' + tab.tabpage_id + ' > div'); var ajax_path = Drupal.settings.views.ajax_path; //If there are multiple views this might've ended up showing up multiple times. if (ajax_path.constructor.toString().indexOf("Array") != -1) { ajax_path = ajax_path[0]; } var args; if (tab.tabObj.args != '') { args = tab.tabObj.args.join('/'); } else { args = ''; } var viewData = { 'view_name': tab.tabObj.vid, 'view_display_id': tab.tabObj.display, 'view_args': args } $.ajax({ url: ajax_path, type: 'GET', data: viewData, success: function(response) { // Call all callbacks. if (response.__callbacks) { $.each(response.__callbacks, function(i, callback) { eval(callback)(target, response); }); } }, complete: function() { tab.stopProgress(); }, error: function() { alert(Drupal.t("An error occurred at @path.", {'@path': ajax_path})); }, dataType: 'json' }); } var quicktabsClick = function() { var tab = new Drupal.quicktabs.tab(this); // Set clicked tab to active. $(this).parents('li').siblings().removeClass('active'); $(this).parents('li').addClass('active'); // Hide all tabpages. tab.container.children().addClass('quicktabs-hide'); // Show the active tabpage. if (tab.tabpage.hasClass('quicktabs_tabpage')) { tab.tabpage.removeClass('quicktabs-hide'); } else { if ($(this).hasClass('qt_ajax_tab')) { tab.startProgress(); // Construct the ajax tabpage. if (tab.tabObj.type != 'view') { // construct the ajax path to retrieve the content, depending on type var qtAjaxPath = Drupal.settings.basePath + 'quicktabs/ajax/' + tab.tabObj.type + '/'; switch (tab.tabObj.type) { case 'node': qtAjaxPath += tab.tabObj.nid + '/' + tab.tabObj.teaser + '/' + tab.tabObj.hide_title; break; case 'block': qtAjaxPath += tab.qtid + '/' + tab.tabObj.bid + '/' + tab.tabObj.hide_title; break; case 'qtabs': qtAjaxPath += tab.tabObj.machine_name; break; case 'callback': qtAjaxPath += tab.tabObj.path; break; } $.ajax({ url: qtAjaxPath, type: 'GET', data: null, success: tab.options.success, complete: tab.options.complete, dataType: 'json' }); } else { // special treatment for views tab.quicktabsAjaxView(); } } } return false; } // theme function for ajax response Drupal.theme.prototype.quicktabsResponse = function(tab, content) { var newDiv = tab.tabObj.type == 'view' ? '
' : '
' + content + '
'; return newDiv; }; /** * Quicktabs' implementation of merlinofchaos's CTools js magic for loading * required js files for ajax-loaded content */ Drupal.quicktabs.ajax.scripts = function(files) { // Build a list of scripts already loaded: var scripts = {}; $('script').each(function () { Drupal.quicktabs.scripts[$(this).attr('src')] = $(this).attr('src'); }); var html = ''; var head = document.getElementsByTagName('head')[0]; for (var i in files) { // Load all files that aren't already present on the page, but make sure not // to add misc/jquery.js because this could override a newer version of // jQuery loaded by jQuery Update module. Ctools itself has a much more generic // way of dealing with this (i.e. not just for jquery.js) and it would be much // better to use ctools rather than copying its code, but I don't want to make // it a dependency at this stage. if (!Drupal.quicktabs.scripts[files[i]] && !files[i].match(/^\/misc\/jquery\.js.*$/)) { Drupal.quicktabs.scripts[files[i]] = files[i]; var script = document.createElement('script'); script.type = 'text/javascript'; script.src = files[i]; head.appendChild(script); html += ''; } } if (html) { $('body').append($(html)); } }; /** * Quicktabs' implementation of merlinofchaos's CTools js magic for loading * required css files for ajax-loaded content */ Drupal.quicktabs.ajax.css_files = function(files) { // Build a list of css files already loaded: $('link:not(.qt-temporary-css)').each(function () { if ($(this).attr('type') == 'text/css') { Drupal.quicktabs.css[$(this).attr('href')] = $(this).attr('href'); } }); var html = ''; for (var i in files) { if (!Drupal.quicktabs.css[files[i].file]) { html += ''; } } if (html) { $('link.ctools-temporary-css').remove(); $('body').append($(html)); } };