Steps to recreate:

- Create an AJAX enabled view with exposed filters (as drop down), enable the reset button
- Create a page and place the view as a block on the page.
- Load the view page - no reset button
- Click filter submit button
- Reset button appears
- Click Reset button

- The page is redirected to a system/404

CommentFileSizeAuthor
#129 2820347-129.patch13.59 KBacbramley
#129 interdiff-2820347-126-129.txt2.13 KBacbramley
#126 2820347-126.patch13.59 KBacbramley
#126 interdiff-2820347-121-126.txt5.74 KBacbramley
#124 2820347-124.patch11.16 KBacbramley
#124 interdiff-2820347-121-124.txt1.31 KBacbramley
#121 interdiff-2820347-117-121.txt1.77 KBfenstrat
#121 2820347-121.patch10.94 KBfenstrat
#117 interdiff.txt413 bytesxaqrox
#117 core-views-exposed-ajax-reset-404-2820347-117.patch10.61 KBxaqrox
#115 core-views-exposed-ajax-reset-404-2820347-115.patch10.63 KBxaqrox
#110 2820347-110.patch3.98 KBmaximpodorov
#105 2820347-105.patch7.93 KBjibran
#105 interdiff-888678.txt740 bytesjibran
#103 2820347-103.patch7.89 KBjibran
#103 interdiff-205b93.txt1.65 KBjibran
#96 core-views-ajax-path--2820347-96.patch7.94 KBesolitos
#96 interdiff--2820347-92-96.txt941 bytesesolitos
#93 2820347-92.patch7.86 KBacbramley
#93 interdiff-2820347-91-92.txt937 bytesacbramley
#91 2820347-91-FAIL.patch7.7 KBacbramley
#91 interdiff-2820347-76-91.txt1.65 KBacbramley
#76 exposed_filter_reset-2820347-67.patch7.33 KBxjm
#76 exposed_filter_reset-2820347-67-FAIL.patch6.28 KBxjm
#67 interdiff-62-67.txt516 bytesacbramley
#67 exposed_filter_reset-2820347-67.patch7.33 KBacbramley
#62 interdiff-60-62.txt758 bytesacbramley
#62 exposed_filter_reset-2820347-62.patch7.08 KBacbramley
#60 exposed_filter_reset-2820347-60.patch7.13 KBacbramley
#60 interdiff-53-60.txt914 bytesacbramley
#57 interdiff-2820347-49-53.txt3.16 KBAnonymous (not verified)
#53 exposed_form_reset_404-2820347.8.3-53.patch7.27 KBAnonymous (not verified)
#51 exposed_form_reset_404-2820347.8.4-51.patch7.26 KBAnonymous (not verified)
#50 exposed_form_reset_404-2820347.8.3-50.patch7.27 KBAnonymous (not verified)
#49 2820347-49.patch8.84 KBDinesh18
#47 interdiff.txt715 bytesDinesh18
#47 2820347-47.patch18.96 KBDinesh18
#44 interdiff-39-44.txt630 bytesacbramley
#44 2820347-44.patch8.84 KBacbramley
#43 interdiff-33-39.txt693 bytesacbramley
#39 2820347-39.patch8.86 KBacbramley
#35 comment#31_reviewed.png12.56 KBDinesh18
#33 2820347-33.patch8.85 KBLendude
#33 interdiff-2820347-30-33.txt567 bytesLendude
#30 2820347-30.patch8.85 KBLendude
#30 interdiff-2820347-24-30.txt3.67 KBLendude
#24 2820347-reroll-array.patch6.15 KBtameeshb
#20 interdiff.txt1.23 KBacbramley
#20 2820347-views-block-exposed-filter-ajax-20.patch6.17 KBacbramley
#15 interdiff.txt823 bytesacbramley
#15 2820347-views-block-exposed-filter-ajax-15.patch6.16 KBacbramley
#13 2820347-views-block-exposed-filter-ajax-13.patch6.15 KBacbramley
#13 interdiff.txt1.32 KBacbramley
#11 interdiff.txt651 bytesacbramley
#11 2820347-views-block-exposed-filter-ajax-failing-test-11.patch4.83 KBacbramley
#6 2820347-views-block-exposed-filter-ajax-failing-test.patch4.79 KBacbramley
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

sittard created an issue. See original summary.

sittard’s picture

Title: Reset rutton redirects user to 404 page on AJAX view when placed as a block » Reset redirects user to 404 page on AJAX view when placed as a block
godotislate’s picture

Looks like there are a couple of issues
1. AJAX behavior is explicitly not applied to reset buttons (/core/modules/views/js/ajax_view.js)

// Exclude the reset buttons so no AJAX behaviours are bound. Many things
    // break during the form reset phase if using AJAX.
    $('input[type=submit], input[type=image]', this.$exposed_form).not('[data-drupal-selector=edit-reset]').each(function (index) {

2. Views AJAX is changing the form action to "/views/ajax" somewhere.

My workaround was to implement a form alter and explicitly set the form action to the correct URL.

acbramley’s picture

Title: Reset redirects user to 404 page on AJAX view when placed as a block » Exposed filter reset redirects user to 404 page on AJAX view when placed as a block
Version: 8.2.1 » 8.2.x-dev

Encountered this today as well, in 2 different ways:

Firstly I had a page display in the same view as the block and tried writing some behat tests (i,e no javascript).
When the test hit the Apply button it was being sent to the page display with filters applied rather than the page the block was on. To fix that I had to move the page display to a new view, no biggy.

Second issue I've now encountered is as described here, except I get redirected to /views/ajax.

acbramley’s picture

The bug seems to be coming from this line in Drupal\views\Form\ViewsExposedForm

$form['#action'] = $view->hasUrl() ? $view->getUrl()->toString() : Url::fromRoute('<current>')->toString();

When the exposed form is submitted via ajax, it sets the action to views/ajax

acbramley’s picture

Here's a failing test to prove the problem.

Status: Needs review » Needs work

The last submitted patch, 6: 2820347-views-block-exposed-filter-ajax-failing-test.patch, failed testing.

aimevp’s picture

I'm having this issue as well but noticed I had a second side-effect caused by the line of code mentioned in #5.

In my view I had several blocks with exposed filters that worked until I added page display's. From that moment the exposed filters on the blocks started using the path's of the first page display in the form action, instead of the "current page".

I don't really understand why the code in views gets to decide where to redirect the form action to. "If it doesn't find a display with a path, redirect to current page". It seems so random to me.

Wouldn't it be better SBX to add a setting "Form redirect path (for example)" within the exposed filters options of each view display (or somewhere else within the view display settings) with a default setting "Current" in which the sitebuilder can define a page display or a path if needed?

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

kovtunos’s picture

Quick fix with the hook_form_alter implementation:

function THEME_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'views_exposed_form') {
    if ($form['#id'] == 'FORM ID HERE') {
      $form['#action'] = '/node/XXX';
    }
  }
}
acbramley’s picture

Rerolling on 8.3.x with updated submit filter text as the default has changed.

Status: Needs review » Needs work
acbramley’s picture

Fix using the request referer if the current page is identified as the views ajax route. I'm not entirely fond of this approach but with my limited views foo this is what I've come up with. The other option would be to make Reset use ajax as well but that would be a more involved change. Let's see if this breaks anything.

Status: Needs review » Needs work

The last submitted patch, 13: 2820347-views-block-exposed-filter-ajax-13.patch, failed testing.

acbramley’s picture

Status: Needs work » Needs review
FileSize
6.16 KB
823 bytes

Missed this change to the test.

anpolimus’s picture

Expecting this issue at my project.
Patch at #15 fix this problem.
I have one problem - when I'm using ajax at the view, reset button click refreshes current page.
Is it normal in this case?

acbramley’s picture

@anpolimus yeah, that is the normal functionality. One option for fixing this would be to change the reset button to use ajax as well, but I think that is going to be a far broader change (without looking into it), probably best for another issue.

anpolimus’s picture

Status: Needs review » Reviewed & tested by the community

In this case, this isssue is fixed.

Lendude’s picture

Bit of nitpicking:

  1. +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_block_exposed_ajax.yml
    @@ -0,0 +1,81 @@
    +uuid: aaeabe85-2292-4d20-a0ae-8e1afc9c5227
    

    UUID needs to be removed

  2. +++ b/core/modules/views/tests/src/FunctionalJavascript/BlockExposedFilterAJAXTest.php
    @@ -0,0 +1,78 @@
    +    // Verify that only the page nodes are present.
    

    Shouldn't we check then that $this->assertNotContains('Article A', $html);

acbramley’s picture

Thanks @Lendude, fixed those up.

Lendude’s picture

@acbramley++
RTBC++

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 20: 2820347-views-block-exposed-filter-ajax-20.patch, failed testing.

Lendude’s picture

Issue tags: +Needs reroll

Needs reroll for #2776975: March 3, 2017: Convert core to array syntax coding standards for Drupal 8.3.x RC phase.

Using the convert trick in that issue won't work here because only the trailing ) of array() is in the patch.

tameeshb’s picture

Patch rerolled.

tameeshb’s picture

Status: Needs work » Needs review
Lendude’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs reroll

Thanks @tameeshb reroll looks good, back to RTBC

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -111,7 +111,24 @@ public function buildForm(array $form, FormStateInterface $form_state) {
+        $referer = $this->getRequest()->headers->get('referer');
+        $form_action = parse_url($referer, PHP_URL_PATH);

I'm not sure about this. I think this might under certain circumstances allow an open redirect. We shouldn't trust a referer.

acbramley’s picture

@alexpott yeah I didn't like the referer solution either, but I'm not sure how else to solve it. I tried using the parent request object but that wasn't working either. Any guidance here would be great.

jibran’s picture

@acbramley I think you should ping @tim.plunkett about it. He might be able to help you out here.

Lendude’s picture

Borrowed the solution from @dawehner in #2866386: Assert the view path is set correctly after second ajax request.

Also, the use of assertWaitOnAjaxRequest() can lead to random fails, so taken that out, but we don't have wait methods for removed elements yet, so added that too.

jibran’s picture

Status: Needs review » Needs work

Thanks, patch looks good to me.

+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -111,7 +126,23 @@ public function buildForm(array $form, FormStateInterface $form_state) {
+      if (!$current->getRouteName() == 'views.ajax') {

It can be converted !==.

Dinesh18’s picture

@jibra, could you please review the below code so that I can create the patch as per comment #31
+ if ($current->getRouteName() !== 'views.ajax') {

Lendude’s picture

Status: Needs work » Needs review
FileSize
567 bytes
8.85 KB

Thanks for the feedback @jibran, here we go.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Thanks! @Lendude

Dinesh18’s picture

FileSize
12.56 KB

Patch #33 looks good and implements #31.
Here is a screengrab. +1 to RTBC

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 33: 2820347-33.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

acbramley’s picture

Thanks @Lendude, much nicer solution!

acbramley’s picture

Assigned: Unassigned » acbramley

Confirmed test failure locally.

EDIT: It seems like getRouteName() is always returning "" now. Not sure when this changed as it was certainly working before.

acbramley’s picture

Status: Needs work » Needs review
FileSize
8.86 KB

Fixed #33 failure

acbramley’s picture

Assigned: acbramley » Unassigned

The last submitted patch, 33: 2820347-33.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

jibran’s picture

Status: Needs review » Needs work

Interdiff, please.

+++ b/core/modules/views/tests/src/FunctionalJavascript/BlockExposedFilterAJAXTest.php
@@ -0,0 +1,80 @@
+use Drupal\Core\Url;

This can be removed now.

acbramley’s picture

Status: Needs work » Needs review
FileSize
693 bytes

Sorry, forgot to upload the interdiff! Url is still being used here:

+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -111,7 +126,23 @@ public function buildForm(array $form, FormStateInterface $form_state) {
+      $current = Url::fromRoute('<current>');

EDIT: Ahh from the test...fixing now.

acbramley’s picture

Lendude’s picture

Last little nitpick:

+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -111,7 +126,23 @@ public function buildForm(array $form, FormStateInterface $form_state) {
+      $current = Url::fromRoute('<current>');
+      if ($this->getRouteMatch()->getRouteName() !== 'views.ajax') {
+        $form_action = $current->toString();
+      }

$current can go inside the if now

Dinesh18’s picture

Assigned: Unassigned » Dinesh18
Status: Needs review » Needs work
Dinesh18’s picture

Status: Needs work » Needs review
FileSize
18.96 KB
715 bytes

Here is an updated patch and interdiff.
Implements #45

jibran’s picture

Status: Needs review » Needs work

The last patch is not correct at all. @Dinesh18 please read https://www.drupal.org/patch/apply and https://www.drupal.org/patch first before uploading the patch. Thanks!

Dinesh18’s picture

Status: Needs work » Needs review
FileSize
8.84 KB

Here is an updated patch which implements #45.

Anonymous’s picture

I found an issue with the patch and getting the path form the currentPathStack. On two of my sites, it returned the path prefixed with two /, and resulted in trying to go to a site with my path as the host name.

I've updated the patch to set $form_action to '' (current path) to avoid issues in setting/getting urls.

I also updated the tests to repeat the original test - checking for the 3 nodes.

Anonymous’s picture

Same patch rolled against 8.4.x

The last submitted patch, 50: exposed_form_reset_404-2820347.8.3-50.patch, failed testing. View results

Dinesh18’s picture

Could you please provide interdiff as well

Lendude’s picture

Status: Needs review » Needs work

#50 indicates we are missing test coverage here since the test we have is fine with using currentPathStack.

@rsmylski any chance you can indicate what was different in your situation then in the existing test?

mcvjoyner’s picture

I have tested the patch, and it works well. Thanks @rsmylski!

Anonymous’s picture

FileSize
3.16 KB

Here's the interdiff.

As for the test change - I changed the final test to check for the first things checked for to start the test, rather than checking for not being a 404. Ultimately, the last check of the urls should confirm we were on the same page.

Lendude’s picture

Assigned: Dinesh18 » Unassigned
Status: Needs work » Reviewed & tested by the community

@rsmylski++

Tested that the changed test coverage indeed fails with the fix from before #50, so we have coverage for the problems described in #50, nice work.

catch’s picture

Status: Reviewed & tested by the community » Needs review
  1. +++ b/core/modules/views/src/Form/ViewsExposedForm.php
    @@ -111,7 +111,15 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     
    -    $form['#action'] = $view->hasUrl() ? $view->getUrl()->toString() : Url::fromRoute('<current>')->toString();
    +    if (!$view->hasUrl()) {
    +      // Default to the current path.
    +      $form_action = '';
    +    }
    +    else {
    +      $form_action = $view->getUrl()->toString();
    +    }
    +
    

    It's minor, but why change from the ternary to the if/else? The ternary seems more readable here and it'll be a shorter line too.

    Also even with the if/else could it not set $form['#action'] directly instead of the temporary variable? But for me I'd stick with the ternary.

  2. +++ b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
    @@ -72,6 +72,32 @@ public function waitForElement($selector, $locator, $timeout = 10000) {
     
       /**
    +   * Looks for the specified selector and returns TRUE when it is unavailable.
    +   *
    +   * @param string $selector
    +   *   The selector engine name. See ElementInterface::findAll() for the
    +   *   supported selectors.
    +   * @param string|array $locator
    +   *   The selector locator.
    +   * @param int $timeout
    +   *   (Optional) Timeout in milliseconds, defaults to 10000.
    +   *
    +   * @return bool
    +   *   TRUE if not found, FALSE if found.
    +   *
    +   * @see \Behat\Mink\Element\ElementInterface::findAll()
    +   */
    +  public function waitForElementRemoved($selector, $locator, $timeout = 10000) {
    +    $page = $this->session->getPage();
    

    Do we really not have anything usable for this purpose already?

acbramley’s picture

Lendude’s picture

Status: Needs review » Needs work

These are the wait options we have:
waitForButton
waitForElement
waitForElementVisible
waitForField
waitForId
waitForLink
waitOnAutocomplete

So no we don't have anything to wait for stuff to disappear as far as I can tell.

+++ b/core/modules/views/tests/src/FunctionalJavascript/BlockExposedFilterAJAXTest.php
@@ -0,0 +1,82 @@
+    $this->assertSession()->assertWaitOnAjaxRequest();
+    $this->assertSession()->waitForElementRemoved('xpath', "//text()[normalize-space() = 'Article A']");

But we do need to remove the assertWaitOnAjaxRequest call, which I apparently failed to do :(

acbramley’s picture

Status: Needs work » Needs review
FileSize
7.08 KB
758 bytes

Fixes #61

Lendude’s picture

Status: Needs review » Reviewed & tested by the community

Feedback has been addressed, back to RTBC

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 62: exposed_filter_reset-2820347-62.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

acbramley’s picture

Status: Needs work » Needs review

That fail looks unrelated.

Lendude’s picture

Codesniffer did find an unused Use though, so lets take that out.

drupal/core/modules/views/src/Form/ViewsExposedForm.php:9 use Drupal\Core\Url;

acbramley’s picture

Lendude’s picture

Status: Needs review » Reviewed & tested by the community

@acbramley thank you!

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

catch’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs change record

This needs a change record for the new method on WebAssert, but otherwise looks good.

acbramley’s picture

Status: Needs work » Needs review
Issue tags: -Needs change record
Lendude’s picture

Status: Needs review » Reviewed & tested by the community

CR looks good, back to RTBC

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 67: exposed_filter_reset-2820347-67.patch, failed testing. View results

acbramley’s picture

Status: Needs work » Needs review

Seems like a CI blip

acbramley’s picture

Status: Needs review » Reviewed & tested by the community

Retest passed, back to RTBC

xjm’s picture

I wanted to test that this didn't regress or change other behaviors of the block exposed form, for a page that was the frontpage, etc., but I'm having some issues reproducing the bug.

I tested this by making the frontpage AJAX and adding an exposed form in a block with a reset button in HEAD. For me, in HEAD the reset button disappears strangely. If I navigate to e.g. node/1 and apply the filter, I get redirected to the node frontpage (with its node path) and have the reset button, which works. But if I reset the filters and then submit the exposed form from the page of the view itself, the reset button does not show up and I have no way of resetting the view results. Strange... But I was not able to reproduce the 404 at all, in HEAD or with the patch.

https://www.drupal.org/pift-ci-job/556226 does seem to show a failing result so I'll try testing a scenario closer to the test view.

Meanwhile, uploading a new test-only patch since the failing result was on an earlier version of the test and an earlier version of Drupal.

The last submitted patch, 76: exposed_filter_reset-2820347-67-FAIL.patch, failed testing. View results

acbramley’s picture

Hi @xjm, sorry but I don't quite understand your comments in #76, are you able to post steps to reproduce your problems? The FAIL patch has correctly failed and the other has passed so is there anything more to do in this issue?

Thanks!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 76: exposed_filter_reset-2820347-67.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jibran’s picture

Status: Needs work » Reviewed & tested by the community

The test fails seems unrelated.

Anybody’s picture

I just tested the patch manually and can luckily confirm RTBC :) It works now!
We've tested it in a multilang environment with translated reset button.

RTBC++ and please commit to next release! Should we perhaps set a higher priority, because it breaks things?

xjm’s picture

@acbramley, I didn't have "problems"; I was describing what steps I, as a Drupal core committer, took in reviewing the RTBC patch. There were no recent test-only patches until the one I posted. Which is why I posted it. :) Also note that I left the issue at RTBC, which means I didn't think it needed more work.

Re: #82, nah, it's a normal bug because the steps to reproduce it are pretty edgecase-y and specific. Thanks!

acbramley’s picture

@xjm no worries at all! Sorry I must have misinterpreted what you said, thanks for clarifying :)

plach’s picture

Status: Reviewed & tested by the community » Needs review

Thanks for all your efforts, I manually tested the latest patch and seems to work fine, without introducing regressions, and the additional test coverage looks great. However I'm not completely sure about the proposed solution.

+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -111,7 +110,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
+    $form['#action'] = $view->hasUrl() ? $view->getUrl()->toString() : '';

This doesn't look proper to me for two reasons:

  1. We have a view_path POST parameter that's meant to store the original path for AJAX requests. This is exactly what we need here.
  2. An empty form action would break if the BASE tag were set.

Therefore I'd suggest to go back to the solution proposed in #49 that in fact relies on the view_path parameter (see ViewAjaxController lines 125 and 149). I think we should solve the double slash issue mentioned in #50 instead of trying a completely different approach.

Of course we would keep all the following improvements the led to #76 :)

xjm’s picture

Issue tags: +Needs tests

We'll also want to add a test case for the form action/base tag issue (I should have caught that).

plach’s picture

Btw, also the behavior of $view->getUrl() does not make a lot of sense here: if the display doesn't define a path, it will fall back to the first display it can find that does define one. However this display could be totally unrelated to the original one, which would lead again to an unexpected destination on submit (at least without AJAX). Maybe we could just use the current path and skip the view url logic altogether?

plach’s picture

I tried to simply remove the additional slash in ViewAjaxController, line 149, and tests are green, which makes me think we are missing test coverage for that and the HEAD behavior is buggy. See https://www.drupal.org/project/drupal/issues/2938524#comment-12552036.

VinceThePrince’s picture

Hi! I think I have a similar Issue to this.

https://stackoverflow.com/questions/49709766/contact-form-throws-the-req...


I have created a "Contact storage contact form" within a custom page object. When I submit this contact storage contact form directly from the page it works super. But when I submit it from a block it throws error "The requested page could not be found." More specific this block uses the view module to filter these pages.

You can test this yourself by going to http://mijnverkeersovertreding.be/rechtsbijstand

In the input "Postcode" fill in 1910 and press Apply. A contact form appears once. You can fill it in with random data and when you submit it, it throws error The requested page could not be found on url /views/ajax.

Kr.

acbramley’s picture

Status: Needs review » Needs work

Btw, also the behavior of $view->getUrl() does not make a lot of sense here: if the display doesn't define a path, it will fall back to the first display it can find that does define one.

@plach You're totally right, I just ran into this situation after adding a new display to a view which was previously just block displays. The new display extended PathPluginBase and therefore was picked up by $view->getUrl() and ended up resulting in a fatal due to missing arguments.

I'm going to have a crack at using view_path like you've suggested.

acbramley’s picture

Status: Needs work » Needs review
FileSize
1.65 KB
7.7 KB

This should fail. Also cleaned up the deprecated traits.

Status: Needs review » Needs work

The last submitted patch, 91: 2820347-91-FAIL.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

acbramley’s picture

Status: Needs work » Needs review
FileSize
937 bytes
7.86 KB

And the fix. Instead of setting the action always, we can leave it as null for almost all cases as it will then default to the page the form is on. For ajax routes, we override it with an empty string as this seems to ensure the action is set to the path the page is rendered on rather than the ajax path (I'm not sure why this happens, but it works :)).

Still needs tests for the base tag issue mentioned in #85

Status: Needs review » Needs work

The last submitted patch, 93: 2820347-92.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

igalafate’s picture

I applied the #67 patch and everything works fine for me, but since I have applied the #92 an exposed filter block of my search view is not redirecting to the search page (/search) anymore. When the filter is applied from any page, the url still the same but with the search params. So for example, using my filter block on the homepage I'm getting "/?keys=test" instead of "/search/?keys=test".

esolitos’s picture

Patch rolled to take care of #67.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Anybody’s picture

Version: 8.6.x-dev » 8.7.x-dev

RTBC +1 for #96

Anybody’s picture

Status: Needs review » Reviewed & tested by the community

We're using this since a longer period of time on several sites now on 8.5.x and 8.6.x, I think we can set #96 RTBC now.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/views/src/Form/ViewsExposedForm.php
    @@ -113,7 +112,14 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +    else {
    +      $form['#action'] = '';
    +    }
    

    Do we need the else here?

  2. +++ b/core/modules/views/tests/src/FunctionalJavascript/BlockExposedFilterAJAXTest.php
    @@ -0,0 +1,81 @@
    +class BlockExposedFilterAJAXTest extends JavascriptTestBase {
    

    This needs to use WebDriverTestBase now - JavascriptTestBase has been deprecated.

  3. As per #93 - still needs tests for the base tag issue mentioned in #85
remram’s picture

The last patch from #96 working great but one thing is missing. It's not respecting the destination and it's value. In this case if you reset your filter it will remove the destination from the URL und you wont be able to go back to the origin page!

gambry’s picture

Current work - since pretty much the beginning - makes sure form action is empty when views is ran through AJAX.
This does fix this issue according to its title - user is not redirected to a 404 page - however the result is a really weird UX due the reset button not having any AJAX event handler attached. The page is consequently re-loaded when you press the reset button and the meaning of having an AJAX exposed form is completely lost. The user needs to scroll the page to find back the view/form, and that's OK if the view/form exists in page on loading and not for example if it's part of a multi-step AJAX process.

On the other side the JS code states this about why reset is excluded from AJAX behaviours:

// Exclude the reset buttons so no AJAX behaviours are bound. Many things
// break during the form reset phase if using AJAX.

So are we only tackling the 404 on reset or the reset not working at all on AJAX?
If the former, than we should state in the IS about the weird UX.

jibran’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
1.65 KB
7.89 KB

Addressed #100.

Status: Needs review » Needs work

The last submitted patch, 103: 2820347-103.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

jibran’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
740 bytes
7.93 KB

Turn out we can't remove #100.1. Fixed reset of the feedback so setting it back to RTBC. @gambry feel free to update the IS.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 105: 2820347-105.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

gambry’s picture

@jibran I believe what #100.1 means is something like:

$form['#action'] = '';
if ($view->hasUrl() && $this->getRouteMatch()->getRouteName() !== 'views.ajax') {
  $form['#action'] = $view->getUrl()->toString();
}

I'll update the IS as soon, as I need to re-test my assumptions from #102 ("we are fixing the 404, but causing a potential weird UX") still applies.

maximpodorov’s picture

The current solution produces invalid HTML code: according to the standard, action attribute must be non-empty if it is specified in the form element.

So +1 for #93.
Or to switch to solutions from #2866386: Assert the view path is set correctly after second ajax request which use ltrim(..., '/') to avoid double slashes.

Anonymous’s picture

what is the status of this bug? I am not as technically adept as most of you contributing in this thread, but I am still having this problem.

It is happening using Drupal 8.6.8 with Empty Page module to produce a blank page without content, and applying two blocks to the empty page.

Upon reset, I get 404 error. Can I "upgrade" or side-grade to 8.6.X dev instead of 8.6.9, or is that not possible?

Is there a fix in place or a workaround?

maximpodorov’s picture

Status: Needs work » Needs review
FileSize
3.98 KB

This patch can be tried. It is the combination of #49 and the patch from #2866386: Assert the view path is set correctly after second ajax request. No tests yet.

IT-Cru’s picture

Patch from #110 fix broken reset button via https://www.drupal.org/project/views_field_formatter embedded views with exposed forms for me.

Anonymous’s picture

would the new patch work on 8.6.8?

UPDATE:
can confirm patch is working on 8.6.8 as intended (so far) without the use of views field formatter.
just producing two blocks on an "empty page" and using the patch seems to do the trick
will perform some more views tests and changes.
will report back if testing produces related errors.

huge thanks, maximpodorov @ Comment #110 !

Is reloading of the page upon reset normal behaviour, even though it is AJAX ?

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

alison’s picture

#110 works great on 8.6.15, thank you!

Is reloading of the page upon reset normal behaviour, even though it is AJAX ?

(@Careless)

I second that ^^ question!

xaqrox’s picture

Here's #2820347-110: Exposed filter reset redirects user to 404 page on AJAX view when placed as a block plus the tests from #2820347-105: Exposed filter reset redirects user to 404 page on AJAX view when placed as a block. It applies to 8.7.x and solved this problem for me. However I discovered a *ton* of related issues while tracking this down, conveniently collected in #3055018: URL's generated within AJAX request are re-routed to that AJAX request, that seem to indicate this might be a bigger problem... or just the same mistake repeated in a few different places? Anyway, hope this helps.

Status: Needs review » Needs work

The last submitted patch, 115: core-views-exposed-ajax-reset-404-2820347-115.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

xaqrox’s picture

larowlan’s picture

Bumped into this on a project, thanks for working on it

  1. +++ b/core/modules/views/src/Form/ViewsExposedForm.php
    @@ -24,21 +25,35 @@ class ViewsExposedForm extends FormBase {
    +  public function __construct(ExposedFormCache $exposed_form_cache, CurrentPathStack $current_path_stack) {
         $this->exposedFormCache = $exposed_form_cache;
    +    $this->currentPathStack = $current_path_stack;
    

    I realise that constructors are not part of our API, but recently we've been doing this in a BC fashion, e.g. see

    </li>
    
    <li>
    <code>
    +++ b/core/modules/views/views.module
    @@ -60,7 +60,7 @@ function views_views_pre_render($view) {
    -          'view_path' => Html::escape(Url::fromRoute('<current>')->toString()),
    +          'view_path' => \Drupal::service('path.current')->getPath(),
    

    We're losing the Html::escape here - are we sure we want that change?

  2. +++ b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
    @@ -71,6 +71,32 @@ public function waitForElement($selector, $locator, $timeout = 10000) {
    +  public function waitForElementRemoved($selector, $locator, $timeout = 10000) {
    

    nice!

jurgenhaas’s picture

Confirmed, #110 works for me too.

stevieb’s picture

the patch from #110 fails using composer

fenstrat’s picture

Status: Needs review » Needs work

The last submitted patch, 121: 2820347-121.patch, failed testing. View results

acbramley’s picture

The failure in #121 is the same issue that we saw all the way back in #87 due to $view->getUrl() returning the url from the first display if the current one doesn't have a path.

acbramley’s picture

Status: Needs work » Needs review
FileSize
1.31 KB
11.16 KB

This patch fixes #123, however I think this will break displays that do have linked displays.

Status: Needs review » Needs work

The last submitted patch, 124: 2820347-124.patch, failed testing. View results

acbramley’s picture

Status: Needs work » Needs review
FileSize
5.74 KB
13.59 KB

After chatting about the issue with some colleagues we agreed that it does seem like the functionality of submitting a block's exposed form and being redirected to the linked (or first routed) display is intended and not a bug.

With that in mind, I've rolled back to #121 fixed the test, and added another scenario.

jibran’s picture

Patch looks good now.

+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -113,7 +132,22 @@ public function buildForm(array $form, FormStateInterface $form_state) {
+      // If we are building an ajax form, don't set the action to the views
+      // ajax route.
+      if ($this->getRouteMatch()->getRouteName() !== 'views.ajax') {

This is non-ajax condition but the comment is about ajax form.

Status: Needs review » Needs work

The last submitted patch, 126: 2820347-126.patch, failed testing. View results

acbramley’s picture

Status: Needs work » Needs review
FileSize
2.13 KB
13.59 KB

Fixed #127 and changed to use node url without the leading slash which seems cause the failure in #126

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for addressing the feedback this looks good now so setting it to be RTBC.

larowlan’s picture

larowlan’s picture

Status: Reviewed & tested by the community » Fixed

Committed b6b8e0f and pushed to 8.8.x. Thanks!

Published both change records.

The constructor change makes this too disruptive for a backport, so leaving at 8.8.x, sites impacted by this can continue to run the patch at 129 via composer-patches or similar.

  • larowlan committed b6b8e0f on 8.8.x
    Issue #2820347 by acbramley, rsmylski, Lendude, jibran, Dinesh18, xaqrox...
esolitos’s picture

Great news, thanks everyone!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

andreyjan’s picture

The patch is fixing the issue when there is only one exposed filter.
When there are at least 2 filters, after submitting Reset button you get redirected to the current page with previously applied filters in query parameters (?type=All&field_some_vocabulary_target_id=123&op=Reset) and the following error is displayed:

Drupal\Core\Form\EnforcedResponseException: in Drupal\Core\Form\FormBuilder->buildForm() (line 351 of core/lib/Drupal/Core/Form/FormBuilder.php).
Drupal\Core\Form\FormBuilder->buildForm('\Drupal\views\Form\ViewsExposedForm', Object) (Line: 135)
Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase->renderExposedForm() (Line: 1238)
Drupal\views\ViewExecutable->build(NULL) (Line: 1391)
Drupal\views\ViewExecutable->execute(NULL) (Line: 1454)
Drupal\views\ViewExecutable->render() (Line: 131)
Drupal\views\Plugin\views\display\Block->execute() (Line: 1630)

I am not sure if I need to open another issue since this one was already committed in 8.8 or just re-opening this one.

larowlan’s picture

@andreyjan - please open a new issue and link it here 🏆 - thanks

matthieuscarset’s picture

Just commenting to let you know this patch #129 unfortunately does not applied on Drupal 8.7 (tested on 8.7.7).

Rajab Natshah’s picture

#129 is working for Drupal 8.7.8
Waiting for Drupal 8.8.0 :)

bbombachini’s picture

This patch didn't apply on 8.8.0 for me.
Thanks @acbramley, I didn't read the whole thread, sorry!

acbramley’s picture

@bbombachini the fix was committed before 8.8.0 so you don't need the patch :)

anneeasterling’s picture

I know this issue is closed and don't expect any action -- I'm just reporting on my experience. On our project, if using exposed filters with ajax turned on, resetting the filters on a view block sends the user to the first page display that was created. I've followed the advice of another commenter to separate the views as a work around. I'd be interested at some point to hear whether others are experiencing the same.

(Leaving this comment here primarily for folks who land here via Google search.)

AaronMcHale’s picture

@anneeasterling if that is indeed a bug (sounds like it might be), could you open a new issue (if one doesn't already exist), providing as much detail as possible on how to reproduce the problem.

Thanks

liquidcms’s picture

Sounds a lot like the issue i am having with ver 4.0.0: #3244756: Submit broken when used with AJAX.

jgoodwill01’s picture

Running into this issue with Version 9.5.0 can anyone help with a patch for current versions of Drupal 9?

alison’s picture

Running into this issue with Version 9.5.0 can anyone help with a patch for current versions of Drupal 9?

Same, haven't confirmed that it's happening on D10, but I'm going to submit a new issue.