summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEarl Miles2008-09-29 23:56:29 (GMT)
committer Earl Miles2008-09-29 23:56:29 (GMT)
commit84809badf76b2cc834dfc0b151fc5bb908d1582d (patch)
tree16b5a01a11d5033f51e7e375fe3ebbf8fd16b377
parentf25f460298aa721b47633cf55112e90cddcd7d1b (diff)
Since it's not easily possible to do the views filter block externally, bring the functionality directly into Views, including modifying the ajax for that to work.
-rw-r--r--includes/view.inc62
-rw-r--r--js/ajax_view.js81
-rw-r--r--modules/comment.views.inc2
-rw-r--r--plugins/views_plugin_display.inc63
-rw-r--r--views.module42
5 files changed, 178 insertions, 72 deletions
diff --git a/includes/view.inc b/includes/view.inc
index 4960cfe..3837ffb 100644
--- a/includes/view.inc
+++ b/includes/view.inc
@@ -371,6 +371,42 @@ class view extends views_db_object {
}
/**
+ * Render the exposed filter form.
+ *
+ * This actually does more than that; because it's using FAPI, the form will
+ * also assign data to the appropriate handlers for use in building the
+ * query.
+ */
+ function render_exposed_form($block = FALSE) {
+ // Deal with any exposed filters we may have, before building.
+ $form_state = array(
+ 'view' => &$this,
+ 'display' => &$this->display_handler->display,
+ 'method' => 'get',
+ 'rerender' => TRUE,
+ 'no_redirect' => TRUE,
+ );
+
+ // Some types of displays (eg. attachments) may wish to use the exposed
+ // filters of their parent displays instead of showing an additional
+ // exposed filter form for the attachment as well as that for the parent.
+ if (!$this->display_handler->displays_exposed() || (!$block && $this->display_handler->get_option('exposed_block'))) {
+ unset($form_state['rerender']);
+ }
+
+ if (!empty($this->ajax)) {
+ $form_state['ajax'] = TRUE;
+ }
+
+ $output = drupal_build_form('views_exposed_form', $form_state);
+ if (!empty($form_state['js settings'])) {
+ $this->js_settings = $form_state['js settings'];
+ }
+
+ return $output;
+ }
+
+ /**
* Build all the arguments.
*/
function _build_arguments() {
@@ -511,31 +547,9 @@ class view extends views_db_object {
$this->_pre_query();
if ($this->display_handler->uses_exposed()) {
- // Deal with any exposed filters we may have, before building.
- $form_state = array(
- 'view' => &$this,
- 'display' => &$this->display_handler->display,
- 'method' => 'get',
- 'rerender' => TRUE,
- 'no_redirect' => TRUE,
- );
-
- // Some types of displays (eg. attachments) may wish to use the exposed
- // filters of their parent displays instead of showing an additional
- // exposed filter form for the attachment as well as that for the parent.
- if (!$this->display_handler->displays_exposed()) {
- unset($form_state['rerender']);
- }
-
- if (!empty($this->ajax)) {
- $form_state['ajax'] = TRUE;
- }
-
- $this->exposed_widgets = drupal_build_form('views_exposed_form', $form_state);
- if (!empty($form_state['js settings'])) {
- $this->js_settings = $form_state['js settings'];
- }
+ $this->exposed_widgets = $this->render_exposed_form();
}
+
// Build all the relationships first thing.
$this->_build('relationship');
diff --git a/js/ajax_view.js b/js/ajax_view.js
index 1548a1c..fe08c73 100644
--- a/js/ajax_view.js
+++ b/js/ajax_view.js
@@ -47,51 +47,56 @@ Drupal.behaviors.ViewsAjaxView = function() {
}
if (Drupal.settings && Drupal.settings.views && Drupal.settings.views.ajaxViews) {
$.each(Drupal.settings.views.ajaxViews, function(i, settings) {
- var $view = $('.view-dom-id-' + settings.view_dom_id);
- if (!$view.size()) {
+ 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);
+ view = '.view-id-' + settings.view_name + '.view-display-id-' + settings.view_display_id;
}
- $view.filter(':not(.views-processed)').each(function() {
+
+ // Process exposed filter forms.
+ $('form#views-exposed-form-' + settings.view_name + '-' + settings.view_display_id)
+ .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('<input type="hidden" name="'+ key + '" value="'+ setting +'"/>');
+ });
+ })
+ .addClass('views-processed')
+ .submit(function () {
+ $('input[@type=submit]', this).after('<span class="views-throbbing">&nbsp</span>');
+ 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 ") + ajax_path); $('.views-throbbing', object).remove(); },
+ dataType: 'json'
+ });
+
+ return false;
+ });
+
+ $(view).filter(':not(.views-processed)').each(function() {
var target = this;
$(this)
.addClass('views-processed')
- // Process exposed filter forms.
- .find('form#views-exposed-form')
- .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('<input type="hidden" name="'+ key + '" value="'+ setting +'"/>');
- });
- })
- .submit(function () {
- $('input[@type=submit]', this).after('<span class="views-throbbing">&nbsp</span>');
- $(this).ajaxSubmit({
- url: ajax_path,
- type: 'GET',
- success: function(response) {
- // Call all callbacks.
- if (response.__callbacks) {
- $.each(response.__callbacks, function(i, callback) {
- eval(callback)(target, response);
- });
- }
- },
- error: function() { alert(Drupal.t("An error occurred at ") + ajax_path); },
- dataType: 'json'
- });
-
- return false;
- })
- .end()
// Process pager links.
.find('ul.pager > li > a')
.each(function () {
diff --git a/modules/comment.views.inc b/modules/comment.views.inc
index faa514f..d5faa9e 100644
--- a/modules/comment.views.inc
+++ b/modules/comment.views.inc
@@ -469,7 +469,7 @@ function comment_views_handlers() {
// argument handlers
'views_handler_filter_node_comment' => array(
- 'parent' => 'views_handler_argument',
+ 'parent' => 'views_handler_filter_in_operator',
),
'views_handler_argument_comment_user_uid' => array(
'parent' => 'views_handler_argument',
diff --git a/plugins/views_plugin_display.inc b/plugins/views_plugin_display.inc
index 5dcb2a4..042594f 100644
--- a/plugins/views_plugin_display.inc
+++ b/plugins/views_plugin_display.inc
@@ -158,6 +158,7 @@ class views_plugin_display extends views_plugin {
'use_more' => array('use_more'),
'link_display' => array('link_display'),
'distinct' => array('distinct'),
+ 'exposed_block' => array('exposed_block'),
// Force these to cascade properly.
'style_plugin' => array('style_plugin', 'style_options', 'row_plugin', 'row_options'),
@@ -228,6 +229,7 @@ class views_plugin_display extends views_plugin {
'pager_element' => TRUE,
'use_more' => TRUE,
'distinct' => TRUE,
+ 'exposed_block' => TRUE,
'link_display' => TRUE,
@@ -336,6 +338,10 @@ class views_plugin_display extends views_plugin {
'row_options' => array(
'default' => array(),
),
+
+ 'exposed_block' => array(
+ 'default' => FALSE,
+ ),
);
if ($this->is_default_display()) {
@@ -705,6 +711,13 @@ class views_plugin_display extends views_plugin {
}
}
+ $options['exposed_block'] = array(
+ 'category' => 'basic',
+ 'title' => t('Exposed form in block'),
+ 'value' => $this->get_option('exposed_block') ? t('Yes') : t('No'),
+ 'desc' => t('Allow the exposed form to appear in a block instead of the view.'),
+ );
+
foreach (array('header' => t('Header'), 'footer' => t('Footer'), 'empty' => t('Empty text')) as $type => $name) {
if (!$this->get_option($type)) {
$field = t('None');
@@ -788,7 +801,7 @@ 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'),
+ '#default_value' => $this->get_option('use_ajax') ? 1 : 0,
);
break;
case 'use_pager':
@@ -1181,6 +1194,20 @@ class views_plugin_display extends views_plugin {
);
$form_state['ok_button'] = TRUE;
break;
+
+ case 'exposed_block':
+ $form['#title'] .= t('Put the exposed form in a block');
+ $form['description'] = array(
+ '#prefix' => '<div class="description form-item">',
+ '#suffix' => '</div>',
+ '#value' => t('If set, any exposed widgets will not appear with this view. Instead, a block will be made available to the Drupal block administration system, and the exposed form will appear there. Note that this block must be enabled manually, Views will not enable it for you.'),
+ );
+ $form['exposed_block'] = array(
+ '#type' => 'radios',
+ '#options' => array(1 => t('Yes'), 0 => t('No')),
+ '#default_value' => $this->get_option('exposed_block') ? 1 : 0,
+ );
+ break;
}
}
@@ -1346,6 +1373,9 @@ class views_plugin_display extends views_plugin {
$this->set_option($section . '_empty', $form_state['values'][$section . '_empty']);
}
break;
+ case 'exposed_block':
+ $this->set_option($section, (bool) $form_state['values'][$section]);
+ break;
}
}
@@ -1614,6 +1644,37 @@ class views_plugin_display extends views_plugin {
}
return $errors;
}
+
+ /**
+ * Provide the block system with any exposed widget blocks for this display.
+ */
+ function get_special_blocks() {
+ $delta = '$exp-' . $this->view->name . '-' . $this->display->id;
+ $desc = t('Exposed form: @view-@display_id', array('@view' => $this->view->name, '@display_id' => $this->display->id));
+
+ return array(
+ $delta => array(
+ 'info' => $desc,
+ )
+ );
+ }
+
+ /**
+ * Render any special blocks provided for this display.
+ */
+ function view_special_blocks($type) {
+ if ($type == '$exp') {
+ // avoid interfering with the admin forms.
+ if (arg(0) == 'admin' && arg(1) == 'build' && arg(2) == 'views') {
+ return;
+ }
+ $this->view->init_handlers();
+ return array(
+ 'content' => $this->view->render_exposed_form(TRUE),
+ );
+ }
+ }
+
}
diff --git a/views.module b/views.module
index d93c3d3..bbbdec9 100644
--- a/views.module
+++ b/views.module
@@ -280,12 +280,23 @@ function views_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$items = array();
- $views = views_get_applicable_views('uses hook block');
- foreach ($views as $data) {
- list($view, $display_id) = $data;
- $result = $view->execute_hook_block($display_id);
- if (is_array($result)) {
- $items = array_merge($items, $result);
+ $views = views_get_all_views();
+ foreach ($views as $view) {
+ $view->init_display();
+ foreach ($view->display as $display_id => $display) {
+ if (isset($display->handler) && !empty($display->handler->definition['uses hook block'])) {
+ $result = $display->handler->execute_hook_block();
+ if (is_array($result)) {
+ $items = array_merge($items, $result);
+ }
+ }
+
+ if (isset($display->handler) && $display->handler->get_option('exposed_block')) {
+ $result = $display->handler->get_special_blocks();
+ if (is_array($result)) {
+ $items = array_merge($items, $result);
+ }
+ }
}
}
@@ -308,8 +319,7 @@ function views_block($op = 'list', $delta = 0, $edit = array()) {
variable_set('views_block_hashes', $hashes);
// Save memory: Destroy those views.
- foreach ($views as $data) {
- list($view, $display_id) = $data;
+ foreach ($views as $view) {
$view->destroy();
}
@@ -324,6 +334,20 @@ function views_block($op = 'list', $delta = 0, $edit = array()) {
}
}
+ // This indicates it's a special one.
+ if (substr($delta, 0, 1) == '$') {
+ list($type, $name, $display_id) = explode('-', $delta);
+ if ($view = views_get_view($name)) {
+ if ($view->access($display_id)) {
+ $view->set_display($display_id);
+ if (isset($view->display_handler)) {
+ $output = $view->display_handler->view_special_blocks($type);
+ return $output;
+ }
+ }
+ }
+ }
+
list($name, $display_id) = explode('-', $delta);
// Load the view
if ($view = views_get_view($name)) {
@@ -894,6 +918,8 @@ function views_exposed_form(&$form_state) {
$form['#action'] = url($view->get_url());
$form['#theme'] = views_theme_functions('views_exposed_form', $view, $display);
+ $form['#id'] = views_css_safe('views_exposed_form-' . check_plain($view->name) . '-' . check_plain($display->id));
+// $form['#attributes']['class'] = array('views-exposed-form');
// If using AJAX, we need the form plugin.
if ($view->use_ajax) {