1

I have a view showing a select list of locations. Upon selecting a location the View shows a Google Map with the locations of the current selection.

For certain items in the select list I would like to redirect away from the View to another page.

I have looked at these discussions:

https://www.drupal.org/node/1379492#comment-6273188

How to change programmatically exposed filters in views

But none of them mentions my specific case of conditional redirection.

Any clues very welcome!

  • Hey @benjamin_dk. For some of the values of the Select (exposed filter) you want to have a simple redirect, instead of the filter actually interacting with the (Google Map) view. Is that right? Have you thought of using a javascript approach? Are the filter changes auto-submitted in your view at the moment? – Stefanos Petrakis Apr 9 '16 at 8:14
  • Yes I just want a simple redirect and the form is autosubmitting. And yea at the moment I have a crude javascript function redirecting but this causes a brief flash of the unwanted view to be shown first. – benjamin_dk Apr 9 '16 at 8:19
  • FYI, I updated my answer below with a switch statement that focuses on your OP even more. Cheers! – Stefanos Petrakis Apr 9 '16 at 9:33
0

A sketch of an idea, for prototyping.
Once this works for you, you could move this javascript code into a render array via form alter. Here are some links for that:

Prototyping: Inside the header area of your view you can insert a js snippet inside of a 'Global: Text area' field (use the full html text format to avoid stripping of html tags):

enter image description here

And here is an example snippet to get you started, I am targeting the node's status exposed filter from my sample view:

<script>
(function($) {
  $( document ).ready(function() {
    $('#edit-status').change(function() {
      switch($(this).val()) {
        case 'optionA':
          window.location = "https://www.drupal.org";            
          break;
        case 'optionB':
        case 'optionC':
          // grouping option together if they have the same target url
          window.location = "https://petrakis.design";            
          break;
        default:
          // default code block, simply exit
      }
    });
  });
})(jQuery);
</script>

Hope this helped!

| improve this answer | |
  • Unfortunately this method does not fix the problem. Views still shows the filtered content for a moment before redirecting. – benjamin_dk Apr 13 '16 at 11:42
  • Your suggestions are valid in the sense that it adds the javascript to the form. Unfortunately these methods do not fix the problem. I tried both adding js in the 'Global: Text Area' and as attached element to the views exposed filter form. I shifted the js to the beginning of the attached js array. I don't know if it is relevant, but the filtered content is in an attachment. Completely removing the autosubmit.js file (ctools) does not work either, since I need the filter parameters from the URL in my redirect. – benjamin_dk Apr 13 '16 at 11:58
0

This is an alternative answer, not javascript based and much closer to the "best practices" way.

The most important piece of information lies inside the ctools/js/auto-submit.js file of CTools. This is the verbatim comment in the beginning of that file:

To make a form auto submit, all you have to do is 3 things:
ctools_add_js('auto-submit');

On gadgets you want to auto-submit when changed, add the ctools-auto-submit
class. With FAPI, add:

'#attributes' => array('class' => array('ctools-auto-submit')),

If you want to have auto-submit for every form element,
add the ctools-auto-submit-full-form to the form. With FAPI, add:

'#attributes' => array('class' => array('ctools-auto-submit- full-form')),

If you want to exclude a field from the ctool-auto-submit-full-form auto submission,
add the class ctools-auto-submit-exclude to the form element. With FAPI, add:

'#attributes' => array('class' => array('ctools-auto-submit-exclude')),

Finally, you have to identify which button you want clicked for autosubmit.
The behavior of this button will be honored if it's ajaxy or not:

'#attributes' => array('class' => array('ctools-use-ajax', 'ctools-auto-submit-click')),

Currently only 'select', 'radio', 'checkbox' and 'textfield' types are supported. We probably
could use additional support for HTML5 input types.

Following that, you need to implement a custom module and using _form_alter:

  1. Disable auto-submit for your exposed filter using the 'ctools-auto-submit-exclude' class
  2. Attach a javascript that will do something similar to the alternative answer's javascript, namely, redirect to another url.

In the following example code, I use a simple redirect based on an exposed filter of the basic content types, article and page. Tested and it worked!

A sample form_alter implementation:

function somemodule_form_views_exposed_form_alter(&$form, &$form_state, $form_id) {

  // This is the name of the FAPI exposed filter element
  $filter_exposed_select_name = 'type';

  // This is the name of the select values and their respective target url
  $target_urls = array(
    'page' => 'http://www.drupal.org',
    'article' => 'http://drupal.stackexchange.com'
  );


  // This will disable auto-submitting the form for our filter element
  $form[$filter_exposed_select_name]['#attributes'] = array('class' => array('ctools-auto-submit-exclude'));

  // This will attach a javascript to the element for handling the redirects
  $form[$filter_exposed_select_name]['#attached']['js'][] = drupal_get_path('module', 'somemodule') . '/somemodule.js';
  $form[$filter_exposed_select_name]['#attached']['js'][] = array(
    'data' => array(
      'bef_custom_redirect' => array(
        'target_name' => $filter_exposed_select_name,
        'target_urls' => $target_urls,
      )
    ),
    'type' => 'setting'
  );
}

and the accompanying javascript file (somemodule.js).

(function($){

Drupal.behaviors.BEFCustomRedirect = {
  attach: function(context, settings) {
    $('.ctools-auto-submit-exclude.form-select[name=' + settings.bef_custom_redirect.target_name + ']').change(function() {
      window.location = settings.bef_custom_redirect.target_urls[$(this).val()];
    });
  }
}

})(jQuery);

Hope this does the trick for you, let me know how it went!

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.