Problem/Motivation
Steps to reproduce
- Create like 5 pieces of content
- Edit the
/admin/contentview 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
| Comment | File | Size | Author |
|---|---|---|---|
| #26 | 2866386-26.patch | 1.29 KB | mbovan |
| #2 | Screen Shot 2017-04-03 at 15.59.08.jpg | 293.59 KB | dawehner |
| #3 | 2866386-3.patch | 849 bytes | dawehner |
| #4 | interdiff-2866386.txt | 970 bytes | dawehner |
| #4 | 2866386-4.patch | 867 bytes | dawehner |
Comments
Comment #2
dawehnerHere is a screenshot of what happens.
Comment #3
dawehnerHere 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.
Comment #4
dawehnerThis fixes problems on some installations for me.
Comment #5
sluceroI believe this and #2703771: Pager with AJAX and path alias sets Views argument incorrectly are both addressing the same issue.
Comment #6
sluceroI was facing this same issue on other views with AJAX enabled. The patch in #4 fixed it for me in all cases.
Comment #7
dmsmidtCould 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!"
Comment #10
ckaotikI 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())inviews_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_pathvariable/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.pathservice 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 (fromUrl::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 ;)Comment #11
ckaotikLet's test this-
Comment #12
ckaotikBack to needs work for adding tests.
Comment #13
socialnicheguru commentedthank you. this fix worked for me.
Comment #15
rob230 commentedThis patch #10 breaks some of my custom code.
For example I have a view which uses this code to get the current path:
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...
Comment #16
berdirThe amount of duplicate and related issues about this is pretty mind-blowing
I found:
* #2844823: Views exposed form action incorrect for embedded views' displays with other displays with paths
* #3000383: Assert the current path on Views AJAX requests is not set with two leading slashes
* #2773229: view path on ajax_views.js save the wrong path after ordering table by a field
* #2703771: Pager with AJAX and path alias sets Views argument incorrectly
* #2820347: Exposed filter reset redirects user to 404 page on AJAX view when placed as a block
Some even have reviews and comments from @dawehner :p
Comment #18
jordik commentedI 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.
Comment #19
joegl commentedI 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:
#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.
Comment #20
lendudeHere 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
Comment #22
neclimdulI 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.
Comment #23
lendude@neclimdul good point, lets put that back in, doesn't seem like that change is needed here to fix this.
Comment #24
jasonawantAdded related issues identified in #16 and then added this #2504115: AJAX forms should submit to $form['#action'] instead of <current>
Comment #25
maximpodorov commentedProbably 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
Comment #26
mbovan commentedSince 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.
Comment #27
mbovan commentedUpdated the issue title to match the test coverage from #26.
Comment #28
berdirGreat, some extra test coverage seems useful for this as earlier fixes and patches in other issues weren't enough to fix it.
Comment #29
alexpottI 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!
Comment #32
liquidcms commentedI 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.
Comment #33
jeeba commentedSo 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.
Comment #34
lendude@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!