case is simple enough to imagine: views_field_view generates multiple instances of the same view, each having an exposed filter form on it. Currently, the logic for generating the form_id for each form is based on two input criteria: $view->name and $view->current_display->id. Drupal.behaviors.ViewsAjaxView iterates over each view and attempts to find and bind the ajax callback logic based on that form id. since the form id is repeated exactly across each instance of the form, all those attempts bind only to the first form instance. the rest behave as if there's no ajax at all (which typically means redirecting to either the linked page display or the homepage).

the attached patch further differentiates the form's id based on $view->dom_id, which was designed specifically for this sort of purpose - multiple instances of the same view on the same page. it also makes the concomitant changes to the binding logic.

there are two problems with it:

  • views_exposed_form_cache() is not designed to have this third dimension of variation. i don't see it being used anywhere else in views, so we could probably safely just insert the third parameter, but as it stands the patch simply sticks $view->dom_id onto the display id. adding a third parameter isn't necessarily without problems though, because...
  • i don't know by when $view->dom_id is reliably generated. i DO know, however, that there's logic in template_preprocess_views_view that generates a dom_id if one isn't set - and it does so with a call to rand(), so it can't be predicted. presumably that logic is there because there's a chance the dom_id ISN'T set...in which case, the ajaxing will fail because the dom_id we stuck on to the form_id will be empty, and we'll have sent something giant to Drupal.settings.

it does seem worth it to me that this goes in, but we need to address these concerns before it can.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

i don't know by when $view->dom_id is reliably generated. i DO know, however, that there's logic in template_preprocess_views_view that generates a dom_id if one isn't set - and it does so with a call to rand(), so it can't be predicted. presumably that logic is there because there's a chance the dom_id ISN'T set...in which case, the ajaxing will fail because the dom_id we stuck on to the form_id will be empty, and we'll have sent something giant to Drupal.settings.

So the general workflow is the following:

  1. If there is no dom_id set (which would be done by custom code in the first place) generate a random one.
  2. this dom_id is stored during multiple ajax requests, so it will keep the same.

Some time ago the dom_id had some deterministic behavior, though this lead to edge-case problems like: what happens if you have the same display displayed multiple times per page etc.

The only problem, which is somehow by design of your patch, is the changed ID and people still rely on the ID to style their exposed forms. I'm not sure how to interact with that problem.

blackandcode’s picture

I have same problems with views. Is there any solution for this so far? This is very big problem

Dumitru Grosul’s picture

Category: feature » bug
FileSize
1.02 KB

Hi sdboyer,

I also encountered this issue.
I am attaching the patch that has a much simpler solution and it does not generate the two problems you noted.

Dumitru Grosul’s picture

Status: Active » Needs review

Changing to needs review.

dawehner’s picture

One problem is patch might cause is when the exposed form is not part of the actual view but located in an external block or used somewhere in a panel.

hefox’s picture

hefox’s picture

sdboyer's patch is applying fine for me, so not sure what's up with test bot.

I favour sbdoyer's more extension approach as I'm having issues with the cache being shared among two view panes of the same pane type that have different settings (which effect how the exposed filters display), and this patch looks to fix that.

hefox’s picture

Updating boyer's patch to fix undefined views_dom_id to => view_dom_id in ajax.inc

mpotter’s picture

Status: Needs review » Reviewed & tested by the community

Been using #8 in Open Atrium 2 for a while. Fixes the issue and haven't seen any side effects.

PlayfulWolf’s picture

Is it correct that this issue is to solve the same problem as MEFIBS module?
I gave that module a try - it works in my case.
https://drupal.org/project/mefibs

juhaniemi’s picture

#8 tested and works in most cases. This patch however generates Notice: Undefined property: view::$dom_id PHP notices in Search API Views but I'm not sure if this report should go to Search API issues.

bpadaria’s picture

#8 works for me too.

Thanks

SocialNicheGuru’s picture

I think this might have to be rerolled against the latest dev.

http://cgit.drupalcode.org/views/commit/?id=710a536

bmunslow’s picture

Patch #8 doesn't work in combination with Better Exposed Filters, reported in BEF issues queue.

hefox’s picture

Part of patch doesn't apply, but that part looks like doesn't matter anymore, so here's a new patch

mstrelan’s picture

Status: Reviewed & tested by the community » Needs work

Testing #15 it seems that $view->dom_id is not set when "exposed form in block" is checked. Also the form elements don't get unique ids, only the form itself. I have <input id="edit-keys"> twice, and that's causing issues with search_api_autocomplete.

The issue of unique ids seems to be caused by drupal_process_form() calling drupal_static_reset('drupal_html_id'). This is because $form_state['process_input'] is always TRUE for exposed forms, because views_plugin_exposed_form::render_exposed_form() sets $form_state['always_process'] = TRUE.

So I believe either views needs to find a way to not always process form input, or core needs a way to not reset the static cache of drupal_html_id.

eyilmaz’s picture

Updated #15.
Create the dom_id, if its not set.

A----’s picture

Patches #15 and #17 do not work anymore since 96a54e041b171eb47c6a00805b9c4731c81d9283 revert commit ( Issue #1809958 by joelpittet, steve.stotter, alesr, klaasvw: Views with exposed filter (ajax enabled) inside modal window (ctools) ).

Please also check issue 1809958.

Martin.’s picture

A very nasty workaround for the problem in #16

Before you call out your view

$ids = &drupal_static('drupal_html_id');
$tmp = $ids;

As soon as your view has rendered

$ids = $tmp;

Full example

  $ids = &drupal_static('drupal_html_id');
  $tmp = $ids;
  $display_id = 'block_1';
  $view = views_get_view('my_view_name');
  $view->set_display($display_id);
  $view->pre_execute();
  $view->execute();
  $ids = $tmp;

Note that there is much room for error but you can use this as a last resort.

NB! Use at your own risk

godotislate’s picture

I needed the JS selector change in #8 added to #17 to get it to work.

hmdnawaz’s picture

After applying the patch # 17 and # 20, the views ajax is not working anymore. I have enabled the ajax in the views settings but it is not working.

hmdnawaz’s picture

Any solution for this problem? Its a very critical issue and did not solve from the 4 years.

hmdnawaz’s picture

Priority: Normal » Critical
dawehner’s picture

Priority: Critical » Major

Any solution for this problem? Its a very critical issue and did not solve from the 4 years.

How is this really critical? For me critical means that a site is broken, which in this case could be resolved by not applying the patch or exposing the same exposed form twice.

thepractice’s picture

This patch updates patch #20 to work with Views 7.x-3.16.

ciss’s picture

Status: Needs work » Needs review

markdc’s picture

I've tested #25 in VIews 3.16 and 3.18. Multiple filters in an AJAX view are working as expected now. Thanks for this!!

ciss’s picture

Rerolled #25 against 7.x-3.x (a5caa46).

idebr’s picture

Note: if you are using the Entity Reference View Widget module, you need a patch to make it compatible. See #2969254: Make Entity Reference View Widget compatible with 'Allow multiple instances of the same exposed filter form on a single page'

Hauke von Quillfeldt’s picture

mpotter’s picture

Rerolled #31 against 7.x-3.22 (for Panopoly 1.72 and OpenAtrium)

DamienMcKenna’s picture

If this is working for folks on large sites & distros, might someone be willing to RTBC it?

ciss’s picture

Hiding #32 since it was rerolled against an old release. Hiding #20 because it has already been rerolled in #31.

ciss’s picture

Aethyx’s picture

We've applied patch #31 in our codebase and rolled it out to multiple platforms without issues. I don't know if that counts as RTBC but woud love to see this issue move forward!

Taran2L’s picture

If the exposed form is displayed as a block, $view dom IDs will be different between the exposed form and the view, because the $view object will be instantiated from scratch thus, dom ID won't be preserved:

826 // This indicates it's a special one.
827 if (substr($delta, 0, 1) == '-') {
828   list($nothing, $type, $name, $display_id) = explode('-', $delta);
829   // Put the - back on.
830   $type = '-' . $type;
831   if ($view = views_get_view($name)) {
832     if ($view->access($display_id)) {
833       $view->set_display($display_id);
834       if (isset($view->display_handler)) {
835         $output = $view->display_handler->view_special_blocks($type);
836         // Before returning the block output, convert it to a renderable
837         // array with contextual links.
838         views_add_block_contextual_links($output, $view, $display_id, 'special_block_' . $type);
839         $view->destroy();
840         return $output;
841       }
842     }
843     $view->destroy();
844   }
845 }
solideogloria’s picture

Status: Needs review » Needs work