File Coverage

lib/Data/Scroller.pm
Criterion Covered Total %
statement 129 138 93.4
branch 18 34 52.9
condition 11 25 44.0
subroutine 25 25 100.0
pod 8 8 100.0
total 191 230 83.0


line stmt bran cond sub pod time code
1             package Data::Scroller;
2 2     2   1588 use strict;
  2         3  
  2         77  
3 2     2   11 use warnings;
  2         4  
  2         77  
4 2     2   21 use vars qw( $VERSION @ISA );
  2         4  
  2         156  
5             $VERSION = '1.00';
6              
7             # =============================================================================
8             # params for use in templates.
9             # =============================================================================
10 2     2   11 use constant PARAM_PAGE_LIST => "page_list";
  2         4  
  2         126  
11 2     2   11 use constant PARAM_PAGE_NEXT => "page_next";
  2         2  
  2         92  
12 2     2   10 use constant PARAM_PAGE_PREV => "page_prev";
  2         2  
  2         91  
13 2     2   17 use constant PARAM_PAGE_FIRST => "page_first";
  2         2  
  2         90  
14 2     2   11 use constant PARAM_PAGE_LAST => "page_last";
  2         3  
  2         94  
15 2     2   8 use constant PARAM_PAGE_NAME => "page_name";
  2         4  
  2         88  
16 2     2   9 use constant PARAM_PAGE_TOTAL => "page_total";
  2         10  
  2         85  
17 2     2   10 use constant PARAM_PAGE_INCREMENT => "page_increment";
  2         2  
  2         121  
18              
19             # =============================================================================
20             # default input parameters.
21             # =============================================================================
22 2     2   9 use constant PAGING_INCREMENT => 10; # default paging increment
  2         4  
  2         175  
23 2     2   11 use constant PAGING_NAME => "row_num"; # default paging name
  2         3  
  2         2726  
24              
25             # ----------------------------------------------------------------------
26             # constructor - takes hash of paramaters
27             # ----------------------------------------------------------------------
28             sub new
29             {
30 4     4 1 1600 my $class = shift;
31 4         7 my $self = {};
32 4         13 bless($self, $class);
33 4 50       11 return undef if !$self->_init(@_);
34 2         13 return $self;
35             }
36              
37             # ----------------------------------------------------------------------
38             # return hashref of parameters for use in templates
39             # ----------------------------------------------------------------------
40             sub display
41             {
42 1     1 1 2 my $self = shift;
43              
44 1         5 my $params = $self->{params};
45 1         2 my $max_value = $self->{max_value};
46 1         2 my $max_display = $self->{max_display};
47 1         2 my $name = $self->{name};
48 1         2 my $increment = $self->{increment};
49 1         2 my $selected = $self->{selected};
50 1         1 my $page_increment = $self->{page_increment};
51              
52             # ----------------------------------------------------------------------
53             # paging not required
54             # ----------------------------------------------------------------------
55 1 50       4 return $params if $max_value <= $increment;
56              
57             # ----------------------------------------------------------------------
58             # what should the page number be for the results the user has selected?
59             # ----------------------------------------------------------------------
60 1         2 my $start = 1;
61 1 50       6 $start = $self->_round($selected / $page_increment) if $selected > 0;
62              
63             # ----------------------------------------------------------------------
64             # set the start and end points for display from the current page number..
65             # ----------------------------------------------------------------------
66 1         2 my $set_start = 1;
67 1         2 my $set_end = $page_increment;
68 1         3 ($set_start, $set_end) = $self->_page_inc_by_one($set_start, $set_end, $start, $page_increment);
69              
70             # ----------------------------------------------------------------------
71             # display extra <$page_increment> results if the selected page is the first
72             # or last in a set..
73             # ----------------------------------------------------------------------
74 1 50 33     10 if ($start == $set_end and $set_end < $max_display) {
    50 33        
75 0         0 $set_end += $page_increment;
76             }
77             elsif ($start == $set_start and $set_start >= $page_increment) {
78 0         0 $set_start = ($set_start - $page_increment);
79             }
80              
81 1         2 my $next = $increment;
82              
83 1         1 my @list = ();
84 1         2 my $value = 0;
85 1         1 my $prev = 0;
86 1         3 for (my $i = $set_start; $i <= $set_end; $i++) {
87 6         8 $value = ($i - 1) * $increment;
88 6 100       12 last if ($value >= $max_value);
89              
90 5         10 my $item = {
91             page_display => $i,
92             page_value => $value,
93             };
94              
95 5 50       10 if ($selected == $value) {
96 0         0 $item->{page_current} = 1;
97 0         0 $next += $value;
98 0 0       0 if ($value > 0) {
99 0         0 $prev = $value - $increment;
100             }
101             }
102 5         16 push @list, $item;
103             }
104              
105 1         3 $params->{+PARAM_PAGE_LIST} = \@list;
106 1         2 $params->{+PARAM_PAGE_NAME} = $name;
107 1         2 $params->{+PARAM_PAGE_TOTAL} = $max_display;
108 1         1 $params->{+PARAM_PAGE_INCREMENT} = $increment;
109            
110 1         4 my $page_last = $self->_round(($max_display * $increment) - $increment);
111 1 50       3 unless (($selected == $page_last)) {
112 1         2 $params->{+PARAM_PAGE_LAST} = $page_last;
113             }
114              
115 1 50       6 if ($next < $max_value) {
116 1         2 $params->{+PARAM_PAGE_NEXT} = $next;
117             }
118              
119 1 50       3 if ($selected > 0) {
120 1         1 $params->{+PARAM_PAGE_FIRST} = 0;
121 1         2 $params->{+PARAM_PAGE_PREV} = $prev;
122             }
123              
124 1         4 return $params;
125             }
126              
127             # ----------------------------------------------------------------------
128             # get methods to retrieve object properties as required
129             # ----------------------------------------------------------------------
130 1     1 1 8 sub max_value { shift->{max_value} }
131 1     1 1 4 sub increment { shift->{increment} }
132 1     1 1 5 sub max_display { shift->{max_display} }
133 1     1 1 6 sub name { shift->{name} }
134 1     1 1 4 sub selected { shift->{selected} }
135 1     1 1 4 sub page_increment { shift->{page_increment} }
136              
137             # ----------------------------------------------------------------------
138             # work out what the paging menu display start and end points are
139             # for the selected page.
140             # this routine uses a base increment of $page_increment, then
141             # increments that by one in either direction, aka google style.
142             # ----------------------------------------------------------------------
143             sub _page_inc_by_one
144             {
145 1     1   1 my $self = shift;
146 1         2 my ($set_start, $set_end, $start, $inc) = @_;
147              
148 1 50 0     11 if ($start <= $inc) {
    0          
149 1         2 $set_end = ($start + $inc) - 1;
150             }
151             elsif ($start > $inc and $set_end < (($start + $inc) - 1)) {
152 0         0 $set_end++;
153 0         0 $set_end = $self->_page_inc_by_one($set_start, $set_end, $start, $inc);
154             }
155              
156 1 50       3 if ($start < ($inc + 1)) {
157 1         2 $set_start = 1;
158             }
159             else {
160 0         0 $set_start = ($set_end - $inc) + 1;
161             }
162              
163 1         3 return ($set_start, $set_end);
164             }
165              
166             # ----------------------------------------------------------------------
167             # round UP
168             # ----------------------------------------------------------------------
169             sub _round
170             {
171 5     5   10 my ($self, $val) = @_;
172 5 100       27 return ($val == int($val) ? $val : int($val + 1));
173             }
174              
175             # ----------------------------------------------------------------------
176             # initialize paging object properties
177             # ----------------------------------------------------------------------
178             sub _init
179             {
180 4     4   14 my ($self, %args) = @_;
181              
182 4   100     44 my $max_value = $args{max_value} || die "max_value is required"; # total records / rows
183 2   100     11 my $increment = $args{increment} || PAGING_INCREMENT; # records to display per page
184 2         4 my $max_display = $args{max_display}; # max pages to display. TODO: not yet user option
185 2 50 33     11 if (!defined($max_display) || !length($max_display)) {
186             # $max_display = int($max_value / $increment) + 1; # ref display page numbers
187 2         11 $max_display = $self->_round(($max_value / $increment));
188             }
189 2   33     30 my $name = $args{name} || $self->PAGING_NAME;
190 2         3 my $selected = $args{selected};
191 2 100 66     15 if (!defined($selected) || $selected !~ /\d+/) {
192 1         2 $selected = 0; # current page, default 0 = page 1
193             }
194             # the number of pages to increment in either direction by when incrementing paging display
195 2   33     22 my $page_increment = $args{page_increment} || $increment;
196              
197 2         6 my $params = $self->_init_params;
198              
199 2         25 $self->{max_value} = $max_value;
200 2         5 $self->{increment} = $increment;
201 2         723 $self->{max_display} = $max_display;
202 2         5 $self->{name} = $name;
203 2         5 $self->{selected} = $selected;
204 2         4 $self->{page_increment} = $page_increment;
205 2         4 $self->{params} = $params;
206 2         7 $self->{initialized} = 1;
207              
208 2         12 return 1;
209             }
210              
211             # ----------------------------------------------------------------------
212             # initialize the params hash ref containing the template variables
213             # ----------------------------------------------------------------------
214             sub _init_params
215             {
216 2     2   26 my $self = shift;
217 2         607 my $params = {};
218 2         6 $params->{+PARAM_PAGE_LIST} = undef;
219 2         4 $params->{+PARAM_PAGE_NAME} = undef;
220 2         4 $params->{+PARAM_PAGE_TOTAL} = undef;
221 2         3 $params->{+PARAM_PAGE_INCREMENT} = undef;
222 2         4 $params->{+PARAM_PAGE_LAST} = undef;
223 2         4 $params->{+PARAM_PAGE_NEXT} = undef;
224 2         4 $params->{+PARAM_PAGE_FIRST} = undef;
225 2         6 $params->{+PARAM_PAGE_PREV} = undef;
226 2         6 return $params;
227             }
228              
229             1;
230              
231             __END__