I was using the pager functionality as an infinite pager, displaying one node item and using the page id. This worked great and I could access pages by going directly to that content using the page number e.g.:

/page/single_page?page=0

Unfortunately, I came across a bug where when I access a page directly through the URL, the AJAX pager would not work anymore.

I traced it down to line 51 in /includes/ajax.inc. The page $_GET query parameter set in the URL (?page=5) simply overrode the $_POST page variable. Therefore, the pager stayed on the same page.

To fix this, I simply used array_merge, providing the POST var as a last array, overriding any GET parameters that have the same key. This way we treat any vars submitted via $_POST in favour of the same parameters supplied through $_GET.

--- docroot/sites/all/modules/contributed/views/includes/ajax.inc
+++ docroot/sites/all/modules/contributed/views/includes/ajax.inc
@@ -48,7 +48,10 @@ function views_ajax() {
 
       // Add all $_POST data, because AJAX is always a post and many things,
       // such as tablesorts, exposed filters and paging assume $_GET.
-      $_GET += $_POST;
+      // Assume the $_POST is the correct data. Use array merge
+      // overriding any $_GET variables with the same key.
+      // OLD: $_GET += $_POST;
+      $_GET = array_merge ( $_GET, $_POST );
 
       // Overwrite the destination.
       // @see drupal_get_destination()
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mvlabat’s picture

This topic is old enough... But is it still actual?

dawehner’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

This would probably automatically fixed if you use another pager ID.

Needs work because of missing tests and codestyle, sorry.

John Pitcairn’s picture

Status: Needs work » Closed (works as designed)

Using a different pager ID does allow an ajax pager to work if there is a page set in the url. No fix required.

IRuslan’s picture

Status: Closed (works as designed) » Needs work

Problem is still active. It's independent from name of argument.
It's caused by next facts:
1. For first link of pager we have no page attribute (same for First link, and in some cases for Previous)
2. During ajax paging GET and POST merged

As a results in POST page parameter omitted when we go to first page, but it's overridden by other value from GET.
So if user go to page with &page=X, when he tries to go to first page, he will see page number X.

mvlabat’s picture

Try using this module. It's a sandbox project but anyway it supports ajax paging with no errors. I'm using it on my production site. And in addition it changes URL by itself, so you can navigate pages with browser's "back" and "forward" buttons. It also supports exposed filters. I think this module is useful for everybody who uses AJAX in Views.

To install it you'll need to download the package with git.

maximpodorov’s picture

I confirm the problem in the current Views.

baldwinlouie’s picture

FileSize
3.58 KB

I can confirm this problem as well. My use case is a little different. I have an AJAX enabled view with exposed filters. For my case, if the view page is accessed with GET parameters in the URL, subsequently, if I unselect all my filters, I hit this same problem.

Here is how you can reproduce my issue:
1. Use the attached view. It is a simple view that has AJAX enabled and exposed filter on content_type
2. Access the view like such: http://DRUPAL_ROOT/admin/content/doc-test-2?type[webform]=webform
3. In the exposed filter, try to unselect all content types and refresh the view.
4. You will see that without any content types selected, it will default back to webform as the content_type.

baldwinlouie’s picture

lmeurs’s picture

Version: 7.x-3.3 » 7.x-3.x-dev
Status: Needs work » Needs review

Confirm. Because AJAX always uses the POST method, the $_POST array contains the most recent parameters. This is why the patch from #1 changes the original

$_GET += $_POST;

into

$_GET = array_merge ( $_GET, $_POST );

The latest stable and dev releases of Views accomplished the same doing:

$_GET = $_POST + $_GET;

The problem is that this also copies parameters from $_GET that are not defined in $_POST.

Example:

Say the URL of the current page is ie. /my/view?page=1 (page 2) and the user clicks on a pager link to /my/view (page 1). The URL in the address bar remains /my/view?page=1 (page is a GET parameter) and /my/view is being requested through AJAX (POST method). Since $_POST['page'] is undefined, $_GET['page'] is wrongly being used.

Why extend $_GET and not start with an empty array? I guess all we need are the most recent parameters from $_POST and $_GET['q']. On a view with many filters and table sort I successfully tried:

$_GET = $_POST + array('q' => $_GET['q']);

I also successfully tried this with fake parameters /my/view?title=searchstring&type=All&status=All&page=2&order=title&sort=asc&foo=bar, and they remained in tact.

(Sorry, still do not know how to create a patch...)

lmeurs’s picture

Just updated to 7.x-3.8 and the problem still occurs. I have not tried the current dev version, but looked at the code and it seems the same as the stable version.

This can be easily tested using Admin views for the content overview with enough nodes to force a pager. Visit admin/content?type=All&status=All&page=1 and try to go to page 1 using the AJAX pager. The throbber appears and disappears, but the content overview remains the same.

Fix from #9 seems to solve it for 7.x-3.8 as well.

markhalliwell’s picture

Assigned: jnpwebdeveloper » Unassigned
Status: Needs review » Needs work
FileSize
1.04 KB

I agree with the approach in #9 (avoids having to do page=0 on page one links). Here's a patch of that against the latest dev. As far as adding tests, that is not my area of expertise, so setting to CNW for now.

markhalliwell’s picture

quotesBro’s picture

Title: If page set in URL AJAX pager does not work anymore » AJAX pager does not work if page number set in URL

#11 worked for me.

Valentine94’s picture

Status: Needs work » Needs review

Bot

Status: Needs review » Needs work

The last submitted patch, 11: if_page_set_in_url_ajax-1786524-11.patch, failed testing.

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 11: if_page_set_in_url_ajax-1786524-11.patch, failed testing.

lmeurs’s picture

I am unfamiliar with automated testing, but the message Failed to run tests probably indicates that the tests are not working correctly, an expected result of failure is ie. FAILED: [[SimpleTest]]: [MySQL] 57,781 pass(es), 19 fail(s), and 57 exception(s).

Can anyone shine his / her light on this?

DeFr’s picture

Cross-linking #1482824: Block display view ajax pager does not advance with multiple pagers on a page when the first pager > 0 in there. The patch contained in its comment 14 fixes the bug too, but in a more backward compatible way: instead of only whitelisting 'q' to go through, it only stops 'page' from being propagated.

lmeurs’s picture

@DeFr: Thanks for the crosslink! I just tested the patch and it solves the problem from this issue so far as well. The solution looks more stable and the patch has been successfully tested by the test bots, but since the problems seem different I cannot set the other issue to RTBC and thus will keep this issue open till the patch has been committed.

alesr’s picture

qzmenko’s picture

If someone googled this page, the solution for D7 is in this issue:
#2805539: Views argument set incorrectly when using AJAX pagination and a path alias