Is it possible to make the views block with a pager activated to remember last clicked page? Currently, after switching to any page of the block's page and reloading browser page it sets back to initial position. Which is very much inconvenient in case if a user wants to (for example) inspect comments (for views of comment type), click to some of them to take actions (reply to comments) and wants to continue further inspection beginning from the last clicked page in the block.

Comments

dawehner’s picture

Status: Active » Fixed

Currently it's not possible without custom coding.

You could fix the issue easily if you disable ajax on the pagers.

yngens’s picture

Status: Fixed » Active

Disabling ajax does not help. Without ajax when you click to next page, it correctly opens http://mysite/photo/1/12757.7604?page=1, however as soon as you click any page '?page=1' part in URL is gone and the block's pager sets back to initial position.

I believe remembering last clicked link is very much needed functionality for the views. So if possible please leave this issue open till someone comes with the solution. For example, the same logic with using cookies could be used as in #354199: Remember last clicked tab

merlinofchaos’s picture

Status: Active » Closed (won't fix)

Sorry, this is not a feature Views supports. Neither does Drupal's core pager.

seanb’s picture

Today I needed this feature for a client of ours. The code below remembers the last page visited for every view display in the session. It only works for ajax views, because the normal pager doesn't add the view name and display id in the URL. So you can't really tell for wich view to set the page (any ideas?). You can customize it further by adding checks for view names etc. Other additions are welcome, as I can see this only works for specific cases.

// Remember pager per view (only for ajax views)
function custom_module_views_pre_execute(&$view) {
  $view_name = $view->name .'_'. $view->current_display .'_'. $view->args[0];
  if(!isset($_GET['page']) && !isset($_GET['pager_element']) && $_SESSION[$view_name] > 0){
    $_GET['page'] = $_SESSION[$view_name];
  }
  else if(isset($_GET['page']) && $_GET['view_name'] == $view->name && $_GET['view_display_id'] == $view->current_display) {
    $_SESSION[$view_name] = $_GET['page'];
  }
  else{
    $_SESSION[$view_name] = 0;
  }
}
jussil’s picture

Last post was very helpful and easy solution in order to remember the ajaxified page. There was only one problem if you are using more than one views in the page. Last solution set the query param page directly which then affects all of the views thats are being called. Instead I used $view->pager['current_page'] to set only the desired views current page and this works like a charm.

// Remember pager per view (only for ajax views)
function custom_module_views_pre_execute(&$view) {
  $view_name = $view->name .'_'. $view->current_display .'_'. $view->args[0];
  if(!isset($_GET['page']) && !isset($_GET['pager_element']) && $_SESSION[$view_name] > 0){
    $view->pager['current_page'] = $_SESSION[$view_name];
  }
  else if(isset($_GET['page']) && $_GET['view_name'] == $view->name && $_GET['view_display_id'] == $view->current_display) {
    $_SESSION[$view_name] = $_GET['page'];
  }
  else{
    $_SESSION[$view_name] = 0;
  }
}
laraz’s picture

Version: 6.x-3.x-dev » 7.x-3.3

I need this feature in drupal 7 and views version 7.x-3.3.

Does this feature works in Drupal 7?

$view->pager['current_page'] is not defined in drupal 7. How I get the current page?

All my pages access to the last else $_SESSION[$view_name]=0;

tomsm’s picture

I have created a custom module with the code mentioned in #4 but the pager is not remembered.
I also tried with the code of #6.

I use views 6.x-3.0 with drupal core 6.28.

This is the contents of my "custom_module.info" file:

; $Id: mymodule5,v 6.x-dev 2012/11/08 09:17:00 tomsm $
name = Custom module
description = My custom module to remember last clicked pager of views.
package = Custom modules
core = "6.x"
version = "6.x-dev"

And this is in my "custom_module.module" file:

function custom_module_views_pre_execute(&$view) {
  $view_name = $view->name .'_'. $view->current_display .'_'. $view->args[0];
  if(!isset($_GET['page']) && !isset($_GET['pager_element']) && $_SESSION[$view_name] > 0){
    $_GET['page'] = $_SESSION[$view_name];
  }
  else if(isset($_GET['page']) && $_GET['view_name'] == $view->name && $_GET['view_display_id'] == $view->current_display) {
    $_SESSION[$view_name] = $_GET['page'];
  }
  else{
    $_SESSION[$view_name] = 0;
  }
}

What am I doing wrong? Do I need to change the name of the view?

rexmondo’s picture

Issue summary: View changes

Here is a solution that works in drupal 7 with views 3.x, as long as you have exposed filters on the view and the exposed filters are set to "remember last selection", in which case $_REQUEST will be populated if and only if you do ajax requests. This means that the view will load the last selected page when a new page with the same view is loaded.

Note that this is only tested in my system on pages that have one view of each type on the page, I'm not sure what will happen if you try to add the same view multiple times on a page, but i suspect it probably won't work.

Add the following code to a module to get this to work.

function module_name_views_pre_view(&$view) {
  $view_name = $view->name . '_' . $view->current_display;
  if(!empty($_REQUEST)) {
    $_SESSION['views_pages'][$view_name] =  isset($_POST['page']) ? $_POST['page'] : null;
  }
  $view->set_current_page($_SESSION['views_pages'][$view_name]);
}
cvbuyten’s picture

In my case the solution from Rexmondo didn't work because $_POST['page'] returned a comma separated string.
But using his example I got a working module

file: lastviewedpage.info

name = Last viewed page
description = "Remember last visited page of a view."
package = 2C
core = 7.x
files[] = lastviewedpage.module
version = "7.0"
project = "drupal"
datestamp = "1269192313"

file: lastviewedpage.module

function lastviewedpage_views_pre_view(&$view){

	$view_name = $view->name . '_' . $view->current_display;
	$page=(isset($_SESSION['views_pages'][$view_name]))?$_SESSION['views_pages'][$view_name]:null;

	if(!empty($_REQUEST)) $page=(isset($_POST['page']))?end(explode(',',$_POST['page'])):null;

	$_SESSION['views_pages'][$view_name] = $page;
	$view->set_current_page($page);
InesRg’s picture

Thanks a lot for your answer !! It works for me too

marius-guenter’s picture

This code is for "Insert Views" Views.
It also worked with ajax and Multilanguage Systems.
Here is my Code to solve the Problem:

First make a Module

Then put these Lines of code inside it.

function MYMODULE_views_pre_view(&$view)
{
	global $language;
	$l = $language->language;
	$view_name = $view->name . '_' . $view->current_display;
	$last = isset($_SESSION['pages']['last']) ? intval(trim($_SESSION['pages']['last'])) : NULL;
	if($last != NULL)
	{
		if(arg(0) == "node" && is_numeric(arg(1)))
		{
			if(arg(1) != $last && isset($_SESSION['views_pages'][$l][$view_name]['page']))
			{
				$page = isset($_SESSION['views_pages'][$l][$view_name]['page']) ? intval(trim($_SESSION['views_pages'][$l][$view_name]['page'])) : 0;
				$view->set_current_page($page);
			}
			else
			{
				$page = isset($_REQUEST['page']) ? intval(trim($_REQUEST['page'])) : 0;
				$_SESSION['views_pages'][$l][$view_name]['page'] = intval(trim($_REQUEST['page']));
			}
			
		}
	}
}

function MYMODULE_preprocess_html(&$variables) 
{	
	if(arg(0) == "node" && is_numeric(arg(1)))
	{
		$_SESSION['pages']['last'] = arg(1);
	}
}

Hope that helps.