Currently you simply can't have exposed filters on a block as long you don't have ajax enabled.
The problem is that exposed filters need a path, though blocks don't have one.

The goal is to add a new checkbox which allows to enable exposed filters on blocks but just use the current url as the path of the form.
This checkbox should have a detailed explanation why you maybe not want this and you absolute know what you are doing etc.

I'm not sure whether this task can really be seen as "novice" task, though it's a really helpful feature for some users.
Please post a comment if you plan to work on this issue and assign the issue to yourself.

Comments

Fidelix’s picture

Assigned: Unassigned » Fidelix

After having a conversation with Dereine and solving some doubts on IRC, I'll try to create a 2 patches:

Patch 1 - Small and good enough to go in: it simply removes the limitation and uses the current URL as the path for the exposed block. It also presents a warning checkbox.

Patch 2 - Allows the user to set the path of the display INSIDE the display's "Exposed form options", for any kind of display.

Fidelix’s picture

Here is patch 1. Needs tests.

If it works, I will clean it a little more and create Patch 2.

Fidelix’s picture

Status: Active » Needs work
StatusFileSize
new5.72 KB

Opera and d.o file uploads don't like each other...

dawehner’s picture

+++ b/plugins/views_plugin_display.incundefined
@@ -713,16 +713,6 @@ class views_plugin_display extends views_plugin {
   /**
-   * Check to see if the display can put the exposed formin a block.
-   *
-   * By default, displays that do not have a path cannot disconnect
-   * the exposed form and put it in a block, because the form has no
-   * place to go and Views really wants the forms to go to a specific
-   * page.
-   */
-  function uses_exposed_form_in_block() { return $this->has_path(); }

Let's keep it for the moment but return TRUE all the time, by default, maybe there are displays which definitive shouldn't have this feature and additional removing a function maybe breaks some custom/other contrib code, you never know.

+++ b/plugins/views_plugin_display.incundefined
@@ -2012,11 +2000,18 @@ class views_plugin_display extends views_plugin {
+        $form['exposed_block'] = $this->has_path() ? $exposed_form_with_path : $exposed_form_without_path; ¶

This is kind of confusing, wouldn't it be possible to just wrap the code with an if(...)

Thanks for working on this patch!

Fidelix’s picture

Absolutely.

Like this?

        if ($this->has_path()) {
         $form['exposed_block'] = $exposed_form_with_path;
        }
        else {
          $form['exposed_block'] = $exposed_form_without_path; 
        }

Or would you prefer it like this?


        if ($this->has_path()) {
          $form['exposed_block'] = array(
            '#type' => 'radios',
            '#options' => array(1 => t('Yes'), 0 => t('No')),
            '#default_value' => $this->get_option('exposed_block') ? 1 : 0,
          );
        }
        else {
          $form['exposed_block'] = array(
            '#type' => 'checkbox',
            '#title' => 'Yes, <strong>I understand that this display doesn\'t have a path</strong>, and the exposed filters will not work as expected',
            '#description' => 'This display doesn\'t have a working path. It does not work as most people would expect. Mark this option if you have a use for it anyway.',
            '#default_value' => $this->get_option('exposed_block') ? 1 : 0,
          );
        }

dawehner’s picture

The second one seems to be a bit easier to understand.

Fidelix’s picture

Revised patch.

dagmar’s picture

+++ b/views.module
@@ -1917,8 +1917,9 @@ function views_exposed_form($form, &$form_state) {
+  //dpm($view->get_url());

Remove this.

Also remember to change the status to 'Needs Review' every time you post a new patch.

Fidelix’s picture

dagmar, thanks for remembering.

I had the intention to remove this after someone tested it. But I will do so now.

Fidelix’s picture

Status: Needs work » Needs review
StatusFileSize
new5.5 KB

Here it goes. Simply removed the dpm() line.

dagmar’s picture

Status: Needs review » Needs work
+++ b/views.module
@@ -1603,7 +1603,6 @@ function views_debug($message, $placeholders = array()) {
-      dpm($output);

Mmm. This shouldn't be removed. This dpm is part of the view_debug function.

dagmar’s picture

+++ b/plugins/views_plugin_display.inc
@@ -2012,11 +2010,21 @@ class views_plugin_display extends views_plugin {
+          $form['exposed_block'] = array(
+            '#type' => 'checkbox',
+            '#title' => 'Yes, <strong>I understand that this display doesn\'t have a path</strong>, and the exposed filters will not work as expected',
+            '#description' => 'This display doesn\'t have a working path. It does not work as most people would expect. Mark this option if you have a use for it anyway.',
+            '#default_value' => $this->get_option('exposed_block') ? 1 : 0,

Also, the strings used in '#title' => and '#description' => cannot be translated at this momment. Wrap the strings using the t() function.

Fidelix’s picture

Status: Needs work » Needs review
StatusFileSize
new5.23 KB

dagmar, I only did that so it doesn't add "to-be-changed" strings on people's database.

I suppose that people messing with patches should expect that, hehee. sorry.

dawehner’s picture

Status: Needs review » Needs work

Here is a follow up issue which really confused me while reviewing this patch: #1444972: Allow displays to decide whether they want to add special blocks

+++ b/views.moduleundefined
@@ -1917,8 +1917,8 @@ function views_exposed_form($form, &$form_state) {
+  $action_url = (!empty($display->display_options['path'])) ? $view->get_url() : current_path();

I fear this will break some custom code. Many people use the $view object to set $view->override_url to get the exposed block acting on a certain page. Maybe you could use views_plugin_dispaly::get_path to achieve this behavior.

The rest looks definitive RTBC.

Fidelix’s picture

dereine, you're right.

I want to leave room for a feature where a user may force and set the block path IF $this->get_option('exposed_block') == 1
Would something like this work?

  /**
   * In some occasions, a block display may want a path.
   */
  function get_path() {
    if (empty($this->options['path'])) {
      return current_path();
    }
    else {
      return $this->get_option('path');
    }
  }
dawehner’s picture

Sadly not really. People use both override_url and override_path to override what they need. They still have to work as before, because changing here will for example break afaik commerce, which are 10k installations.

Fidelix’s picture

How about this, on views_plugin_exposed_form.inc:

  /**
   * 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->view,
      'display' => &$this->display,
      'method' => 'get',
      'rerender' => TRUE,
      'no_redirect' => TRUE,
      'always_process' => 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->view->display_handler->displays_exposed() || (!$block && $this->view->display_handler->get_option('exposed_block'))) {
      unset($form_state['rerender']);
    }

    if (!empty($this->ajax)) {
      $form_state['ajax'] = TRUE;
    }
    
    // The exposed form always needs an action URL.
    if (!empty($view->override_url)){
      $form['#action'] = $view->override_url;
    }
    elseif (!empty($display->display_options['path'])) {
      $form['#action'] = $display->display_options['path'];
    }
    elseif ($view->get_url()) {
      $form['#action'] = $view->get_url();
    }
    else {
      $form['#action'] = current_path();
    }
    
    $form_state['exposed_form_plugin'] = $this;
    $form = drupal_build_form('views_exposed_form', $form_state);
    $output = drupal_render($form);

    if (!$this->view->display_handler->displays_exposed() || (!$block && $this->view->display_handler->get_option('exposed_block'))) {
      return "";
    }
    else {
      return $output;
    }
  }
barraponto’s picture

In the meanwhile, can we get a warning telling users that their settings (exposed forms on view blocks with ajax disabled) will not result in the expected behavior? Because this is a recurring issue, we should try to mitigate it while we fix it.

Of course, I'm all for fixing it.

spgd01’s picture

Issue summary: View changes

A warning would be very helpful

amit0212’s picture

To add exposed form in block follow these step:

1)First add view in page
2)Then add required fields and filters as per your requirements
3)Under Advanced section Look at Exposed Form and set the link to Yes while clicking on Exposed form in block: option and save it.
4)Now goto admin/structure/blocks and see your newly created exposed form block listed under Disable blocks region. Now You can configure it and show on desired page.

damienmckenna’s picture

Assigned: Fidelix » Unassigned

FYI the "assigned" field is for indicating that you're actively working on an issue, if you're not actively working on an issue please leave it set to "unassigned". Thank you.