aboutsummaryrefslogtreecommitdiff
path: root/lib/MasterWebInterface/Util/BrowseHTML.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MasterWebInterface/Util/BrowseHTML.pm')
-rwxr-xr-xlib/MasterWebInterface/Util/BrowseHTML.pm126
1 files changed, 126 insertions, 0 deletions
diff --git a/lib/MasterWebInterface/Util/BrowseHTML.pm b/lib/MasterWebInterface/Util/BrowseHTML.pm
new file mode 100755
index 0000000..32d773e
--- /dev/null
+++ b/lib/MasterWebInterface/Util/BrowseHTML.pm
@@ -0,0 +1,126 @@
+package MasterWebInterface::Util::BrowseHTML;
+use strict;
+use warnings;
+use TUWF ':html', 'xml_escape';
+use Exporter 'import';
+use POSIX 'ceil';
+our @EXPORT = qw| htmlBrowse htmlBrowseNavigate |;
+
+# generates a browse box, arguments:
+# items => arrayref with the list items
+# options => hashref containing at least the keys s (sort key), o (order) and p (page)
+# nextpage => whether there's a next page or not
+# sorturl => base URL to append the sort options to (if there are any sortable columns)
+# pageurl => base URL to append the page option to
+# class => classname of the mainbox
+# header =>
+# can be either an arrayref or subroutine reference,
+# in the case of a subroutine, it will be called when the header should be written,
+# in the case of an arrayref, the array should contain the header items. Each item
+# can again be either an arrayref or subroutine ref. The arrayref would consist of
+# two elements: the name of the header, and the name of the sorting column if it can
+# be sorted
+# row => subroutine ref, which is called for each item in $list, arguments will be
+# $self, $item_number (starting from 0), $item_value
+# footer => subroutine ref, called after all rows have been processed
+# Mostly written by Yorhel --> https://g.blicky.net/vndb.git/tree/COPYING
+sub htmlBrowse {
+ my($self, %opt) = @_;
+
+ $opt{sorturl} .= $opt{sorturl} =~ /\?/ ? ';' : '?' if $opt{sorturl};
+
+ # top navigation
+ $self->htmlBrowseNavigate($opt{pageurl}, $opt{options}{p}, $opt{nextpage}, 't') if $opt{pageurl};
+
+ div class => 'mainbox browse'.($opt{class} ? ' '.$opt{class} : '');
+ table class => 'stripe';
+
+ # header
+ thead;
+ Tr;
+ if(ref $opt{header} eq 'CODE') {
+ $opt{header}->($self);
+ } else {
+ for(0..$#{$opt{header}}) {
+ if(ref $opt{header}[$_] eq 'CODE') {
+ $opt{header}[$_]->($self, $_+1);
+ } elsif ($opt{simple}) {
+ td class => $opt{header}[$_][3]||'tc'.($_+1), $opt{header}[$_][2] ? (colspan => $opt{header}[$_][2]) : ();
+ if($opt{header}[$_][1]) {
+ lit qq|<a href="$opt{sorturl}o=d;s=$opt{header}[$_][1]">$opt{header}[$_][0]</a>|;}
+ else {
+ txt $opt{header}[$_][0];}
+ end;
+ } else {
+ td class => $opt{header}[$_][3]||'tc'.($_+1), $opt{header}[$_][2] ? (colspan => $opt{header}[$_][2]) : ();
+ lit $opt{header}[$_][0];
+ if($opt{header}[$_][1]) {
+ lit ' ';
+ $opt{options}{s} eq $opt{header}[$_][1] && $opt{options}{o} eq 'a' ? lit "\x{25B4}" : a href => "$opt{sorturl}o=a;s=$opt{header}[$_][1]", "\x{25B4}";
+ $opt{options}{s} eq $opt{header}[$_][1] && $opt{options}{o} eq 'd' ? lit "\x{25BE}" : a href => "$opt{sorturl}o=d;s=$opt{header}[$_][1]", "\x{25BE}";
+ }
+ end;
+ }
+ }
+ }
+ end;
+ end 'thead';
+
+ # footer
+ if($opt{footer}) {
+ tfoot;
+ $opt{footer}->($self);
+ end;
+ }
+
+ # rows
+ $opt{row}->($self, $_+1, $opt{items}[$_])
+ for 0..$#{$opt{items}};
+
+ end 'table';
+ end 'div';
+
+ # bottom navigation
+ $self->htmlBrowseNavigate($opt{pageurl}, $opt{options}{p}, $opt{nextpage}, 'b') if $opt{pageurl};
+}
+
+
+# creates next/previous buttons (tabs), if needed
+# Arguments: page url, current page (1..n), nextpage (0/1 or [$total, $perpage]), alignment (t/b), noappend (0/1)
+# Mostly written by Yorhel --> https://g.blicky.net/vndb.git/tree/COPYING
+sub htmlBrowseNavigate {
+ my($self, $url, $p, $np, $al, $na) = @_;
+ my($cnt, $pp) = ref($np) ? @$np : ($p+$np, 1);
+ return if $p == 1 && $cnt <= $pp;
+
+ $url .= $url =~ /\?/ ? ';p=' : '?p=' unless $na;
+
+ my $tab = sub {
+ my($left, $page, $label) = @_;
+ li $left ? (class => 'left') : ();
+ a href => $url.$page; lit $label; end;
+ end;
+ };
+ my $ell = sub {
+ use utf8;
+ li class => 'ellipsis'.(shift() ? ' left' : '');
+ b '⋯';
+ end;
+ };
+ my $nc = 5; # max. number of buttons on each side
+
+ ul class => 'maintabs browsetabs ' . ($al eq 't' ? 'notfirst' : 'bottom');
+ $p > 2 and ref $np and $tab->(1, 1, '&laquo; first');
+ $p > $nc+1 and ref $np and $ell->(1);
+ $p > $_ and ref $np and $tab->(1, $p-$_, $p-$_) for (reverse 2..($nc>$p-2?$p-2:$nc-1));
+ $p > 1 and $tab->(1, $p-1, '&lsaquo; previous');
+
+ my $l = ceil($cnt/$pp)-$p+1;
+ $l > 2 and $tab->(0, $l+$p-1, ('last').' &raquo;');
+ $l > $nc+1 and $ell->(0);
+ $l > $_ and $tab->(0, $p+$_, $p+$_) for (reverse 2..($nc>$l-2?$l-2:$nc-1));
+ $l > 1 and $tab->(0, $p+1, ('next').' &rsaquo;');
+ end 'ul';
+}
+
+1;