Hi all

I have a reasonably new drupal site that I'm putting together and I'm reasonably new to using it. I've searched for this problem I'm having but have been unable to either find it or search for the right thing.

I have a view, which displays as a list in a page, with 20 nodes per page, across 3 pages. I am displaying the results in random ascending order.

Once the first page is displayed and I decide to go to the next page by selecting either page 2, next or last at the bottom I run into the issue that I get the results regenerated. So instead of getting page 2 of my original search, it seems to give me a new set of results on page 2. However I still have the ability to go back to page 1 or 3, so it realises it's still on page 2.

Is it possible to have my original search displayed throughout the 3 pages, so that nodes aren't displayed on all 3 pages potentially?

I hope this is clear.

Thanks

Comments

edrex’s picture

i guess no-one has ever had a use-case for paged randomness. it's hard to even imagine how that would work. random is usually used to call out some limited fixed number of items.

edrex’s picture

do you have a use-case?

develcuy’s picture

Not until now :) CCKRand is featured to provide a field which is configurable to be reindexed with random values every n seconds by cron run. It is enabled to provide a sort criteria, so you can randomize order in your views.

--
develCuy's fruits
(3 John 1:2) Dear friend, I pray that you may enjoy good health and that all may go well with you, even as your soul is getting along well.

paulnem’s picture

The idea behind the view is this,

Users create advertisements/listings for services that they offer. A small picture and descriptive title is displayed in the view in a random order, as services/advertisements do not expire as long as they are paid for we can end up with quite a few, so we don't want the same ones displaying on the first page always.

There are options to filter down into these advertisments, based on location in the city and we've also implemented more descriptive categories for the advertisements to limit how many are displayed per search.

The reason I've picked 20 advertisments, 5 per line with 4 lines, is that it seems a reasonable amount to display without becoming just a little too much for the page and the viewer.

edrex’s picture

i guess the problem is that the way views' random sorting works now, a new random "seed" is used for each non-cached page hit. This is the behavior people expect in the vast majority of cases (rotating random image etc). Paging (as in the pager) generates a new page hit, which naturally re-randomizes. So essentially the two features (random sort and pager) are incompatible.

If you really need this feature, and have some php chops, you could make a copy of the random sort (in your own module) and then modify it to cache the random seed in the user's session or something. Not sure how that would work. Good luck!

paulnem’s picture

Does anyone have any other thoughts on this issue?

I've emailed the views developer, who doesn't think it is possible even if money is offered (I thought money solved everything!)

I would be interested to hear if anyone had an idea to have this functionality work and get it into the views module. I obviously want it to be in a standard module for future use.

meeotch’s picture

I realize this thread is almost a year old - but I've got a need for the same functionality. Application is similar: I want to display a list of users, sorted randomly so that the same ones don't always end up on the first page, but not trigger a "reshuffling" of the order when going to subsequent pages.

One thought: I'm not sure if Drupal generates a unique session ID per login - but maybe it's possible to hack the views module to seed the random number generator with that.

The Views maintainer has marked this issue "wontfix". http://drupal.org/node/156335 Though, honestly, it seems like logical functionality to include.

michellepurestock’s picture

I have the same issue as meeotch. I am trying to sort a view randomly of users in a block but I get repeats of the same users in the view. Sometimes two or three repeats of a user. When you reload the page that the block is on, I do get a new sort but there is always at least one user doubled up on the page.

alan d.’s picture

While it is possible to do the requested functionality, it would require significant work

An pseudo-random solution could use the following logic:

1) Add a new CCK field of type int, no edit or display

2) Create a cron_hook that inserts random numbers into this field

3) Present the view sorted by this random field

Then everytime cron runs you'll get a new sort order. I'd set the cron to reload once a day, so that the pager works for the majority of the day.

Or if you want some good old hacking fun, read on...

A true session based would require a full query to be done to create the indexing. This would then be stored in the session. Personally, I would create a custom module based block or page callback. View do not handle special sorting fields. (Please correct me if you discover that I'm wrong.)

Using a custom array paginator, you can then generate what pages/users to load. See the code snippet in http://drupal.org/node/211819#comment-847409 for the pager.

The query would be similar to this: (This is how views generate their queries)

SELECT node.nid, node.title AS node_title, node.changed AS node_changed, node_data_field_image.field_image_fid AS node_data_field_image_field_image_fid, node_data_field_image.field_image_title AS node_data_field_image_field_image_title, node_data_field_image.field_image_alt AS node_data_field_image_field_image_alt
FROM node node
LEFT JOIN content_type_site node_data_field_site_category ON node.vid = node_data_field_site_category.vid
LEFT JOIN content_field_image node_data_field_image ON node.vid = node_data_field_image.vid
LEFT JOIN content_type_site node_data_field_visit_website ON node.vid = node_data_field_visit_website.vid
WHERE (
node.status = '1'
)
AND (
node.type
IN (
'site'
)
)
AND (
node_data_field_site_category.field_site_category_value =1
)
ORDER BY FIELD( node.nid, 95, 96, 97, 100, 103) ASC
LIMIT 0 , 5

(EDIT: Or seed the engine to simplify the query. Duh)

Where the values, 95, 96, 97, 100, 103 are the values returned by the pager. Make sure that the limit is the same as the count() of the order fields.

I think that it could be a day or two of solid programming to get this running. Use the Devel module to capture the views SQL statement. And remember that the CCK tables change under certain circumstances, so if a field is changed from single to multi, the SQL will also change.


Alan Davison
www.caignwebs.com.au

Alan Davison
summit’s picture

Subscribing greetings, Martijn

meeotch’s picture

Ha! I had the same thought (cron job to reorder a CCK field), then checked this thread on a whim, and there it was. I suppose rearranging once or twice a day would be good enough for my application.

Question: Is there a way to hide the field in the view? (Besides CSS display:none - which I got working, but which apparently google doesn't approve of.)

alan d.’s picture

This was off the main topic but here is a starting point for

  1. Random user block
  2. Random user page

This uses a simple session based seed for the page, and the block is regenerated on each load.

Play, modify and share :)

random_users.info

; $Id$
name = Random users
description = Some session based random madness
package = Other
version = VERSION

random_users.module

<?php

/**
 * Implementation of hook_help().
 */
function random_users_help($section) {
  switch ($section) {
    case 'admin/help#random_users':
      return t('Generates a block and a paged list of users.');
  }
}

/**
 * Implementation of hook_menu().
 */
function random_users_menu($may_cache) {
  $items = array();

  if ($may_cache) {
    $items[] = array('path' => 'users',
      'title' => t('User list'),
      'callback' => 'random_users_list',
      'access' => user_access('access content'),
      'type' => MENU_SUGGESTED_ITEM);
  }
  return $items; 
}

/**
 * Implementation of hook_block().
 */
function random_users_block($op = 'list', $delta = 0, $edit = array()) {

  if ($op == 'list') {
     $blocks[0]['info'] = t('Random users list');
     return $blocks;
  }
  else if ($op == 'configure' && $delta == 0) {
    $form['random_users_block_number_users'] = array(
      '#type' => 'textfield',
      '#title' => t('Number user to display.'),
      '#default_value' => variable_get('random_users_block_number_users', 10),
    );
    return $form;
  }
  else if ($op == 'save' && $delta == 0) {
    variable_set('random_users_block_number_users', $edit['random_users_block_number_users']);
  }
  else if ($op == 'view') {
    if (user_access('access content')) {
          $result = db_query_range('SELECT uid, name FROM {users} WHERE status != 0 AND access != 0 ORDER BY RAND()', 0, variable_get('random_users_block_number_users', 10));
          while ($account = db_fetch_object($result)) {
            $items[] = $account;
          }
          $output = theme('user_list', $items);

          $block['subject'] = t('Some users');
          $block['content'] = $output;
          return $block;
    }
  }
}

/**
 * 
 */
function random_users_list() {
  if (empty($_SESSION['random_users_list'])) {
    $_SESSION['random_users_list'] = rand(1, 999999);
  }
  $seed = $_SESSION['random_users_list'];
  // Extract the affected users:
  //$query, $limit = 10, $element = 0, $count_query
  $result = pager_query("SELECT u.uid FROM {users} u WHERE u.access != 0 AND u.status != 0 ORDER BY RAND(%d)", 20, 0, NULL, $seed);

  $output = '<div id="users-list">';
  while ($account = db_fetch_object($result)) {
    $account = user_load(array('uid' => $account->uid));
    $output .= theme('user_listing', $account) . '<br class="clear"/>';
  }
  $output .= '</div>';
  $output .= theme('pager', 20, 0);
  return $output;
}

function theme_user_listing($account) {
  return '<div>' . theme('username', $account) . '</div>';
}

?>

Alan Davison
www.caignwebs.com.au

Alan Davison
swentel’s picture

This is actually pretty easy, see http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#funct... (and much more sane than the cck rand solution)
I'm currently working on a patch for views 2 which will either add the functionality in the existing random field or I'll release a new module. I'll see if I can backport it easily to views 1.

swentel’s picture