Bivio::UI::XHTML::Widget::Pager
# Copyright (c) 2005-2009 bivio Software, Inc. All Rights Reserved. # $Id$ package Bivio::UI::XHTML::Widget::Pager; use strict; use Bivio::Base 'UI.Widget'; use Bivio::Biz::QueryType; use Bivio::UI::ViewLanguageAUTOLOAD; my($_I) = b_use('Type.Integer'); my($_BLOCK_SIZE) = 15; # Table Pager Widget # list_class : string (required) # pages : int (15) -- The number of pages to select from. sub initialize { my($self) = @_; return if $self->unsafe_get('_link'); $self->initialize_attr(_link => Link([$self . 'link_text'], [$self . 'link_href'], _num_class($self))); $self->initialize_attr(_selected => SPAN(String([$self . 'selected']), _num_class($self, 1))); _create_navigation_link($self, 'prev'); _create_navigation_link($self, 'next'); return; } sub internal_new_args { my(undef, $list_class, $pages, $attributes) = @_; Bivio::Die->die('missing list_class') unless $list_class; return { list_class => $list_class, (defined($pages) ? (pages => $pages) : ()), ($attributes ? %$attributes : ()), }; } sub render { my($self, $source, $buffer) = @_; my($req) = $source->get_request; my($key) = 'Model.' . $self->get('list_class'); my($query) = $req->get($key)->get_query; return unless $query->get('has_next') || $query->get('has_prev'); $self->get('_prev')->render($req, $buffer); my($no_sep) = 0; foreach my $page (@{_get_page_numbers($self, $query)}) { $req->put($self . 'no_sep' => $no_sep++); if ($page == $query->get('page_number')) { $req->put($self . 'selected' => $page); $self->get('_selected')->render($req, $buffer); next; } $req->put($self . 'link_text' => $page); $req->put($self . 'link_href' => $req->get($key)->format_uri( Bivio::Biz::QueryType->THIS_LIST, undef, { page_number => $page, })); $self->get('_link')->render($req, $buffer); } $self->get('_next')->render($req, $buffer); return; } # Returns a widget which renders a navigator for the specified direction # Returns a list of page numbers to render as links. sub _create_navigation_link { my($self, $direction) = @_; my($key) = 'Model.' . $self->get('list_class'); my($text) = vs_text("$key.paged_list.$direction"); $self->initialize_attr('_' . $direction => If([[$key, '->get_query'], 'has_' . $direction], Link(_nav($self, $direction, $text, 1), [$key, '->format_uri', Bivio::Biz::QueryType->from_name(uc($direction) . '_LIST')]), _nav($self, $direction, $text, 0), )); return; } sub _get_page_numbers { my($self, $query) = @_; return [] unless my $pc = $query->unsafe_get('page_count'); my($mod) = $self->get_or_default('pages', $_BLOCK_SIZE); my($block) = int($query->get('page_number') / $mod) * $_BLOCK_SIZE; return [$block + 1 .. $_I->min($block + $mod, $pc)]; } sub _nav { my($self, $direction, $text, $on) = @_; return Join([ _order_widgets($self, $direction, SPAN(String($text), $direction . ' ' . ($on ? 'on' : 'off'))), ]); } # Returns the widgets in the correct order depending on the direction. sub _num_class { my($self, $selected) = @_; return { class => [sub { my(undef, $no_sep, $class) = @_; return $class . ($no_sep ? '' : ' want_sep'); }, [$self . 'no_sep'], $selected ? 'selected num' : 'num'], }; } sub _order_widgets { my($self, $direction, @widgets) = @_; return $direction eq 'next' ? reverse(@widgets) : @widgets; } 1;