// $Id$ /** * @file ajaxView.js * * Handles AJAX fetching of views, including filter submission and response. */ Drupal.Views.Ajax = Drupal.Views.Ajax || {}; /** * An ajax responder that accepts a packet of JSON data and acts appropriately. * * The following fields control behavior. * - 'display': Display the associated data in the view area. */ Drupal.Views.Ajax.ajaxViewResponse = function(target, response) { if (response.debug) { alert(response.debug); } var $view = $(target); // Check the 'display' for data. if (response.status && response.display) { var $newView = $(response.display); $view.replaceWith($newView); $view = $newView; Drupal.attachBehaviors($view.parent()); } if (response.messages) { // Show any messages (but first remove old ones, if there are any). $view.find('.views-messages').remove().end().prepend(response.messages); } }; /** * Ajax behavior for views. */ Drupal.behaviors.ViewsAjaxView = function() { if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) { 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]; } $.each(Drupal.settings.views.ajaxViews, function(i, settings) { var view = '.view-dom-id-' + settings.view_dom_id; if (!$(view).size()) { // Backward compatibility: if 'views-view.tpl.php' is old and doesn't // contain the 'view-dom-id-#' class, we fall back to the old way of // locating the view: view = '.view-id-' + settings.view_name + '.view-display-id-' + settings.view_display_id; } // Process exposed filter forms. $('form#views-exposed-form-' + settings.view_name.replace(/_/g, '-') + '-' + settings.view_display_id.replace(/_/g, '-')) .filter(':not(.views-processed)') .each(function () { // remove 'q' from the form; it's there for clean URLs // so that it submits to the right place with regular submit // but this method is submitting elsewhere. $('input[name=q]', this).remove(); var form = this; // ajaxSubmit doesn't accept a data argument, so we have to // pass additional fields this way. $.each(settings, function(key, setting) { $(form).append(''); }); }) .addClass('views-processed') .submit(function () { $('input[type=submit], button', this).after(' '); var object = this; $(this).ajaxSubmit({ url: ajax_path, type: 'GET', success: function(response) { // Call all callbacks. if (response.__callbacks) { $.each(response.__callbacks, function(i, callback) { eval(callback)(view, response); }); $('.views-throbbing', object).remove(); } }, error: function() { alert(Drupal.t("An error occurred at @path.", {'@path': ajax_path})); $('.views-throbbing', object).remove(); }, dataType: 'json' }); return false; }); $(view).filter(':not(.views-processed)') // Don't attach to nested views. Doing so would attach multiple behaviors // to a given element. .filter(function() { // If there is at least one parent with a view class, this view // is nested (e.g., an attachment). Bail. return !$(this).parents('.view').size(); }) .each(function() { // Set a reference that will work in subsequent calls. var target = this; $(this) .addClass('views-processed') // Process pager, tablesort, and attachment summary links. .find('ul.pager > li > a, th.views-field a, .attachment .views-summary a') .each(function () { var viewData = {}; // Construct an object using the settings defaults and then overriding // with data specific to the link. $.extend( viewData, settings, Drupal.Views.parseQueryString($(this).attr('href')), // Extract argument data from the URL. Drupal.Views.parseViewArgs($(this).attr('href'), settings.view_base_path) ); $(this).click(function () { $(this).addClass('views-throbbing'); $.ajax({ url: ajax_path, type: 'GET', data: viewData, success: function(response) { $(this).removeClass('views-throbbing'); // Scroll to the top of the view. This will allow users // to browse newly loaded content after e.g. clicking a pager // link. var offset = $(target).offset(); // Only scroll upward if (offset.top - 10 < $(window).scrollTop()) { $('html,body').animate({scrollTop: (offset.top - 10)}, 500); } // Call all callbacks. if (response.__callbacks) { $.each(response.__callbacks, function(i, callback) { eval(callback)(target, response); }); } }, error: function() { $(this).removeClass('views-throbbing'); alert(Drupal.t("An error occurred at @path.", {'@path': ajax_path})); }, dataType: 'json' }); return false; }); }); // .each function () { }); // $view.filter().each }); // .each Drupal.settings.views.ajaxViews } // if };