views:

128

answers:

2

I have a CGI page with a table which is populated by fetching the data from database, in a word its like a DATAGRID.

And just at the bottom right end of tha Grid I need a link like "First << 1 2 >> Last" or like" |< < > >| "on clicking which I can navigate to and fro the records. And I am intend to have "10" records per page.

While surfing I got a piece of code which I am going to paste in the code field. But problem is that it displays the paging link something like this "1 2 3 4 5 ..and so on". But I am not willing to have this paging format because the number of records increases the length of the link also goes on increasing. So can this code be modified to the format which I am intending to have?

#!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>";


---------------------------------------------------------------------------------------
A: 

I think you probably want Data::Pageset.

davorg
First of all i would want to thank you for your instant reply.Sir i went through the link which you have specified and i downloaded the tar file available in D Drive.But i got confused as which code and where am i supposed to put in my code.So i have pasted my code as well in the code field now. So kindly Please guide me as to what to do further. Thank you sir.
sonya
You need to install it. Perl has a system for it. Type 'cpan Data::Pageset' into a shell and (if the shell can find the cpan command) the code will not only be downloaded, it will also be installed and its dependencies too.
reinierpost
What's up with all the "sir"s and "boss"es lately?
Ether
Shell? Actually am not into UNIX or LINUX. I am working on WINDOWS(XP) Platform. This Data::Pageset Wont work on windows?Please DO Let Me know.
sonya
Are you trying to tell me that Windows doesn't have a shell? That's nonsense. Been years since I used Windows for development but it used to be called command.com. I think you're using ActivePerl. That has its own mechanism for installing CPAN modules. Try reading the documentation. http://docs.activestate.com/activeperl/5.10/faq/ActivePerl-faq2.html
davorg
Thanks a lot for the information .I would surely go through the link and get the things working Mr.davorg and get back to you if i face any problem further.
sonya
+1  A: 

If all you don't like are the links, then you can modify the loop at the end to print the links you want. It's just a matter manipulating page numbers.

( I don't know where you got this code, but "page 0" is not user-friendly to even programmers who have been working with 0 offset for decades! And if you know your page size, the offset is needless data, and as it indicates more page size, it's also wrong. )

So the simplest change is:

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>];
}

Just a note: not linking to the current page helps a user understand quicker where they are in the list. Also it means that they can't hit the server just to reload the page. You want to be able to clearly communicate that they are already on the first or last page.

However, part of your question is how would you do that in Perl CGI. Using actual Perl CGI, you don't print '<td>'. You use methods to create tags:

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 )
    );

You should note that I also modified it so that your first page is #1 as well.

Since you indicated that you might want some page numbers as well, the only adjustment I had to make was to compute the min-max range, like so:

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 ));

And use those values to add numbered page links to the list passed to the map creating @cells:

  ( [ 1                 => '|&lt;' ]
  , [ ( $pageNum - 1 )  => '&lt;'  ]
  , ( map { [ $_ => $_ ] } $min_page..$max_page )
  , [ ( $pageNum + 1 )  => '&gt;'  ]
  , [ $numofPages       => '&gt;|' ]
  ) 
Axeman
Thanks a lot for the help Mr.axeman, i will go through the code and get back to you once am done with it and if i face ant problem implementing it.Thankyou.
sonya
Hello,i tried using the above code bt i got an errors i.e at the line.. "? $query->a( { href => "?pageNum=$page" }, $text ) [ERROR is : Can't call method "a" on unblessed reference line 98.]". What is this unblessed reference and how do i elimanate that?Please can sombody help me sort this out? Thank you.
sonya
@sonya: The code originally posted had `my $query = new CGI;` My suggestion was to replace *parts* of the script with new behavior, not as a rewrite. If `CGI->new` is returning `undef`, you have a whole other problem.
Axeman