如何在Perl CGI脚本中进行分页?

时间:2010-09-15 12:55:34

标签: perl cgi

我有一个带有表的CGI页面,该表通过从数据库中获取数据来填充,就像DATAGRID一样。

就在网格的右下角,我需要一个像“First<< 1>> Last”这样的链接 或点击“|<<>> |”点击,我可以在记录之间导航。而且我打算每页有“10”记录。

在浏览时我得到了一段代码,我将在代码字段中粘贴。但问题是它显示的分页链接类似于“1 2 3 4 5 ..等等”。但是我不愿意使用这种分页格式,因为记录数增加了链接的长度也在不断增加。那么这段代码可以修改为我打算拥有的格式吗?

#!C:\perl\bin\perl.exe -wT

use CGI;
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use strict;
use warnings;
use DBI;
my $query = new CGI;
my $bornum;
my $itemnum;
my $i;
my @overduedata;
my $pageNum =$query->param('pageNum');
print "Content-Type: text/html\n\n";

unless($pageNum) {
   $pageNum=0;
 }
my $offset=$query->param('offset');
unless($offset) {
    $offset=10;
 }
$i=0;
my $numOfRec = 100;
while ($i < $numOfRec){
   $bornum = "bornum" . $i;
   $itemnum = "itmnum" . $i;
   push (@overduedata, { bornum => $bornum, itemnum => $itemnum });
   $i = $i + 1;
 }

print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">";
print "\n<form>";
print "\nNo: of records per page : <input type=text name=offset>";
print "\n<input type=submit value=submit>";
print "\n</form>";
print "\n<br> No: of rec per page = " . $offset . " -- pageNum = " . $pageNum ;
print "<table border=1>";

my $startDisplay = ($pageNum) * $offset;
my $endDisplay = ($pageNum + 1) * $offset;
$i = $startDisplay;
while ($i < $endDisplay){
   print "<tr><td>" . $i . "</td><td>" . $overduedata[$i]->{'bornum'} . "</td><td>" .
          $overduedata[$i]->{'itemnum'} . "</td></tr>";
   $i = $i + 1;
 }
print "</table>";

my $numofPages = $numOfRec / $offset;
$i = 0;
print "<table border=1><tr>";
while ($i < $numofPages){
     print "<td> <a href = ?pageNum=" . $i . "&offset=" . $offset . ">" . 
             $i . "</a></td>";
     $i = $i + 1;
}
print "<tr></table>";


---------------------------------------------------------------------------------------

2 个答案:

答案 0 :(得分:2)

我想你可能想要Data::Pageset

答案 1 :(得分:1)

如果你不喜欢的是链接,那么你可以在最后修改循环以打印你想要的链接。这只是操纵页码的问题。

(我不知道你在哪里得到这个代码,但“第0页”对于那些已经使用0偏移数十年的程序员来说也不是用户友好的!如果你知道你的页面大小,那么偏移是不必要的数据,因为它表示更多的页面大小,它也错误。)

所以最简单的改变是:

my $pageN;
if ( $pageNum > 0 ) { 
    print q[<td><a href="?pageNum=1">|&lt;</a></td>];
    $pageN  = $pageNum - 1;
    print qq[<td><a href="?pageNum=$pageN">&lt;</a></td>];
}
else  { # don't link to the current page
    print q[<td><span class="currentpage">|&lt;</span></td>];
    print q[<td><span class="currentpage">&lt;</span></td>];

}

if ( $pageNum < ( $numofPages - 1 )) { 
    $pageN  = $pageNum + 1;
    print qq[<td><a href="?pageNum=$pageN">&gt;</a></td>];
    print qq[<td><a href="?pageNum=$numofPages">&gt;|</a></td>];
}
else { # don't link to the current page
    print q[<td><span class="currentpage">&gt;</span></td>];
    print q[<td><span class="currentpage">&gt;|</span></td>];
}

只需注意:不链接到当前页面有助于用户更快地了解他们在列表中的位置。此外,这意味着他们无法点击服务器只是来重新加载页面。您希望能够清楚地传达他们已经在第一页或最后一页。

但是,您的部分问题是如何在Perl CGI 中执行此操作。使用实际的Perl CGI,您不需要print '<td>'。您可以使用方法创建标记:

my @cells 
    = map { 
        my ( $page, $text ) = @$_;
        ( $query->td(
                $page > 0 and $page <= $numofPages and $pageNum != $page 
                    ? $query->a( { href => "?pageNum=$page" }, $text )
                    : $query->span( { -class => 'currentpage' }, $text )
          ), "\n"
        )
    } ( [ 1                 => '|&lt;' ]
      , [ ( $pageNum - 1 )  => '&lt;'  ]
      , [ ( $pageNum + 1 )  => '&gt;'  ]
      , [ $numofPages       => '&gt;|' ]
      )
    ;

print $query->table( 
      { -class => 'pagenav', -border => 1 }
    , $query->Tr( { -class => 'pagenavrow' } @cells )
    );

你应该注意我也修改了它,所以你的第一页也是#1。

由于您表示您可能还需要一些页码,因此仅限于此 我必须做的调整是计算最小 - 最大范围,如下:

use List::Util qw<max min>;
my $min_page = max( 1, $pageNum - 5 );
my $max_page = min( $numofPages, $min_page + 10 );
$min_page    = max( 1, min( $min_page, $max_page - 10 ));

并使用这些值将已编号的页面链接添加到传递给创建map的{​​{1}}的列表中:

@cells