The Needs Review Queue Bot → tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide → to find step-by-step guides for working with issues.
- Status changed to Needs work
almost 2 years ago 1:33pm 19 June 2023 - Status changed to Needs review
almost 2 years ago 1:34pm 19 June 2023 - last update
almost 2 years ago 29,499 pass, 1 fail - Status changed to Needs work
almost 2 years ago 2:08pm 19 June 2023 - 🇺🇸United States smustgrave
Was previously tagged for tests which still need to happen.
- First commit to issue fork.
- Merge request !57303032353: Patched views per https://www.drupal.org/node/3032353. → (Open) created by cobadger
- First commit to issue fork.
- Status changed to Needs review
over 1 year ago 1:15am 10 February 2024 - 🇺🇸United States cobadger
Re-rolled patch for 10.2.x and added test coverage.
- Status changed to Needs work
over 1 year ago 4:35pm 12 February 2024 - 🇺🇸United States smustgrave
Tests should be added to the MR. But it needs to be cleaned up as there are now a mix of patches and MRs with no explanation or interdiffs between them.
Also issue summary should follow standard issue template.
- 🇧🇪Belgium p-neyens
New patch starting from comment 42 ✨ Exposed forms in a block are not currently updated when Ajax filtering is executed Needs work but with adding the missing use.
Error: Class "Drupal\views\Controller\RenderContext" not found in Drupal\views\Controller\ViewAjaxController->ajaxView() (regel 222 van /var/app/web/core/modules/views/src/Controller/ViewAjaxController.php). Error: Class "Drupal\views\Controller\BubbleableMetadata" not found in Drupal\views\Controller\ViewAjaxController->ajaxView()
- 🇧🇬Bulgaria SimeonKesmev
There are instances where the form ID can have uniquifying suffix, so here is a change to account for that.
The whole approach looks fragile to me as in theory there can be multiple blocks on the page.
Also I have problem with the facets as the parameter "exposed_form_display" does not get attached, as commented in #28. What is the use case for it? - 🇺🇦Ukraine khiminrm
I've fixed bug with empty "exposed_form_display" mentioned in #45
- 🇺🇦Ukraine khiminrm
Noticed bug. when after last the patch the exposed filter block has been refreshed - the exposed form is not submitted by Ajax second time - with page reload.
- 🇺🇦Ukraine khiminrm
I've improved a little the exposed form selector to be more precise.
- 🇺🇦Ukraine khiminrm
And updated selector in javascript in case if there are multiple exposed forms for the same view on one page
- 🇨🇿Czech Republic David Urban
I have tested #49 patch with Core 11.1.1 BEF 7.0.5 and Facets 3.0.0. It fixes the issue with Facets not updating after selecting one.
But it creates another issue in which View Footer and Pagination gets multiplied on every Ajax update. Is there any chance you could have a look at it please?
- 🇺🇦Ukraine khiminrm
@david-urban
I didn't notice such bug, but I haven't not tested on Core 11.x yet.
Maybe try to check template for the view. It could be that footer and pagination are outside the view's main 'div' wrapper.
You can check also ViewAjaxController how it replaces content during ajax call so you will have idea what actually is replaced on a page.I've another one bug https://www.drupal.org/node/3163299 → and those patch conflicts with this one in similar lines of code. Have not tried yet though. Trying to compare both patches. I hope those issue's patch will work for all cases.
- 🇺🇦Ukraine khiminrm
When using multiple instances of the exposed form block for the same view on one page, both forms are updated but only for one of them the behaviors are attached. Any ideas how to fix that?
- 🇺🇦Ukraine khiminrm
When exposed form in block, all attributes including classes are moved from the form to the block. In the latest patch only form is replaced. It can produce some bugs. For example if using better_exposed_filters and exclude text fields from autosubmit, it will not work after ajax replace of the exposed form https://git.drupalcode.org/project/better_exposed_filters/-/blob/7.0.x/j.... So it would be better to replace block and not only form.
So we need to improve somehow this:
$response->addCommand(new ReplaceCommand("form[id^=\"views-exposed-form-$view_id\"]", $this->renderer->render($exposed_form)));
- 🇬🇧United Kingdom aurora-norris
After we updated to Drupal 10.3 and PHP 8.3 this patch caused https://www.drupal.org/project/drupal/issues/3350137#comment-15802025 🐛 renderPlain on a node render array causes RuntimeException if the node renders a view programmatically Needs work to occur so I've added back a line to check if the session exists before trying to access it (the session should theoretically always exist so I'm not sure exactly what the problem is).
- 🇬🇧United Kingdom aurora-norris
Turns out the bug I encountered was actually in facets so I'm hiding my patch.
- 🇮🇳India rahulkhandelwal1990 Gurgugram
After applying patch drupal-exposed_forms_in_block_not_updated_ajax_filtering-3032353-49.patch i am getting duplicate exposed form on page as i am rendering filters as view block.
- 🇭🇺Hungary mxr576 Hungary
Read this thread and 🐛 Views - update filters block on ajax request Needs work . Also evaluated current and previous approached in patches and MRs.
Because this issue has found a close-enough solution to cover this issue with tests and there were more activity on that issue, I have closed the other one as duplicate and continue the work here.
Credits should be transferred from the other issue.
- 🇭🇺Hungary mxr576 Hungary
Let's start with a clean sheet, I will provide in depth analyzes and details that hopefully justifies my decision.
- Merge request !12048Resolve #3032353 "Ajax refresh exposed form in block" → (Open) created by mxr576
- 🇭🇺Hungary mxr576 Hungary
I have spent hours understanding the root cause of the issue, examining proposed solutions, and analyzing the reasoning behind them. Below I'll respond to previous comments and explain my thought process behind the fix currently pushed to
MR#12048.The AJAX controller must either replace the exposed form in the block or the block itself. I couldn't find a reliable way to identify and target the parent block(s) containing an exposed form - this also seemed beyond the scope of a controller that rebuilds a form. Therefore, I decided to target and replace the form itself (following @khiminrm's suggestion in #53), and I believe I've resolved the issues he mentioned by removing attributes from the form before replacing it.
@lendude provided crucial information in #12 explaining why the simple approach below doesn't work with multiple blocks and would break when 🐛 Views hardcodes exposed filter block form ID's which breaks AJAX when the same form is shown multiple times on one page Needs work is fixed. However, I disagree with #15 that this issue should be blocked by the other one, and I've sought a future-proof solution that will work regardless of which fix lands in Drupal core first.
$exposed_form_block_render_array = $view->display_handler->viewExposedFormBlocks(); $exposed_form = $this->renderer->render($exposed_form_block_render_array); $response->addCommand(new ReplaceCommand("[data-drupal-selector={$exposed_form_block_render_array['#id']}] form", $exposed_form));
Since 🐛 Views hardcodes exposed filter block form ID's which breaks AJAX when the same form is shown multiple times on one page Needs work will make form IDs dynamic, they cannot be used to target previously rendered forms in blocks for replacement, as new instances will have different IDs than existing ones. While additional CSS classes could be added to forms (like in
the proposed fix for the other issue), finding the right class in an array of classes within the controller seemed fragile. This is why I decided to add a wrapper element around the form and store its ID as a data attribute, which can be easily retrieved and used in the controller.The solution has been tested with Facets 3.x and Better Exposed Filters, not just with Drupal core's built-in exposed form plugin.
Additional reactions to previous conversations and proposed solutions:
#2 render context wrapping
The Controller always runs within an existing render context - I've verified this multiple times and couldn't find a way to run it outside a render context. Therefore, I don't believe the following workaround is necessary:
+ $context = new RenderContext(); + $exposed_form = $this->renderer->executeInRenderContext($context, function () use ($view) { + return $view->display_handler->viewExposedFormBlocks(); + }); + if (!$context->isEmpty()) { + $bubbleable_metadata = $context->pop(); + BubbleableMetadata::createFromRenderArray($exposed_form) + ->merge($bubbleable_metadata) + ->applyTo($exposed_form); + }
Or the workaround from
\Drupal\views\Plugin\views\style\StylePluginBase::renderFields()
:// Views may be rendered both inside and outside a render context: // - HTML views are rendered inside a render context: then we want to // use ::render(), so that attachments and cacheability are bubbled. // - non-HTML views are rendered outside a render context: then we // want to use ::renderInIsolation(), so that no bubbling happens if ($renderer->hasRenderContext()) { $renderer->render($data); } else { $renderer->renderInIsolation($data); }
Due to the existing render context,
->render()
bubbles up cacheability metadata out of the box.Please correct me if I've missed something.
#17 "Add exposed_form_display option to the request." or not
#17 by @allaprishchepa should no longer be relevant since the solution targets the form rather than the block. The block inherits attributes (like the targeted ID selector in #17:
"#views-exposed-form-" . $view_id
) when exposed in a block, which may have been the root cause of the problem. - 🇭🇺Hungary mxr576 Hungary
It worth mentioning that I had an interesting adventure/sidetrack where I tried to figure out how to render just the form in a way that it is not exposed inside the block to avoid attributes bubble up from the form to the block, it turned out to be a dead end.
https://drupal.slack.com/archives/C079NQPQUEN/p1746456106393489
- 🇭🇺Hungary mxr576 Hungary
Last night I have got an alternative idea that seems even more scoped the task at hand does not introduce any markup change. If this seems better than we probably need a change record to notify contrib/downstream developers that their exposed plugin implementation - unless it extends
\Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase
must set a new data attribute on the form. - 🇧🇪Belgium StryKaizer Belgium
We discussed this issue at Drupal Dev Days (Me/WannesDR/Lendude).
One thing Lendude mentioned is: there are people explicitly using "views exposed forms as block" to ensure their forms are not getting refreshed by AJAX.
To keep this backwards compatible, we suggested introducing a setting to toggle the behavior.
For existing views, the default behavior should stay as is.
For new views, the default behavior can be "update the form with AJAX".I'd suggest pushing 🐛 Ajax exposed filters not working for multiple instances of the same Views block placed on one page Needs work first, which only focuses on replacing the ID and using a data attribute as selector for the AJAX command.
Once that issue lands, we can focus on actually replacing the "views exposed form as a block", keeping the backwards compatibility setting in mind.
- 🇭🇺Hungary mxr576 Hungary
To keep this backwards compatible, we suggested introducing a setting to toggle the behavior.
For existing views, the default behavior should stay as is.
For new views, the default behavior can be "update the form with AJAX".This also occurred to me as a potential BC layer if necessary, so I like the idea, but I am not going to have capacity to work on this right now.
I'd suggest pushing #3163299: Ajax exposed filters not working for multiple instances of the same Views block placed on one page first, w
May I ask why the order matters? Why this one cannot be fixed sooner than the other?
(I am pushing for eliminating the dependency based on the slow progress I have seen on both tickets from the past. However, if both gets active involvement then...) - 🇭🇺Hungary mxr576 Hungary
Wow, I did not want to make these changes, so rolling back. Probably this is needs work due to the previous comment by @strykaizer, but first I would like to have a yey or nay on the proposed solution.
The Needs Review Queue Bot → tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide → to find step-by-step guides for working with issues.