From b6bc096483857c9da19508cbce79b8f5f5d10081 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonathan=20Ara=C3=B1a=20Cruz?= <jonhattan@49817.no-reply.drupal.org>
Date: Mon, 7 Mar 2011 20:21:41 +0100
Subject: [PATCH] Issue #382394: apply ajax pager effects

---
 css/views.css                    |    5 +++
 includes/view.inc                |    6 ++--
 js/ajax_view.js                  |   73 ++++++++++++++++++++++++++++++++++++-
 plugins/views_plugin_display.inc |   13 ++++---
 theme/theme.inc                  |    4 ++-
 views.module                     |    2 +-
 6 files changed, 90 insertions(+), 13 deletions(-)

diff --git a/css/views.css b/css/views.css
index beb5782..64de361 100644
--- a/css/views.css
+++ b/css/views.css
@@ -96,3 +96,8 @@ div.view:hover div.views-hide {
   border-top: none;
 }
 
+/* Prevent animation jumps when using ajax calls on View tables */
+.view-content table {
+  display: block;
+  margin: 0;
+}
diff --git a/includes/view.inc b/includes/view.inc
index b316afc..9384ee0 100644
--- a/includes/view.inc
+++ b/includes/view.inc
@@ -115,7 +115,7 @@ class view extends views_db_object {
   }
 
   /**
-   * The pager element id to use if use_apger is on
+   * The pager element id to use if use_pager is on
    */
   function set_pager_element($pager_element) {
     $this->pager['element'] = $pager_element;
@@ -135,7 +135,7 @@ class view extends views_db_object {
    * rather than a page refresh.
    */
   function set_use_ajax($use_ajax) {
-    $this->use_ajax = $use_ajax;
+    $this->use_ajax['use_ajax'] = $use_ajax;
   }
 
   /**
@@ -405,7 +405,7 @@ class view extends views_db_object {
       unset($form_state['rerender']);
     }
 
-    if (!empty($this->ajax)) {
+    if (!empty($this->use_ajax)) {
       $form_state['ajax'] = TRUE;
     }
 
diff --git a/js/ajax_view.js b/js/ajax_view.js
index e56e73a..78fe39e 100644
--- a/js/ajax_view.js
+++ b/js/ajax_view.js
@@ -27,6 +27,7 @@ Drupal.Views.Ajax.ajaxViewResponse = function(target, response) {
     $view.replaceWith($newView);
     $view = $newView;
     Drupal.attachBehaviors($view.parent());
+    $view.find('.view-content').hide();
   }
 
   if (response.messages) {
@@ -36,6 +37,61 @@ Drupal.Views.Ajax.ajaxViewResponse = function(target, response) {
 };
 
 /**
+ * jQuery effect for Views.
+ */
+Drupal.Views.Ajax.jQueryEffectHide = function(target, effect) {
+  var $view_content = $(target + ' .view-content');
+  var $view = $view_content.children();
+  var height = $view_content.height();
+  $view_content.height($view_content.height());
+
+  switch(effect) {
+    case 'hideshow':
+      $view.hide('slow');
+      break;
+    case 'slide':
+      $view.slideUp('slow');
+      break;
+    case 'fade':
+      $view.fadeOut('slow');
+      break;
+  }
+  return height;
+};
+
+/**
+ * jQuery effect for Views.
+ */
+Drupal.Views.Ajax.jQueryEffectShow = function(target, effect, height) {
+  var $view_content = $(target + ' .view-content');
+  var $view = $view_content.children();
+  $view_content.show();
+  $view.show();
+  var height_new = $view_content.height();
+
+  $view.hide();
+  $view_content.height(height).animate({height: height_new}, 'slow', 'swing', function(){
+    switch(effect) {
+      case 'hideshow':
+        $view.show('slow', function(){
+          $view_content.height('');
+        });
+        break;
+      case 'slide':
+        $view.slideDown('slow', function(){
+          $view_content.height('');
+        });
+        break;
+      case 'fade':
+        $view.fadeIn('slow', function(){
+          $view_content.height('');
+        });
+        break;
+    }
+  });
+};
+
+/**
  * Ajax behavior for views.
  */
 Drupal.behaviors.ViewsAjaxView = function() {
@@ -76,6 +132,7 @@ Drupal.behaviors.ViewsAjaxView = function() {
       .submit(function () {
         $('input[type=submit], button', this).after('<span class="views-throbbing">&nbsp</span>');
         var object = this;
+        var height = Drupal.Views.Ajax.jQueryEffectHide(view, settings.view_use_ajax);
         $(this).ajaxSubmit({
           url: ajax_path,
           type: 'GET',
@@ -85,10 +142,15 @@ Drupal.behaviors.ViewsAjaxView = function() {
               $.each(response.__callbacks, function(i, callback) {
                 eval(callback)(view, response);
               });
+              Drupal.Views.Ajax.jQueryEffectShow(view, settings.view_use_ajax, height);
               $('.views-throbbing', object).remove();
             }
           },
-          error: function(xhr) { Drupal.Views.Ajax.handleErrors(xhr, ajax_path); $('.views-throbbing', object).remove(); },
+          error: function(xhr) {
+            $('.views-throbbing', object).remove();
+            Drupal.Views.Ajax.handleErrors(xhr, ajax_path);
+            Drupal.Views.Ajax.jQueryEffectShow(view, settings.view_use_ajax, height);
+          },
           dataType: 'json'
         });
 
@@ -125,6 +187,8 @@ Drupal.behaviors.ViewsAjaxView = function() {
               $(this).click(function () {
                 $.extend(viewData, Drupal.Views.parseViewArgs($(this).attr('href'), settings.view_base_path));
                 $(this).addClass('views-throbbing');
+                var height = Drupal.Views.Ajax.jQueryEffectHide(view, settings.view_use_ajax);
+
                 $.ajax({
                   url: ajax_path,
                   type: 'GET',
@@ -153,8 +217,13 @@ Drupal.behaviors.ViewsAjaxView = function() {
                         eval(callback)(target, response);
                       });
                     }
+                    Drupal.Views.Ajax.jQueryEffectShow(view, settings.view_use_ajax, height);
+                  },
+                  error: function(xhr) {
+                    $(this).removeClass('views-throbbing');
+                    Drupal.Views.Ajax.handleErrors(xhr, ajax_path);
+                    Drupal.Views.Ajax.jQueryEffectShow(view, settings.view_use_ajax, height);
                   },
-                  error: function(xhr) { $(this).removeClass('views-throbbing'); Drupal.Views.Ajax.handleErrors(xhr, ajax_path); },
                   dataType: 'json'
                 });
 
diff --git a/plugins/views_plugin_display.inc b/plugins/views_plugin_display.inc
index a8e4a7d..f5f7452 100644
--- a/plugins/views_plugin_display.inc
+++ b/plugins/views_plugin_display.inc
@@ -105,7 +105,7 @@ class views_plugin_display extends views_plugin {
     if (!empty($this->definition['use ajax'])) {
       return $this->get_option('use_ajax');
     }
-    return FALSE;
+    return 'no';
   }
 
   /**
@@ -343,7 +343,7 @@ class views_plugin_display extends views_plugin {
         'default' => FILTER_FORMAT_DEFAULT,
       ),
       'use_ajax' => array(
-        'default' => FALSE,
+        'default' => 'no',
       ),
       'items_per_page' => array(
         'default' => 10,
@@ -727,7 +727,7 @@ class views_plugin_display extends views_plugin {
       $options['use_ajax'] = array(
         'category' => 'basic',
         'title' => t('Use AJAX'),
-        'value' => $this->get_option('use_ajax') ? t('Yes') : t('No'),
+        'value' => $this->get_option('use_ajax') != 'no' ? t('Yes') : t('No'),
         'desc' => t('Change whether or not this display will use AJAX.'),
       );
     }
@@ -936,8 +936,9 @@ class views_plugin_display extends views_plugin {
         );
         $form['use_ajax'] = array(
           '#type' => 'radios',
-          '#options' => array(1 => t('Yes'), 0 => t('No')),
-          '#default_value' => $this->get_option('use_ajax') ? 1 : 0,
+          '#options' => array('hideshow' => t('Hide/show'), 'slide' => t('Slide up/down'), 'fade' => t('Fade in/out'), 'no' => t('None')),
+          '#description' => t("If AJAX is being used, you can select a jQuery effect to transition between changing content."),
+          '#default_value' => $this->get_option('use_ajax'),
         );
         break;
       case 'use_pager':
@@ -1573,7 +1574,7 @@ class views_plugin_display extends views_plugin {
         $this->set_option($section, $form_state['values'][$section]);
         break;
       case 'use_ajax':
-        $this->set_option($section, (bool)$form_state['values'][$section]);
+        $this->set_option($section, $form_state['values'][$section]);
         break;
       case 'use_pager':
         $this->set_option($section, $form_state['values'][$section]);
diff --git a/theme/theme.inc b/theme/theme.inc
index c6377a5..beb8b91 100644
--- a/theme/theme.inc
+++ b/theme/theme.inc
@@ -141,7 +141,7 @@ function template_preprocess_views_view(&$vars) {
   $vars['classes_array'][] = 'view-dom-id-' . $vars['dom_id'];
 
   // If using AJAX, send identifying data about this view.
-  if ($view->use_ajax) {
+  if ($view->use_ajax['use_ajax'] != 'no') {
     $settings = array(
       'views' => array(
         'ajax_path' => url('views/ajax'),
@@ -158,6 +158,8 @@ function template_preprocess_views_view(&$vars) {
             // To fit multiple views on a page, the programmer may have
             // overridden the display's pager_element.
             'pager_element' => $view->pager['element'],
+            // jQuery effect for AJAX transitions
+            'view_use_ajax' => $view->use_ajax['use_ajax'],
           ),
         ),
       ),
diff --git a/views.module b/views.module
index df5d0b5..016e920 100644
--- a/views.module
+++ b/views.module
@@ -1044,7 +1044,7 @@ function views_exposed_form(&$form_state) {
 //  $form['#attributes']['class'] = array('views-exposed-form');
 
   // If using AJAX, we need the form plugin.
-  if ($view->use_ajax) {
+  if ($view->use_ajax['use_ajax']) {
     drupal_add_js('misc/jquery.form.js');
   }
   views_add_js('dependent');
-- 
1.7.2.3

