Mewsoft::Pagination - Standalone Object-Oriented Efficient Data Pagination


Mewsoft-Pagination documentation Contained in the Mewsoft-Pagination distribution.

Index


Code Index:

NAME

Top

Mewsoft::Pagination - Standalone Object-Oriented Efficient Data Pagination

SYNOPSIS

Top

	use Mewsoft::Pagination;

	#Example data
	my $total_entries = 100;
	my $entries_per_page = 10;
	my $pages_per_set = 7;
	my $current_page = 4;

	my $paginate = Mewsoft::Pagination->new(
		total_entries       => $total_entries, 
		entries_per_page    => $entries_per_page, 
		current_page        => $current_page,
		pages_per_set       => $pages_per_set,
		mode => "slide", #modes are 'slide', 'fixed', default is 'slide'
	);

	# General page information
	print "         First page: ", $paginate->first_page, "\n";
	print "          Last page: ", $paginate->last_page, "\n";
	print "          Next page: ", $paginate->next_page, "\n";
	print "      Previous page: ", $paginate->previous_page, "\n";
	print "       Current page: ", $paginate->current_page, "\n";

	# Entries on current page
	print "First entry on current page: ", $paginate->first, "\n";
	print " Last entry on current page: ", $paginate->last, "\n";

	#Returns the number of entries on the current page
	print "Entries on the current page: ", $paginate->entries_on_current_page, " \n";

	# Page set information
	print "First page of previous page set: ",  $paginate->previous_set, "\n";
	print "    First page of next page set: ",  $paginate->next_set, "\n";

	# Print the page numbers of the current set (visible pages)
	foreach my $page (@{$paginate->pages_in_set()}) {
		if($page == $paginate->current_page()) {
			print "<b>$page</b> ";
		} else {
			print "$page ";
		}
	}

	#This will print out these results:
	#First page: 1
	#Last page: 10
	#Next page: 5
	#Previous page: 3
	#Current page: 4
	#First entry on current page: 31
	#Last entry on current page: 40
	#Entries on the current page: 10 
	#First page of previous page set: 
	#First page of next page set: 11
	#     1 2 3 <b>4</b> 5 6 7 




DESCRIPTION

Top

The standalone object-orinated module produced by Mewsoft::Pagination which does not depend on any other modules can be used to create page navigation for any type of applications specially good for web applications. For example I use it in our Forums software, Auctions, Classifieds, and also our Directory Software andmany others. It makes live easier better than repeating the same code in your applications.

In addition it also provides methods for dealing with set of pages, so that if there are too many pages you can easily break them into chunks for the user to browse through. This part taken direct from the similar module Data::Pageset. Basically this module is a duplicate of the module Data::Pageset. The reason I created this module is that all other pagination modules depends on other modules which is also dependes on others modules. So it is not good if you are building a large web application to ask your customers to install such a small module to support your product.

This module is very friendly where you can change any single input parameter at anytime and it will automatically recalculate all internal methods data without the need to recreate the object again.

All the main object input options can be set direct and the module will redo the calculations including the mode method.

You can include this module with your applications by extracting the module package and copying the module file Pagination.pm to your application folder and just replace this line in the above code:

use Mewsoft::Pagination;

by this line:

use Pagination;

You can even choose to view page numbers in your set in a 'sliding' fassion.

METHODS

Top

new()

	use Mewsoft::Pagination;
	my $paginate = Mewsoft::Pagination->new(
		total_entries       => $total_entries, 
		entries_per_page    => $entries_per_page, 
		current_page        => $current_page,
		pages_per_set       => $pages_per_set,
		mode => "slide", #modes are 'slide', 'fixed', default is 'slide'
	);

This is the constructor of the object.

SETTINGS are passed in a hash like fashion, using key and value pairs. Possible settings are:

total_entries - how many data units you have,

entries_per_page - the number of entries per page to display,

current_page - the current page number (defaults to page 1) and,

pages_per_set - how many pages to display, defaults to 10,

mode - the mode (which defaults to 'slide') determins how the paging will work.

total_entries()

  $paginate->total_entries($total_entries);

This method sets or returns the total_entries. If called without any arguments it returns the current total entries.

entries_per_page()

  $paginate->entries_per_page($entries_per_page);

This method sets or returns the entries per page (page size). If called without any arguments it returns the current data entries per page.

current_page()

  $paginate->current_page($page_num);

This method sets or returns the current page. If called without any arguments it returns the current page number.

mode()

	$paginate->mode('slide');

This method sets or returns the pages set mode which takes only two values 'fixed' or 'slide'. The default is 'slide'. The fixed mode will be good if you want to display all the navigation pages.

pages_per_set()

  $paginate->pages_per_set($number_of_pages_per_set);

Sets or returns the number of pages per set (visible pages). If called without any arguments it will return the current number of pages per set.

entries_on_current_page()

  $paginate->entries_on_current_page();

This method returns the number of entries on the current page.

first_page()

  $paginate->first_page();

Returns first page. Always returns 1.

last_page()

  $paginate->last_page();

Returns the last page number, the total number of pages.

total_pages()

  $paginate->total_pages();

Returns the last page number, the total number of pages.

first()

  $paginate->first();

Returns the number of the first entry on the current page.

last()

  $paginate->last();

Returns the number of the last entry on the current page.

previous_page()

  $paginate->previous_page();

Returns the previous page number, if one exists. Otherwise it returns undefined.

next_page()

  $paginate->next_page();

Returns the next page number, if one exists. Otherwise it returns undefined.

first_page_in_set()

  $paginate->first_page_in_set();

Returns 1 if the first page is in the current pages set. Otherwise it returns 0.

last_page_in_set()

  $paginate->last_page_in_set();

Returns 1 if the last page is in the current pages set. Otherwise it returns 0.

previous_set()

  print "Previous set starts at ", $paginate->previous_set(), "\n";

This method returns the page number at the start of the previous page set. undef is return if pages_per_set has not been set.

next_set()

  print "Next set starts at ", $paginate->next_set(), "\n";

This method returns the page number at the start of the next page set. undef is return if pages_per_set has not been set.

pages_in_set()

  foreach my $page_num (@{$paginate->pages_in_set()}) {
    print "Page: $page_num \n";
  }

This method returns an array ref of the the page numbers within the current set. undef is return if pages_per_set has not been set.

EXPORT

Top

None by default.

AUTHOR

Top

Ahmed Amin Elsheshtawy, <support@mewsoft.com> Website: http://www.mewsoft.com

SEE ALSO

Top

Data::Page. Data::Pageset.

COPYRIGHT AND LICENSE

Top


Mewsoft-Pagination documentation Contained in the Mewsoft-Pagination distribution.
#=Copyright Infomation
#==========================================================
#Module Name      : Mewsoft::Pagination
#Program Author   : Dr. Ahmed Amin Elsheshtawy, Ph.D. Physics
#Home Page          : http://www.mewsoft.com
#Contact Email      : support@mewsoft.com
#Products               : Auction, Classifieds, Directory, PPC, Forums, Snapshotter
#Copyrights © 2008 Mewsoft Corp. All rights reserved.
#==========================================================
#==========================================================
package Mewsoft::Pagination;

# pagination - pag·i·na·tion
#1. the process of numbering the pages of a book.
#2. the number and arrangement of pages, as might be noted in a bookseller’s catalogue.

$VERSION = '0.40';

use strict;

#==========================================================
#==========================================================
sub new {
my ($class, %args) = @_;
    
	my $self = bless {}, $class;
	
	#while (my($key, $value)=each(%args)) {print ("$key =  $value\n");}

	$args{total_entries} += 0;
	$args{entries_per_page} += 0;
	$args{current_page} += 0;
	$args{pages_per_set} += 0;
	
	$args{entries_per_page} = int($args{entries_per_page});
	$args{current_page} = int($args{current_page});
	$args{pages_per_set} = int($args{pages_per_set});

	$self->{total_entries} =  int($args{total_entries});
	$self->{entries_per_page} = $args{entries_per_page} > 0 ? $args{entries_per_page} : 10;
	$self->{current_page} = $args{current_page} > 0 ? $args{current_page} : 1;
	$self->{pages_per_set} = $args{pages_per_set} > 0 ? $args{pages_per_set} : 5;

    if ( defined $args{mode} && $args{mode} eq 'fixed' ) {
        $self->{mode} = 'fixed';
    } else {
        $self->{mode} = 'slide';
    }
	
	$self->_do_calculation();

    return $self;
}
#==========================================================
sub _do_calculation {
my ($self) = shift;
	
	# Calculate the total pages & the last page number
	$self->{last_page} = int ($self->{total_entries} / $self->{entries_per_page});
	if (($self->{total_entries} % $self->{entries_per_page})) { $self->{last_page}++; }
	$self->{last_page} = 1 if ($self->{last_page} < 1);
	$self->{total_pages} = $self->{last_page};

	if ($self->{current_page} > $self->{last_page}) {$self->{current_page} = $self->{last_page};}

	$self->{first_page} = 1;  #always = 1

	# calculate the first data entry on the current page
	if ($self->{total_entries} == 0) {
		$self->{first} = 0;
	} else {
		$self->{first} = (($self->{current_page} - 1) * $self->{entries_per_page}) + 1;
	}
	
	# calculate the last data entry on the current page
	if ($self->{current_page} == $self->{last_page}) {
		$self->{last} = $self->{total_entries};
	} else {
		$self->{last} = ($self->{current_page} * $self->{entries_per_page});
	}

	# Calculate entries on the current page
	if ($self->{total_entries} == 0) {
		$self->{entries_on_current_page} = 0;
	} else {
		$self->{entries_on_current_page} = $self->last - $self->first + 1;
	}
	
	#calculate the previous page number if any
	if ($self->{current_page} > 1) {
		$self->{previous_page} = $self->{current_page} - 1;
	} else {
		$self->{previous_page} = undef;
	}
	
	#calculate the next page number if any
	$self->{next_page} = $self->{current_page} < $self->{last_page} ? $self->{current_page} + 1 : undef;
	
	#calculate pages sets
	$self->_calculate_visible_pages();
	
	#check if the first page is currently in the pages set displayed
	$self->{first_page_in_set} = @{$self->{Page_Set_Pages}}[0] == 1 ? 1 : 0;
	#check if the last page is currently in the pages set displayed
	$self->{last_page_in_set} = @{$self->{Page_Set_Pages}}[$#{$self->{Page_Set_Pages}}] == $self->{last_page} ? 1 : 0;
}
#==========================================================

sub total_entries {
my ($self) = shift; 
	if (@_) {
		$self->{total_entries} = shift ;
		$self->_do_calculation();
	}
	return $self->{total_entries};
}
#==========================================================

sub entries_per_page {
my ($self) = shift; 
	if (@_) {
		$self->{entries_per_page} = shift ;
		$self->_do_calculation();
	}
	return $self->{entries_per_page};
}
#==========================================================

sub current_page {
my ($self) = shift; 
	if (@_) {
		$self->{current_page} = shift ;
		$self->_do_calculation();
	}
	return $self->{current_page};
}
#==========================================================

sub mode {
my ($self) = shift; 
	if (@_) {
		$self->{mode} = shift ;
		$self->_do_calculation();
	}
	return $self->{mode};
}
#==========================================================

sub pages_per_set {
my ($self) = shift; 
	if (@_) {
		$self->{pages_per_set} = shift ;
		$self->_do_calculation();
	}
	return $self->{pages_per_set};
}
#==========================================================

sub entries_on_current_page {
my ($self) = shift;

	if ($self->{total_entries} == 0) {
		return 0;
	} else {
		return $self->last - $self->first + 1;
	}
}
#==========================================================

sub first_page {
my ($self) = shift;
	return 1;
}
#==========================================================

sub last_page {
my ($self) = shift; 
	return $self->{last_page};
}
#==========================================================

sub total_pages {
my ($self) = shift; 
	return $self->{last_page};
}
#==========================================================

sub first {
my ($self) = shift;
	return $self->{first};
}
#==========================================================

sub last {
my ($self) = shift;
	return $self->{last};
}
#==========================================================

sub previous_page {
my ($self) = shift;
	return $self->{previous_page};
}
#==========================================================

sub next_page {
my ($self) = shift;
	return $self->{next_page};
}
#==========================================================

sub first_page_in_set {
my ($self) = shift;
	return $self->{first_page_in_set};
}
#==========================================================

sub last_page_in_set {
my ($self) = shift;
	return $self->{last_page_in_set};
}
#==========================================================
#==========================================================
#==========================================================
# The code below originally from the module Data::Pageset
sub _calculate_visible_pages {
my ($self)= shift;

    unless ( $self->{pages_per_set} > 1 ) {
        # Only have one page in the set, must be page 1
        $self->{Page_Set_Previous} = $self->{current_page} - 1 if ($self->{current_page} != 1);
        $self->{Page_Set_Pages} = [1];
        $self->{Page_Set_Next}  = $self->{current_page} + 1 if ($self->{current_page} < $self->{last_page});
    } else {
        if ( $self->{mode} eq 'fixed' ) {
            my $starting_page = $self->_calc_start_page($self->{pages_per_set});
            my $end_page      = $starting_page + $self->{pages_per_set} - 1;

            if ( $end_page < $self->{last_page}) {
                $self->{Page_Set_Next} = $end_page + 1;
            }

            if ( $starting_page > 1 ) {
                $self->{Page_Set_Previous} = $starting_page - $self->{pages_per_set};
				$self->{Page_Set_Previous} =  1 if $self->{Page_Set_Previous} < 1;
            }

            $end_page = $self->{last_page} if ($self->{last_page} < $end_page);
            $self->{Page_Set_Pages} = [ $starting_page .. $end_page ];
        } else {

            # We're in slide mode

            # See if we have enough pages to slide
            if ( $self->{pages_per_set} >= $self->{last_page} ) {

                # No sliding, no next/prev pageset
                $self->{Page_Set_Pages} = [ '1' .. $self->{last_page} ];
            } else {

				# Find the middle rounding down - we want more pages after, than before
                my $middle = int( $self->{pages_per_set} / 2 );

                # offset for extra value right of center on even numbered sets
                my $offset = 1;
                if ( $self->{pages_per_set} % 2 != 0 ) {
                    # must have been an odd number, add one
                    $middle++;
                    $offset = 0;
                }

                my $starting_page = $self->{current_page} - $middle + 1;
                $starting_page = 1 if $starting_page < 1;
                my $end_page = $starting_page + $self->{pages_per_set} - 1;
                $end_page = $self->{last_page} if ($self->last_page() < $end_page);

                if ( $self->{current_page} <= $middle ) {
                    # near the start of the page numbers
                    $self->{Page_Set_Next} = $self->{pages_per_set} + $middle - $offset;
                    $self->{Page_Set_Pages} = [ '1' .. $self->{pages_per_set} ];
                } elsif ( $self->{current_page} > ( $self->{last_page} - $middle - $offset ) )
                {
                    # near the end of the page numbers
                    $self->{Page_Set_Previous} = $self->{last_page} - $self->{pages_per_set} - $middle + 1;
                    $self->{Page_Set_Pages}= [ ( $self->{last_page} - $self->{pages_per_set} + 1 ) .. $self->{last_page} ];
                } else {
                    # Start scrolling
                    $self->{Page_Set_Pages} = [ $starting_page .. $end_page ];
                    $self->{Page_Set_Previous} = $starting_page - $middle - $offset;
                    $self->{Page_Set_Previous} = 1 if $self->{Page_Set_Previous} < 1;
                    $self->{Page_Set_Next} = $end_page + $middle;
                }
            }
        }
    }

}
#==========================================================
# The code below originally from the module Data::Pageset
# Calculate the first page in the current set
sub _calc_start_page {
my ( $self) = @_;

    my $current_page_set = 0;

    if ( $self->{pages_per_set} > 0 ) {
        $current_page_set = int( $self->{current_page} / $self->{pages_per_set} );
        if ( $self->{current_page} % $self->{pages_per_set} == 0 ) {
            $current_page_set = $current_page_set - 1;
        }
    }

    return ( $current_page_set * $self->{pages_per_set} ) + 1;
}
#==========================================================

sub previous_set {
    my $self = shift;
    return $self->{Page_Set_Previous} if defined $self->{Page_Set_Previous};
    return undef;
}
#==========================================================

sub next_set {
my ($self) = shift;
    return $self->{Page_Set_Next} if defined $self->{Page_Set_Next};
    return undef;
}
#==========================================================

sub pages_in_set {
my ($self) = shift;
    return $self->{Page_Set_Pages};
}
#==========================================================
#==========================================================

1;