Problem/Motivation

Steps to reproduce

  • Create like 5 pieces of content
  • Edit the /admin/content view to use 1 item per page and enable ajax
  • Use the pager multiple times

Expected result

settings.view_path points to /admin/content

Actual result

settings.view_path points to /views/ajax

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Comments

dawehner created an issue. See original summary.

dawehner’s picture

Issue summary: View changes
StatusFileSize
new293.59 KB

Here is a screenshot of what happens.

dawehner’s picture

Status: Active » Needs review
StatusFileSize
new849 bytes

Here is a fix. This ensures that we always use the view path and never the ajax one.

Maybe we should switch to the current path service always.

dawehner’s picture

StatusFileSize
new970 bytes
new867 bytes

This fixes problems on some installations for me.

slucero’s picture

slucero’s picture

I was facing this same issue on other views with AJAX enabled. The patch in #4 fixed it for me in all cases.

dmsmidt’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests
+++ b/core/modules/views/views.module
@@ -60,7 +60,7 @@ function views_views_pre_render($view) {
+          'view_path' => '/' . ltrim(\Drupal::routeMatch()->getRouteName() === 'views.ajax' ? \Drupal::service('path.current')->getPath() : Html::escape(Url::fromRoute('<current>')->toString()), '/'),

Could we please split this up in multiple lines of code for readability.

And to quote @Lendude during the Drupal Event we are currently attending (@wearesynetic): "Also, this needs test!"

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

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now 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.

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

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now 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.

ckaotik’s picture

StatusFileSize
new1.41 KB

I just ran into this issue from a different angle and noticed that even the first path used by the AJAX controller is incorrect.
My setup was as 1) a ThemeNegotiator to switch themes based on path/alias of a page and 2) a view with enabled AJAX and a views_infinite_scroll pager. As a result, any AJAX-content was using the wrong (i.e. default) theme, because the path set as "current" by the handler was incorrect.

I came up with a solution to set 'view_path' => Html::escape(Url::fromRoute('<current>', [], ['path_processing' => FALSE])->toString()) in views_views_pre_render, but then still encountered the problematic behavior on the second time paging. Integrating your patch from #4 into my findings resulted in my attached patch.

To explain my changes in a bit more detail:
TLDR: The views AJAX handling was actually using the current page's full alias, where it should have used the internal path.
This confusion was probably caused by the different definition of paths, as everywhere else in the views module, the view_path variable/setting does not use a leading slash. However in D8, internal paths always start with a leading slash. (see #2423913: Leading slash in link fields and views has different UX)
A possible side effect of this might also be argument parsing issues such as #2703771: Pager with AJAX and path alias sets Views argument incorrectly.

To get the internal path, I originally disabled the path_processing, so no alias resolving and no language prefixing etc. was applied. Your approach to use the current.path service is more stable here, and - most importantly - also fixes the main "second paging" issue. I don't think we need to worry about the page's alias (from Url::fromRoute('<current>')) but I might just miss a special use case here where the current page is unrouted but a path should always exist, right... ?
The other change was to the $this->currentPath->setPath() call in the controller, which should set a D8 internal path (which must have a leading slash), but blindly prepended the slash. That lead to the current path set to something like //en/my-view-alias, where it should have been /my-view-path.
Ideally, we'd just use $this->currentPath->setPath($path, $request); (without any slash change magic) because we know it's a D8 internal path, but I wasn't brave enough for that ;)

ckaotik’s picture

Status: Needs work » Needs review

Let's test this-

ckaotik’s picture

Status: Needs review » Needs work

Back to needs work for adding tests.

socialnicheguru’s picture

thank you. this fix worked for me.

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

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now 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.

rob230’s picture

This patch #10 breaks some of my custom code.

For example I have a view which uses this code to get the current path:

$current_path = \Drupal::service('path.current')->getPath();

It should point to the path of the current page (although the view is a block), but when AJAX is used, it points to the wrong place.

When I apply your patch, the above code returns /views/ajax. What I want it to return is the path of the current page that the views block appears on.

Edit: to be honest that isn't a problem with this patch, the path IS /views/ajax because that's the path being used by AJAX request...

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.

jordik’s picture

I needed a workaround quickly, so I found one and it works for me.
Instead of getting the current path, which is changed by AJAX, by using:
$my_variable = \Drupal::service('path.current')->getPath();

You will need to get the view object (class ViewExecutable) and use the path, which is stored in its config.
$my_variable = $this->view->getUrl()->getInternalPath();

In my case I was using a class, which extends FieldPluginBase, so the view object was accessible through $this->view.
This one is never changed by AJAX, so you can use it for a destination parameter.

joegl’s picture

I do not think this is just a Views problem (although I could be wrong). I have ran into many issues with Drupal Core AJAX where anything auto-rendered/generated in an AJAX request uses the "current" route/URL, which evaluates to the AJAX request itself, and not the actual page you are rendering to/from. So any URL's auto-generated by Drupal Core AJAX point to the AJAX request itself, which doesn't make sense to me personally (it will only render correctly the first time).

Essentially, within Drupal Core this method of creating a new Url is used quite a bit, especially related to AJAX:

new Url('<current>');

#3055018: URL's generated within AJAX request are re-routed to that AJAX request is the issue I've used to try to compile these problems.

lendude’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new1.29 KB
new2.69 KB

Here is a test for this, to validate that the view_path start out right and ends up wrong after a number of AJAX calls. Test only patch is the interdiff to #10

The last submitted patch, 20: 2866386-20-TEST_ONLY.patch, failed testing. View results

neclimdul’s picture

+++ 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(),

I guess my only question would be why do we feel confident in dropping the escape? This changed in #10 but I didn't catch why.

lendude’s picture

StatusFileSize
new660 bytes
new2.71 KB

@neclimdul good point, lets put that back in, doesn't seem like that change is needed here to fix this.

maximpodorov’s picture

Probably the current issue is obsolete since another solution has been accepted: #2820347: Exposed filter reset redirects user to 404 page on AJAX view when placed as a block

mbovan’s picture

StatusFileSize
new1.29 KB

Since proposed changes from #23 were committed in #2820347: Exposed filter reset redirects user to 404 page on AJAX view when placed as a block, I am cherry-picking the tests.

mbovan’s picture

Title: 'view_path' is set to /views/ajax after second ajax request » Assert the view path is set correctly after second ajax request

Updated the issue title to match the test coverage from #26.

berdir’s picture

Status: Needs review » Reviewed & tested by the community

Great, some extra test coverage seems useful for this as earlier fixes and patches in other issues weren't enough to fix it.

alexpott’s picture

Category: Bug report » Task
Status: Reviewed & tested by the community » Fixed

I credited @dmsmidt and @neclimdul for patch review (even though the full scope of the patch on this issue landed elsewhere) and @Berdir for finding all the dupes.

Committed 3a3a039 and pushed to 8.8.x. Thanks!

  • alexpott committed 3a3a039 on 8.8.x
    Issue #2866386 by Lendude, dawehner, ckaotik, mbovan, Berdir, dmsmidt,...

Status: Fixed » Closed (fixed)

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

liquidcms’s picture

I guess my case is slightly different.

I have an ajax modal open on my page and when it completes i run the view to get an updated version of the view as it would have changed from the code run by the modal. I use a command like: $response->addCommand(new ReplaceCommand($block['div'], $html)); to update the block the view is in.

That View has a set of links in it and they end up having their destinations messed up as a result of this issue.

I am running 8.9.16 - so this issue isn't entirely fixed yet.

jeeba’s picture

So any patch on Drupal 9? Currently I'm using Drupal 9.4.5 with the modules Show More and Load More, both have the same problem.

lendude’s picture

@jeeba this fix has been committed so there will be no patch for this specific issue, if you still have similar problems please find an existing issue for it or if none exist, please open a new issue describing the steps to reproduce your issue on a clean Drupal core install.

Thanks!