Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Printing "X" amount of records

Status
Not open for further replies.

yolond

Technical User
Jan 5, 2001
9
I have written a script that reads a database among other things. My problem is this. As the script is now, it'll read the entire database and print out each line (of the entire database) nicely formatted (using the FOREACH). What I want to do is grab 'x' amount of records, click next, get the next 'x' amount of records until all records are viewed.

How would I go about doing this? I'm fairly new to perl programming from scratch and would appreciate any help.
 
I pretty sure my way is not the best way, as it performs a complete database lookup each time, but it works for me. if someone has a better way, please post it.
basically, i have the script with a couple extra variables, $start_index and $page_limit, which are passed to the script from the calling page, or set automatically. it prints "$page_limit" number of entries from the point "$start_index" on. This is assuming the database has been put in an array form (which i call @data). this script example also assumes that the the html formdata was parsed into a hash(%formdata).
then, for the previous and next buttons, it increments or decrements the "$start_index" by "$page_limit", and has a form submitted to itself. if other variables are needed by the cgi, add a "hidden" input to the bottom form for each one.[tt]

#the database calls and basic cgi stuff that you already
#have would be above, but not the foreach loop...

my $start_index = ( $formdata{start_index} || 0 );
my $page_limit = ( $formdata{page_limit} || 20 );

for (my $i = $start_index; $i <= @data &&
$i <= $page_limit; $i++)
{
print $data[$i], &quot;\n&quot;;
}


print qq~<FORM METHOD=&quot;post&quot; ACTION=&quot;???.cgi&quot;
NAME=&quot;Next_Prev&quot;>\n~;

if ($start_index > 0 && $start_index % $page_limit == 0)
{
$start_index -= $page_limit;
print qq~<INPUT TYPE=&quot;submit&quot; NAME=&quot;Previous&quot;
VALUE=&quot;Previous&quot;>\n~;
}

if ($start_index + $page_limit < @data)
{
$start_index += $page_limit;
print qq~<INPUT TYPE=&quot;submit&quot; NAME=&quot;Next&quot;
VALUE=&quot;Next&quot;>\n~;
}

print qq~<INPUT TYPE=&quot;hidden&quot; NAME=&quot;page_limit&quot; VALUE=
page_limit>\n~;
print qq~<INPUT TYPE=&quot;hidden&quot; NAME=&quot;start_index&quot; VALUE=
$start_index>\n</FORM>\n</BODY>\n</HTML>\n~;
[/tt]

Please note, the print statements that overflow onto two lines really should be only one, and i indented them for readability. i used qq~~ instead of &quot;&quot; so i wouldn't have to escape the quotes inside. also, you could hardcode the $page_limit to 20 or whatever if it's never going to change.
hope this works for you. but actually, i hope someone posts something better.
&quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
Hmmm, I must be doing something wrong. I get several next/previous buttons on one output. Below is my subroutine along with my commented out foreach. Do I still need that? Or am I misnaming my arrays.

Code:
sub view {

# Read the database.
open(RESOLVED,&quot;<$done_file&quot;) || &ErrorMsg(&quot;Could not open file '$done_file'&quot;);
@resolved = <RESOLVED>;
close(RESOLVED);

&getdate;
&links;

print &quot;Content-type: text/html\n\n&quot;;
print qq~<html>
<head>
<title>$title</title>
</head>

<$body>
$logo

<center><table width=&quot;580&quot;>
  <tr><td align=center><$font>
	$links
	<br><br>
  <b>Here are the System Administrator Support Requests that have<br>been completed to date:</b>
  <font color=FF9900><b>$date</b></font>
  <br><br><br>
~;

@data = ($date_in,$time_in,$email,$domain,$task,$date_out,$time_out,$resolution,$tech);

my $start_index = ( $data{start_index} || 0 );
my $page_limit = ( $data{page_limit} || 2 );

for (my $i = $start_index; $i <= @resolved && 
     $i <= $page_limit; $i++)
{
	print $resolved[$i], &quot;\n&quot;;

#foreach $line (reverse@resolved) {
#	chop($line);
#	($date_in,$time_in,$email,$domain,$task,$date_out,$time_out,$resolution,$tech)=split(/\|/,$line);
#
#	$task_print = $task;
#	$task_print =~ s/``/<br>/g;
#
#	$resolution_print = $resolution;
#	$resolution_print =~ s/``/<br>/g;
#
#	print qq~
 # <table width=&quot;100%&quot;><tr>
#	<td>
#	<table cellspacing=0 cellpadding=0 border=1 width=&quot;100%&quot; bordercolor=003366 bgcolor=white>
#	  <tr><td>
#		<table width=&quot;100%&quot;>
#		  <tr><td colspan=2><$font><b>Received at:</b> <font color=FF9900>$date_in - $time_in</font></font></td></tr>
#		  <tr><td colspan=2><$font><b>$task2:</b> $task_print</font></td></tr>
#		</table>
#		<table width=&quot;100%&quot; bgcolor=&quot;#EEEEEE&quot;>
#		  <tr><td><$font><b>Completed at:</b> <font color=FF9900>$date_out - $time_out</font></font></td><td><$font><b>$tech2: </b> $tech</font></td></tr>
#		  <tr><td colspan=2><$font><b>$resolution2:</b> $resolution_print</font></td></tr>
#		</table>
#	  </td></tr>
#	</table>
#  </td></tr></table>
#  <br>
#	~;
#}


print qq~<FORM METHOD=&quot;post&quot; ACTION=&quot;sysresolve2.cgi&quot; NAME=&quot;Next_Prev&quot;>\n~;

if ($start_index > 0 && $start_index % $page_limit == 0)
{
    $start_index -= $page_limit;
    print qq~<INPUT TYPE=&quot;submit&quot; NAME=&quot;Previous&quot; VALUE=&quot;Previous&quot;>\n~;
}

if ($start_index + $page_limit < @resolved)
{
    $start_index += $page_limit;
    print qq~<INPUT TYPE=&quot;submit&quot; NAME=&quot;Next&quot; VALUE=&quot;Next&quot;>\n~;
}

print qq~<INPUT TYPE=&quot;hidden&quot; NAME=&quot;page_limit&quot; VALUE=page_limit>\n~;
print qq~<INPUT TYPE=&quot;hidden&quot; NAME=&quot;start_index&quot; VALUE=$start_index>~;

}

print qq~
  </font></td></tr>
</table></center>

</body>
</html>
~;
}
 
errr, okay, what the code needs is this:

the previous and next buttons shouldn't be inside the for loop, they should be printed afterwards.
also, you seem to want your loop to be applied to the reverse of your data, so do that first.
as for the body of the for loop, make it exactly what your foreach loop is (a foreach loop is really just a special case of a for loop. you have to generalize it to only iterate over the specified indexes), except replace every instance of &quot;$line&quot; with &quot;$_&quot;, so it'll look something like:[tt]
@resolved = reverse @resolved;

for ($i = $start_index; $i <= @resolved &&
$i <= $page_limit; $i++)
{
chop($_);
($date_in,$time_in,$email,$domain,$task,$date_out,$time_out,$resolution,$tech)=split(/\|/,$_);
#et cetra, et cetra, until the end of all your formatting
#then, end the loop and print out the previous/next button
}

if ($start_index > 0 && blah blah)
{
#i think you should understand now[/tt]


in fact, as i wrote it here, put the rest of your original foreach loop into the for loop, make sure the for loop ends first, then print out the next/previous buttons. remove the line you had above the loop, assigning @data as you did. this isn't needed. &quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top