Index: includes/view.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/view.inc,v
retrieving revision 1.141
diff -u -p -r1.141 view.inc
--- includes/view.inc	19 Nov 2008 22:33:55 -0000	1.141
+++ includes/view.inc	6 Dec 2008 07:00:13 -0000
@@ -28,6 +28,7 @@ class view extends views_db_object {
   var $build_info = array();
 
   var $use_ajax = FALSE;
+  var $ajax_refresh_interval = 0;
 
   // pager variables
   var $pager = array(
@@ -128,6 +129,15 @@ class view extends views_db_object {
   }
 
   /**
+   * Whether or not AJAX should be used. If AJAX is used, paging,
+   * tablesorting and exposed filters will be fetched via an AJAX call
+   * rather than a page refresh.
+   */
+  function set_ajax_refresh_interval($interval) {
+    $this->ajax_refresh_interval = $interval;
+  }
+
+  /**
    * Set the exposed filters input to an array. If unset they will be taken
    * from $_GET when the time comes.
    */
Index: js/ajax_view.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/js/ajax_view.js,v
retrieving revision 1.13
diff -u -p -r1.13 ajax_view.js
--- js/ajax_view.js	2 Dec 2008 18:35:50 -0000	1.13
+++ js/ajax_view.js	6 Dec 2008 07:00:13 -0000
@@ -40,13 +40,11 @@ Drupal.Views.Ajax.ajaxViewResponse = fun
  * Ajax behavior for views. 
  */
 Drupal.behaviors.ViewsAjaxView = function() {
-  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 ajax_path = Drupal.Views.Ajax.getAjaxPath();
+
   if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) {
-    $.each(Drupal.settings.views.ajaxViews, function(i, settings) {
+    $.each(Drupal.settings.views.ajaxViews, function(view_dom_id, settings) {
+      Drupal.settings.views.ajaxViews[settings.view_dom_id].currentView = {};
       var view = '.view-dom-id-' + settings.view_dom_id;
       if (!$(view).size()) {
         // Backward compatibility: if 'views-view.tpl.php' is old and doesn't
@@ -95,6 +93,13 @@ Drupal.behaviors.ViewsAjaxView = functio
       });
 
       $(view).filter(':not(.views-processed)').each(function() {
+        // If this view is set to autmoatically refresh, schedule refreshing.
+        // We only need to set the timeout once because it will be reset
+        // when the new view loads and this behavior reattaches.
+        if (settings.ajax_refresh_interval) {
+          var timeoutId = window.setTimeout('Drupal.Views.Ajax.refreshView("' + settings.view_dom_id + '", "' + view + '")', settings.ajax_refresh_interval);
+          $(window).unload(function () {clearTimeout(timeoutId);});
+        }
         var target = this;
         $(this)
         .addClass('views-processed')
@@ -139,7 +144,7 @@ Drupal.behaviors.ViewsAjaxView = functio
           $.each(settings, function (key, setting) {
             viewData[key] = setting;
           });
-
+          delete(viewData.currentView);
           $(this)
             .click(function () {
               $(this).addClass('views-throbbing');
@@ -167,3 +172,36 @@ Drupal.behaviors.ViewsAjaxView = functio
     }); // .each Drupal.settings.views.ajaxViews
   } // if
 };
+
+Drupal.Views.Ajax.getAjaxPath = function () {
+  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];
+  }
+  return ajax_path;
+};
+
+Drupal.Views.Ajax.refreshView = function (domId, selector) {
+  var target = $(selector).addClass('views-throbbing').get(0);
+  var viewData = Drupal.settings.views.ajaxViews[domId];
+  // Read in current state information.
+  $.extend(viewData, viewData.currentView);
+  var ajax_path = Drupal.Views.Ajax.getAjaxPath();
+  $.ajax({
+    url: ajax_path,
+    type: 'GET',
+    data: viewData,
+    success: function(response) {
+      $(target).removeClass('views-throbbing');
+      // Call all callbacks.
+      if (response.__callbacks) {
+        $.each(response.__callbacks, function(i, callback) {
+          eval(callback)(target, response);
+        });
+      }
+    },
+    error: function() { $(target).removeClass('views-throbbing'); alert(Drupal.t("An error occurred at @path.", {'@path': ajax_path})); },
+    dataType: 'json'
+  });
+}
Index: plugins/views_plugin_display.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_display.inc,v
retrieving revision 1.17
diff -u -p -r1.17 views_plugin_display.inc
--- plugins/views_plugin_display.inc	2 Dec 2008 20:23:21 -0000	1.17
+++ plugins/views_plugin_display.inc	6 Dec 2008 07:00:18 -0000
@@ -152,7 +152,7 @@ class views_plugin_display extends views
       'header' => array('header', 'header_format', 'header_empty'),
       'footer' => array('footer', 'footer_format', 'footer_empty'),
       'empty' => array('empty', 'empty_format'),
-      'use_ajax' => array('use_ajax'),
+      'use_ajax' => array('use_ajax', 'ajax_refresh_interval'),
       'items_per_page' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
       'use_pager' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
       'use_more' => array('use_more'),
@@ -223,6 +223,7 @@ class views_plugin_display extends views
           'empty_format' => TRUE,
 
           'use_ajax' => TRUE,
+          'ajax_refresh_interval' => TRUE,
           'items_per_page' => TRUE,
           'offset' => TRUE,
           'use_pager' => TRUE,
@@ -304,6 +305,9 @@ class views_plugin_display extends views
       'use_ajax' => array(
         'default' => FALSE,
       ),
+      'ajax_refresh_interval' => array(
+        'default' => 0,
+      ),
       'items_per_page' => array(
         'default' => 10,
       ),
@@ -631,7 +635,7 @@ class views_plugin_display extends views
         'category' => 'basic',
         'title' => t('Use AJAX'),
         'value' => $this->get_option('use_ajax') ? t('Yes') : t('No'),
-        'desc' => t('Change whether or not this display will use AJAX.'),
+        'desc' => t('Change whether and how this display will use AJAX.'),
       );
     }
 
@@ -803,6 +807,14 @@ class views_plugin_display extends views
           '#options' => array(1 => t('Yes'), 0 => t('No')),
           '#default_value' => $this->get_option('use_ajax') ? 1 : 0,
         );
+        $period = drupal_map_assoc(array(1, 2, 3, 5, 7, 10, 15, 20, 30, 45, 60, 180, 300), 'format_interval');
+        $form['ajax_refresh_interval'] = array(
+          '#type' => 'select',
+          '#title' => t('Refresh'),
+          '#description' => t('Set an interval at which this view should automatically refresh, or "None" for no automatic refreshing.'),
+          '#options' => array(0 => t('None')) + $period,
+          '#default_value' => $this->get_option('ajax_refresh_interval'),
+        );
         break;
       case 'use_pager':
         $form['#title'] .= t('Use a pager for this view');
@@ -1310,6 +1322,7 @@ class views_plugin_display extends views
         break;
       case 'use_ajax':
         $this->set_option($section, (bool)$form_state['values'][$section]);
+        $this->set_option('ajax_refresh_interval', intval($form_state['values']['ajax_refresh_interval']));
         break;
       case 'use_pager':
         $this->set_option($section, $form_state['values'][$section]);
@@ -1588,6 +1601,7 @@ class views_plugin_display extends views
    */
   function pre_execute() {
     $this->view->set_use_ajax($this->use_ajax());
+    $this->view->set_ajax_refresh_interval($this->get_option('ajax_refresh_interval'));
     // Copy pager information from the display.
     $this->view->set_use_pager($this->use_pager());
     $this->view->set_pager_element($this->get_option('pager_element'));
Index: theme/theme.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/theme.inc,v
retrieving revision 1.65
diff -u -p -r1.65 theme.inc
--- theme/theme.inc	2 Dec 2008 22:17:42 -0000	1.65
+++ theme/theme.inc	6 Dec 2008 07:00:20 -0000
@@ -131,7 +131,7 @@ function template_preprocess_views_view(
       'views' => array(
         'ajax_path' => url('views/ajax'),
         'ajaxViews' => array(
-          array(
+          $vars['dom_id'] => array(
             'view_name' => $view->name,
             'view_display_id' => $view->current_display,
             'view_args' => implode('/', $view->args),
@@ -140,6 +140,8 @@ function template_preprocess_views_view(
             // To fit multiple views on a page, the programmer may have
             // overridden the display's pager_element.
             'pager_element' => $view->pager['element'],
+            // Data are in seconds, but the Javascript expects milliseconds.
+            'ajax_refresh_interval' => $view->ajax_refresh_interval * 1000,
           ),
         ),
       ),
