aboutsummaryrefslogtreecommitdiff
path: root/lib/MasterWebInterface/Util/BrowseHTML.pm
blob: 32d773efa885c8b201cbb5900385a18ee465f681 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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;