coldfingertips has asked for the wisdom of the Perl Monks concerning the following question:

This was asked in the CB earlier and I made a few attempts but the morning is catching up to me and for some reason I can't think of the way to do this!

I'm pulling records from a database and I need to break it up into managable pages (15 per page for now but I'll change it later if I need). This means page=1 would display items 0-14, page=2 would display 15-29, etc.

my $page = url_param("page"); if ($page) { my $per_page = 15; my $count_low = $per_page - 1; my $count_high = }
Something was wrong with my logic in determining what items are expected to be called on that page and this is where I need your help. I need the calculations to determine the first and the last record needed to be printed based on the url_param page number. I know this is easy but I'm making this harder than it has to.

Replies are listed 'Best First'.
Re: Number of listings per page
by eric256 (Parson) on Feb 22, 2005 at 18:50 UTC

    You can always use a nice module like Data::Page to help you with it.

    use strict; use warnings; use Data::Page; my $page = Data::Page->new($records, 15, url_param("page")); my $first = $page->first; my $last = $page->last; my $next_page = $page->next_page; my $prev_page = $page->previous_page;


    ___________
    Eric Hodges
Re: Number of listings per page
by dragonchild (Archbishop) on Feb 22, 2005 at 18:19 UTC
    The low is N * P + 1. The high is N * (P + 1). So, if N is 15 and P is 0 (first page), you have 1-15. If P is 3 (4th page), then you have 46-60.

    If your pages start from 1, then you have N*(P-1)+1 and N*P.

    The way to solve these problems is to generate some sample results, then determining the pattern from them. Most mathematical equations are not written, then proven. You usually have a pattern, you map an equation to it, then you try and prove it for values beyond your pattern.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: Number of listings per page
by brian_d_foy (Abbot) on Feb 22, 2005 at 21:13 UTC
Re: Number of listings per page
by friedo (Prior) on Feb 22, 2005 at 18:21 UTC
    Assuming you always want 15 items per page, I would just do something like:

    my $page = url_param('page'); my $per_page = 15; if($page) { my $min = $page == 1 ? $page : $page_per * ($page - 1); my $max = $page_per * $page; }

    This gives you some overlap (1-15, 15-30, 30-45, etc.) If you don't want overlap, it's easy to modify.

Re: Number of listings per page
by injunjoel (Priest) on Feb 22, 2005 at 19:31 UTC
    Greetings all,
    Depending on the DataBase you are using to pull the records from I would suggest something akin to "LIMIT 15 OFFSET 0" (<= this is MySQL syntax but you get the point) then on subsequent requests pass along your offset incremented by the limit. This way you let the DB do the pagination work for you.
    A quick example (moving forward through your data):
    my $offset = url_param('offset') || 0; my $sth = $dbh->prepare("SELECT * FROM foo WHERE something = 1 LIMIT 1 +5 OFFSET $offset"); my $rv = $sth->execute(); my @data; if($rv && ($rv ne "0E0")){ while($_ = $sth->fetchrow_hashref()){ push @data, $_; } $sth->finish(); } #set up the offset for the next page $offset += 15;
    One of the things you might want to do as well is pass a direction for your pagination... you wouldn't want to limit users to only traversing forward through your records right? Pass a param called "direction" or "dir" set to either "fwd" or "rev" and set your offset accordingly.
    HTH

    -InjunJoel
    "I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo
Re: Number of listings per page
by artist (Parson) on Mar 01, 2005 at 22:02 UTC
    I found this somewhere, I don't know the source. Helpful to build next, previous links also.
    sub BuildNextPrevLinks { my ($query,$blankon,$total,$numdisplay,$position) = @_; my ($startno,$endno,$prevstring,$nextstring,$firststring,$laststri +ng); my ($lastpagenum,$laststart); return unless ($total || $blankon); $numdisplay=15 unless $numdisplay; # calculations need to be based on total found not our display tot +al if ($total > $numdisplay) { $startno = $position+1; $endno = $startno + ($numdisplay - 1); $endno = $total if ($endno > $total); } else { # when we have less than the number of rows passed in $startno = 1; $endno = $total; } if ($position>=$numdisplay) { my $newquerystring; my $prevstart = $position - $numdisplay; my $prevlink = &EditQueryString($query,'position',$prevstart); $prevstring="<a href=\"$prevlink\">Previous $numdisplay</a>"; my $firstlink = &EditQueryString($query,'position',0); $firststring="<a href=\"$firstlink\">First $numdisplay</a>"; } else { $prevstring="Previous $numdisplay" if ($blankon); $firststring="First $numdisplay" if ($blankon); } if ($endno<$total){ my $nextstart = $position + $numdisplay; my $how_many_left = $total - $nextstart; if ($how_many_left > $numdisplay) { $how_many_left = $numdisplay; } my $nextlink = &EditQueryString($query,'position',$nextstart); $nextstring="<a href=\"$nextlink\">Next $how_many_left"; $lastpagenum = ($total % $numdisplay); $laststart = $total - $lastpagenum; my $lastlink = &EditQueryString($query,'position',$laststart); $laststring="<a href=\"$lastlink\">Last $lastpagenum</a>"; # $laststring="<a href=\"$lastlink\">Last $lastpagenum</a>"; } else { $nextstring="Next $numdisplay" if ($blankon); $laststring="Last $numdisplay" if ($blankon); } return ($firststring,$prevstring,$nextstring,$laststring,$startno, +$endno); }