Commit 2b9f8d5a authored by merlinofchaos's avatar merlinofchaos

#115949: (by Nedjo) Allow use if AJAX paging with exposed filters and pager.

parent ed12c39b
......@@ -2034,7 +2034,7 @@ function views_ui_disable_page($view) {
* Page callback for the tools - other page
*/
function views_ui_admin_tools() {
return array('markup' => array('#value' => t('This page is not yet implemented.')));
return t('This page is not yet implemented. But try the convert tool.');
}
/**
......
......@@ -21,6 +21,7 @@ function views_views_plugins() {
'no ui' => TRUE,
'no remove' => TRUE,
'js' => array('misc/collapse.js', 'misc/textarea.js', 'misc/tabledrag.js', 'misc/autocomplete.js', "$path/dependent.js"),
'use ajax' => TRUE,
'use pager' => TRUE,
),
'page' => array(
......@@ -28,6 +29,7 @@ function views_views_plugins() {
'help' => t('Display the view as a page, with a URL and menu links.'),
'handler' => 'views_plugin_display_page',
'uses hook menu' => TRUE,
'use ajax' => TRUE,
'use pager' => TRUE,
),
'block' => array(
......@@ -35,6 +37,8 @@ function views_views_plugins() {
'help' => t('Display the view as a block.'),
'handler' => 'views_plugin_display_block',
'uses hook block' => TRUE,
'use ajax' => TRUE,
'use pager' => TRUE,
),
),
'style' => array(
......@@ -177,6 +181,16 @@ class views_plugin_display extends views_object {
return $this->has_exposed;
}
/**
* Does the display use AJAX?
*/
function use_ajax() {
if (!empty($this->definition['use ajax'])) {
return $this->get_option('use_ajax');
}
return FALSE;
}
/**
* Does the display have a pager enabled?
*/
......@@ -198,6 +212,7 @@ class views_plugin_display extends views_object {
'header' => array('header', 'header_format', 'header_empty'),
'footer' => array('footer', 'footer_format', 'footer_empty'),
'empty' => array('empty', 'empty_format'),
'use_ajax' => array('use_ajax'),
'items_per_page' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
'use_pager' => array('items_per_page', 'offset', 'use_pager', 'pager_element'),
'link_display' => array('link_display'),
......@@ -249,6 +264,7 @@ class views_plugin_display extends views_object {
'empty' => TRUE,
'empty_format' => TRUE,
'use_ajax' => TRUE,
'items_per_page' => TRUE,
'offset' => TRUE,
'use_pager' => TRUE,
......@@ -442,12 +458,19 @@ class views_plugin_display extends views_object {
$options['row_plugin']['links']['row_options'] = t('Settings');
}
}
if (!empty($this->definition['use ajax'])) {
$options['use_ajax'] = array(
'category' => 'basic',
'title' => t('Use AJAX'),
'value' => $this->get_option('use_ajax') ? t('Yes') : t('No'),
);
}
if (!empty($this->definition['use pager'])) {
$options['use_pager'] = array(
'category' => 'basic',
'title' => t('Use pager'),
'value' => $this->get_option('use_pager') ? t('Yes') : t('No'),
'value' => $this->get_option('use_pager') ? ($this->get_option('use_pager') ? t('Mini') : t('Yes')) : t('No'),
);
}
$options['items_per_page'] = array(
......@@ -575,11 +598,24 @@ class views_plugin_display extends views_object {
'#default_value' => $this->get_option('title'),
);
break;
case 'use_ajax':
$form['#title'] .= t('Use AJAX when available to load this view');
$form['description'] = array(
'#prefix' => '<div class="description form-item">',
'#suffix' => '</div>',
'#value' => t('If set, this view will use an AJAX mechanism for paging, table sorting and exposed filters. This means the entire page will not refresh. It is not recommend that you use this if this view is the main content of the page, but it is very useful for side content.'),
);
$form['use_ajax'] = array(
'#type' => 'radios',
'#options' => array(1 => t('Yes'), 0 => t('No')),
'#default_value' => $this->get_option('use_ajax'),
);
break;
case 'use_pager':
$form['#title'] .= t('Use a pager for this view');
$form['use_pager'] = array(
'#type' => 'radios',
'#options' => array(1 => t('Yes'), 0 => t('No')),
'#options' => array(1 => t('Full pager'), 'mini' => t('Mini pager'), 0 => t('No')),
'#default_value' => $this->get_option('use_pager'),
);
$form['pager_element'] = array(
......@@ -793,6 +829,7 @@ class views_plugin_display extends views_object {
case 'access':
case 'link_display':
case 'php_arg_code':
case 'use_ajax':
$this->set_option($section, $form_state['values'][$section]);
break;
case 'use_pager':
......@@ -997,6 +1034,7 @@ class views_plugin_display extends views_object {
* overridden on an individual display.
*/
function pre_execute() {
$this->view->set_use_ajax($this->use_ajax());
// Copy pager information from the display.
$this->view->set_use_pager($this->use_pager());
$this->view->set_pager_element($this->get_option('pager_element'));
......
......@@ -27,6 +27,8 @@ class view extends views_db_object {
var $args = array();
var $build_info = array();
var $use_ajax = FALSE;
// pager variables
var $pager = array(
'use_pager' => FALSE,
......@@ -84,6 +86,13 @@ class view extends views_db_object {
$this->pager['items_per_page'] = $items_per_page;
}
/**
* Whether or not AJAX should be used.
*/
function set_use_ajax($use_ajax) {
$this->use_ajax = $use_ajax;
}
/**
* Whether or not the pager should be used.
*/
......
// $Id$
/**
* @file ajax.inc
*
* Handles AJAX submission and response in Views UI.
*/
* @file ajax_admin.js
*
* Handles AJAX submission and response in Views UI.
*/
Drupal.Views.Ajax = {};
Drupal.Views.Ajax = Drupal.Views.Ajax || {};
/**
* Handles the simple process of setting the ajax form area with new data.
......
......@@ -3,7 +3,6 @@ Drupal.Views = {};
/**
* jQuery UI tabs, Views integration component
*/
Drupal.behaviors.viewsTabs = function (context) {
if ($.ui && $.ui.tabs) {
$('#views-tabset:not(.views-processed)').addClass('views-processed').tabs({
......@@ -20,3 +19,36 @@ Drupal.behaviors.viewsTabs = function (context) {
return false;
});
}
/**
* Helper function to parse a querystring.
*/
Drupal.Views.parseQueryString = function (query) {
var args = {};
var pos = query.indexOf('?');
if (pos != -1) {
query = query.substring(pos + 1);
}
var pairs = query.split('&');
for(var i in pairs) {
var pair = pairs[i].split('=');
// Ignore the 'q' path argument, if present.
if (pair[0] != 'q') {
args[pair[0]] = unescape(pair[1].replace(/\+/g, ' '));
}
}
return args;
};
/**
* Helper function to return the last portion of a class.
*/
Drupal.Views.getClassSuffix = function (elt, prefix) {
var className = elt.className.split(' ');
for (var i in className) {
if (className[i].indexOf(prefix) == 0) {
return className[i].substring(prefix.length);
}
}
return false;
};
\ No newline at end of file
......@@ -26,6 +26,8 @@ function template_preprocess_views_view(&$vars) {
$vars['rows'] = $view->style_handler->render($view->result);
$vars['css_name'] = views_css_safe($view->name);
$vars['name'] = $view->name;
$vars['display_id'] = $view->current_display;
if (!$vars['rows']) {
$vars['empty'] = $view->display_handler->render_empty();
......@@ -53,9 +55,29 @@ function template_preprocess_views_view(&$vars) {
$vars['pager'] = '';
if (!empty($view->pager['use_pager'])) {
$vars['pager'] = theme('pager', $view->exposed_input, $view->pager['items_per_page'], $view->pager['element']);
$pager_type = $view->pager['use_pager'] == 'mini' ? 'views_mini_pager' : 'pager';
$vars['pager'] = theme($pager_type, $view->exposed_input, $view->pager['items_per_page'], $view->pager['element']);
}
// If using AJAX, send identifying data about this view.
if ($view->use_ajax) {
$settings = array(
'views' => array(
'ajax_path' => url('views/ajax'),
'ajaxViews' => array(
array(
'view_name' => $view->name,
'view_display_id' => $view->current_display,
'view_args' => implode('/', $view->args),
'view_path' => $_GET['q'],
),
),
),
);
drupal_add_js($settings, 'setting');
views_add_js('ajax_view');
}
}
/**
......@@ -236,6 +258,41 @@ function template_preprocess_views_exposed_form(&$vars) {
$vars['button'] = drupal_render($form);
}
function theme_views_mini_pager($tags = array(), $limit = 10, $element = 0, $parameters = array(), $quantity = 9) {
global $pager_page_array, $pager_total;
// Calculate various markers within this pager piece:
// Middle is used to "center" pages around the current page.
$pager_middle = ceil($quantity / 2);
// current is the page we are currently paged to
$pager_current = $pager_page_array[$element] + 1;
// max is the maximum page number
$pager_max = $pager_total[$element];
// End of marker calculations.
$li_previous = theme('pager_previous', (isset($tags[1]) ? $tags[1] : t('‹‹')), $limit, $element, 1, $parameters);
$li_next = theme('pager_next', (isset($tags[3]) ? $tags[3] : t('››')), $limit, $element, 1, $parameters);
if ($pager_total[$element] > 1) {
$items[] = array(
'class' => 'pager-previous',
'data' => $li_previous,
);
$items[] = array(
'class' => 'pager-current',
'data' => t('Page @current of @max', array('@current' => $pager_current, '@max' => $pager_max)),
);
$items[] = array(
'class' => 'pager-next',
'data' => $li_next,
);
return theme('item_list', $items, NULL, 'ul', array('class' => 'pager'));
}
}
/**
* @defgroup views_templates Views' template files
*/
......@@ -16,7 +16,7 @@
* @ingroup views_templates
*/
?>
<div class="view view-<?php print $css_name; ?>">
<div class="view view-<?php print $css_name; ?> view-id-<?php print $name; ?> view-display-id-<?php print $display_id; ?>">
<?php if ($header): ?>
<div class="view-header">
<?php print $header; ?>
......
......@@ -14,12 +14,18 @@ function views_theme() {
$path = drupal_get_path('module', 'views');
require_once "./$path/theme/theme.inc";
// Some quasi clever array merging here.
// Some quasi clever array merging here.
$base = array(
'file' => 'theme.inc',
'path' => "$path/theme",
);
// Our extra version of pager from pager.inc
$hooks['views_mini_pager'] = $base + array(
'arguments' => array('tags' => array(), 'limit' => 10, 'element' => 0, 'parameters' => array()),
);
$arguments = array(
'display' => array('view' => NULL),
'style' => array('view' => NULL, 'options' => NULL, 'rows' => NULL),
......@@ -110,6 +116,14 @@ function views_menu() {
$items += $result;
}
}
$items['views/ajax'] = array(
'title' => t('Views'),
'page callback' => 'views_ajax',
'access callback' => 'user_access',
'access arguments' => array('access content'),
'description' => t('Ajax callback for view loading.'),
'type' => MENU_CALLBACK,
);
return $items;
}
......@@ -248,6 +262,55 @@ function views_access($view, $account = NULL) {
return $view->access($display_id, $account);
}
/**
* Menu callback to load a view via AJAX.
*/
function views_ajax() {
if (isset($_REQUEST['view_name']) && isset($_REQUEST['view_display_id'])) {
$name = $_REQUEST['view_name'];
$display_id = $_REQUEST['view_display_id'];
$args = isset($_REQUEST['view_args']) ? explode('/', $_REQUEST['view_args']) : array();
$path = isset($_REQUEST['view_path']) ? $_REQUEST['view_path'] : NULL;
views_include('ajax');
$object = new stdClass();
$object->status = FALSE;
$object->display = '';
// Load the view.
if ($v = views_get_view($name)) {
$view = drupal_clone($v);
if ($view->access($display_id)) {
// Fix 'q' for paging.
if (!empty($path)) {
$_GET['q'] = $path;
}
$errors = $view->validate();
if ($errors === TRUE) {
$object->status = TRUE;
$object->title = $view->get_title();
$object->display .= $view->preview($display_id, $args);
}
else {
foreach ($errors as $error) {
drupal_set_message($error, 'error');
}
}
// Register the standard JavaScript callback.
$object->__callbacks = array('Drupal.Views.Ajax.ajaxViewResponse');
// Allow other modules to extend the data returned.
drupal_alter('ajax_data', $object, 'views', $view);
}
}
$messages = theme('status_messages');
$object->messages = $messages ? '<div class="views-messages">'. $messages .'</div>' : '';
views_ajax_render($object);
}
}
/**
* Set the current 'page view' that is being displayed so that it is easy
* for other modules or the theme to identify.
......@@ -1074,6 +1137,10 @@ function views_exposed_form(&$form_state) {
$form['#theme'] = views_theme_functions('views_exposed_form', $view, $display);
// If using AJAX, we need the form plugin.
if ($view->use_ajax) {
drupal_add_js('misc/jquery.form.js');
}
views_add_js('dependent');
return $form;
}
......@@ -1136,3 +1203,4 @@ function views_views_query_substitutions($view) {
global $language;
return array('***CURRENT_TIME***' => time(), '***CURRENT_LANGUAGE***' => $language->language);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment