% if ( exists($opt{'redirect'}) && $opt{'redirect'} % && scalar(@$rows) == 1 && $total == 1 % && $type ne 'html-print' % ) { % my $redirect = $opt{'redirect'}; % $redirect = &{$redirect}($rows->[0], $cgi) if ref($redirect) eq 'CODE'; % my( $url, $method ) = @$redirect; % redirect( $url. $rows->[0]->$method() ); % } elsif ( exists($opt{'redirect_empty'}) && ! scalar(@$rows) && $total == 0 % && $type ne 'html-print' % && $opt{'redirect_empty'} % && ( ref($opt{'redirect_empty'}) ne 'CODE' % || &{$opt{'redirect_empty'}}($cgi) ) % ) { % my $redirect = $opt{'redirect_empty'}; % $redirect = &{$redirect}($cgi) if ref($redirect) eq 'CODE'; % redirect( $redirect ); % } else { % if ( $opt{'name_singular'} ) { % $opt{'name'} = PL($opt{'name_singular'}); % } % ( my $xlsname = $opt{'name'} ) =~ s/\W//g; % if ( $total == 1 ) { % if ( $opt{'name_singular'} ) { % $opt{'name'} = $opt{'name_singular'} % } else { % #$opt{'name'} =~ s/s$// if $total == 1; % $opt{'name'} =~ s/((s)e)?s$/$2/ if $total == 1; % } % } % % unless ( $opt{nohtmlheader} ) { % % if ( $type eq 'html-print' ) { <& /elements/header-popup.html, $opt{'title'} &> % } else { % if ( $type eq 'select' ) { <&/elements/header-popup.html, $opt{'title'} &> % } else { % % my @menubar = (); % if ( $opt{'menubar'} ) { % @menubar = @{ $opt{'menubar'} }; % #} else { % # @menubar = ( 'Main menu' => $p ); % } <& /elements/header.html, $opt{'title'}, include( '/elements/menubar.html', @menubar ) &> % } % } % % } % % unless ( $type eq 'html-print' ) { % if ( $opt{'add_link'} ) { #or after html_init? Add a <% $opt{'name_singular'} %>

% } <% defined($opt{'html_init'}) ? ( ref($opt{'html_init'}) ? &{$opt{'html_init'}}($opt{html_init_data}) : $opt{'html_init'} ) : '' %> % } % unless ( $total ) { % unless ( $opt{'disable_nonefound'} ) {

No matching <% $opt{'name'} %> found.
% } % } % % if ( $total || $opt{'disableable'} ) { #hmm... and there *are* ones to show?? % if ( $curuser->access_right('Download report data') % and !$opt{'disable_download'} % and $type ne 'html-print' ) { % $cgi->param('_type', "html" ); % }
% if (! $opt{'disable_total'}) { <% $total %> total <% $opt{'name'} %> % } % if ( $confmax && $total > $confmax % && ! $opt{'disable_maxselect'} % && $type ne 'html-print' ) % { % $cgi->delete('maxrecords'); % $cgi->param('_dummy', 1); % my $query = $m->scomp('/elements/create_uri_query'); ( show per page ) % $cgi->param('maxrecords', $maxrecords); % } % if ( defined($opt{'html_posttotal'}) && $type ne 'html-print' ) { <% ref($opt{'html_posttotal'}) ? &{$opt{'html_posttotal'}}() : $opt{'html_posttotal'} %> % }
% if ( $opt{'count_addl'} ) { % my $n=0; % foreach my $count ( @{$opt{'count_addl'}} ) { % my $data = $count_arrayref->[++$n]; % if ( ref($count) ) { <% &{ $count }( $data ) %> % } else { <% sprintf( $count, $data ) %>
% } % } % }
<% $opt{'download_label'} || 'Download results:' %> % $cgi->param('_type', "$xlsname.xls" ); % my $query = $m->scomp('/elements/create_uri_query'); ">Spreadsheet |  % $cgi->param('_type', 'csv'); % my $query = $m->scomp('/elements/create_uri_query'); ">CSV |  % if ( defined($opt{xml_elements}) ) { % $cgi->param('_type', 'xml'); % my $query = $m->scomp('/elements/create_uri_query'); ">XML |  % } % $cgi->param('_type', 'html-print'); % my $query = $m->scomp('/elements/create_uri_query'); ">webpage %# "save search" -- for now, obey disable_download and the 'Download %# report data' ACL, because saving a search allows the user to receive %# copies of the data.
%# XXX should do a check here on whether the user already has this %# search saved... <& /elements/popup_link.html, 'action' => $fsurl.'/edit/saved_search.html?title='. uri_escape($opt{title}), 'label' => 'Save this search', 'actionlabel' => 'Save this search', 'width' => 650, 'height' => 500, &>
% my $pager = ''; % unless ( $type eq 'html_print' ) { <% $pager = include( '/elements/pager.html', 'offset' => $offset, 'num_rows' => scalar(@$rows), 'total' => $total, 'maxrecords' => $maxrecords, ) %> <% defined($opt{'html_form'}) ? ( ref($opt{'html_form'}) ? &{$opt{'html_form'}}() : $opt{'html_form'} ) : '' %> % } <& SELF:data_table, rows => $rows, null_link => $null_link, link_agentnums => \@link_agentnums, self_url => $self_url, %opt &> <% $pager %>
% } % if ( $type eq 'html-print' ) { % unless ( $opt{nohtmlheader} ) { % } % } else { <% defined($opt{'html_foot'}) ? ( ref($opt{'html_foot'}) ? &{$opt{'html_foot'}}() : $opt{'html_foot'} ) : '' %> <% $opt{nohtmlheader} ? '' : include( '/elements/footer.html' ) %> % } % } <%init> my $curuser = $FS::CurrentUser::CurrentUser; my %args = @_; my $type = $args{'type'}; my $header = $args{'header'}; my $rows = $args{'rows'}; my @link_agentnums = @{ $args{'link_agentnums'} }; my $null_link = $args{'null_link'}; my $confmax = $args{'confmax'}; my $maxrecords = $args{'maxrecords'}; my $offset = $args{'offset'}; my %opt = %{ $args{'opt'} }; # must be an arrayref of the row count, followed by any other totals my $count_arrayref = $args{'totals'}; my $total = $count_arrayref->[0]; # there used to be an option to override this, for highly dubious reasons my $self_url = $cgi->url('-path_info' => 1, '-full' =>1); <%method data_table> % my %opt = @_; % my $rows = delete $opt{rows}; % my $self_url = delete $opt{self_url}; <& /elements/table-grid.html &> <& SELF:header_row, 'header' => $opt{'header'}, 'header2' => $opt{'header2'}, 'sort_fields' => ($opt{'sort_fields'} || $opt{'fields'}), &> <& SELF:data_rows, rows => $rows, opt => \%opt &> % if ( $opt{'footer'} ) { <& SELF:footer_row, row => $opt{'footer'}, opt => \%opt &> % } <%method header_row> <%args> @sort_fields @header @header2 => () % my $h2 = 0; % my $colspan = 0; % my $order_by = $cgi->param('order_by'); % my $self_url = $cgi->url('-path_info' => 1, '-full' =>1); % foreach my $header ( @header ) { % % my $field = shift @sort_fields; % % $colspan-- if $colspan > 0; % next if $colspan; % % my $label = ref($header) ? $header->{label} : $header; % unless ( ref($field) || !$field ) { % if ( $order_by eq $field ) { % $cgi->param('order_by', "$field DESC"); % } else { % $cgi->param('order_by', $field); % } % my $query = $m->scomp('/elements/create_uri_query'); % $label = qq($label); % } % % $colspan = ref($header) ? $header->{colspan} : 0; % my $rowspan = 1; % my $style = ''; % if ( @header2 ) { % if ( !length($header2[$h2]) ) { % $rowspan = 2; % splice @header2, $h2, 1; % } else { % $h2++; % $style = 'STYLE="border-bottom: none"' % } % } <% $style %> > <% $label %> % } % if ( @header2 ) { % foreach my $header ( @header2 ) { % my $label = ref($header) ? $header->{label} : $header; <% $label %> % } % } <%method data_rows> <%args> $rows => [] %opt % my %align = ( % 'l' => 'left', % 'r' => 'right', % 'c' => 'center', % ' ' => '', % '.' => '', % ); % if ( $opt{align} and !ref($opt{align}) ) { % $opt{align} = [ map $align{$_}, split(//, $opt{align}) ]; % } % my $i = 0; # for row striping # XXX CSS - nth-child % my $id = 0; % foreach my $row ( @$rows ) { % % my $rowstyle = ''; % if ( $row eq $opt{'footer_data'} ) { # XXX CSS - tfoot % $rowstyle = ' STYLE="border-top: dashed 1px black; font-style: italic background-color=#dddddd"'; % } % % my $trid = ''; % if ( $opt{'link_field' } ) { % my $link_field = $opt{'link_field'}; % if ( ref($link_field) eq 'CODE' ) { % $trid = &{$link_field}($row); % } else { % $trid = $row->$link_field(); % } % } > % if ( $opt{'fields'} ) { % % my $links = $opt{'links'} ? [ @{$opt{'links'}} ] : ''; % my $onclicks = $opt{'link_onclicks'} ? [ @{$opt{'link_onclicks'}} ] : []; % my $tooltips = $opt{'tooltips'} ? [ @{$opt{'tooltips'}} ] : []; % my $aligns = $opt{'align'} ? [ @{$opt{'align'}} ] : ''; % my $colors = $opt{'color'} ? [ @{$opt{'color'}} ] : []; % my $sizes = $opt{'size'} ? [ @{$opt{'size'}} ] : []; % my $styles = $opt{'style'} ? [ @{$opt{'style'}} ] : []; % my $cstyles = $opt{'cell_style'} ? [ @{$opt{'cell_style'}} ] : []; % my $formats = $opt{'format'} ? [ @{$opt{'format'}} ] : []; % % foreach my $field ( % % # if the value of the field is an arrayref, then construct a table in % # the cell. % # if it's a (non-empty) scalar, and a format has been specified, then % # format the scalar with that. % # otherwise, just output the value. % # XXX we should also do date formats like this % map { % if ( ref($_) eq 'ARRAY' ) { % % my $tableref = $_; % % ''. % % join('', map { % % my $rowref = $_; % % ''. % % join('', map { % % my $e = $_; % % ''; % % } @$rowref ). % % ''; % } @$tableref ). % % '
{$_}), % qw( align bgcolor colspan rowspan % style valign width ) % ). % '>'. % % ( $e->{'link'} % ? '' % : '' % ). % ( $e->{'onclick'} # don't use with 'link' % ? '' % : '' % ). % ( $e->{'size'} % ? '' % : '' % ). % ( $e->{'data_style'} % ? '<'. uc($e->{'data_style'}). '>' % : '' % ). % $e->{'data'}. % ( $e->{'data_style'} % ? '{'data_style'}). '>' % : '' % ). % ( $e->{'size'} ? '' : '' ). % ( $e->{'link'} || $e->{'onclick'} % ? '' % : '' ). % '
'; % % } else { % if ( length($_) > 0 and my $format = shift @$formats ) { % $_ = sprintf($format, $_); % } % $_; % } % } % % # get the value of the field spec: % # - if the spec is a coderef, evaluate the coderef % # - if the spec is a string, call that string as a method % # - if the spec is an integer, get the field in that position % map { % if ( ref($_) eq 'CODE' ) { % &{$_}($row); % } elsif ( ref($row) eq 'ARRAY' and % $_ =~ /^\d+$/ ) { % # for the 'straight SQL' case: specify fields % # by position % encode_entities($row->[$_]); % } else { % encode_entities($row->$_()); % } % } % @{$opt{'fields'}} % % ) { % % my $class = ( $field =~ /^agentnum ) % || grep { $row->agentnum == $_ } % @{ $opt{link_agentnums} } % ) { % % $link = &{$link}($row) % if ref($link) eq 'CODE'; % % $onclick = &{$onclick}($row) % if ref($onclick) eq 'CODE'; % $onclick = qq( onClick="$onclick") if $onclick; % % $tooltip = &{$tooltip}($row) % if ref($tooltip) eq 'CODE'; % $tooltip = qq! id="a$id" !. % qq! onmouseover="return overlib(!. % $m->interp->apply_escapes($tooltip, 'h', 'js_string'). % qq!, FGCLASS, 'tooltip', REF, 'a$id', !. % qq!REFC, 'LL', REFP, 'UL')"! if $tooltip; % % if ( $link ) { % my( $url, $method ) = @{$link}; % if ( ref($method) eq 'CODE' ) { % $a = $url. &{$method}($row); % } else { % $a = $url. $row->$method(); % } % $a = qq(); % } % elsif ( $onclick ) { % $a = qq(); % } % elsif ( $tooltip ) { % $a = qq(); % } % $id++; % } % % } % % my $font = ''; % my $color = shift @$colors; % $color = &{$color}($row) if ref($color) eq 'CODE'; % my $size = shift @$sizes; % $size = &{$size}($row) if ref($size) eq 'CODE'; % if ( $color || $size ) { % $font = ''; % } % % my($s, $es) = ( '', '' ); % my $style = shift @$styles; % $style = &{$style}($row) if ref($style) eq 'CODE'; % if ( $style ) { % $s = join( '', map "<$_>", split('', $style) ); % $es = join( '', map "", split('', $style) ); % } % % my $cstyle = shift @$cstyles; % $cstyle = &{$cstyle}($row) if ref($cstyle) eq 'CODE'; % $cstyle = qq(STYLE="$cstyle") % if $cstyle; % } % % } else { # not $opt{'fields'} % % foreach ( @$row ) { % } % % } % $i++; % % } # foreach $row <%method footer_row> <%args> $row %opt %# don't try to respect all the styling options, just the ones that are %# hard to replicate with CSS % my %align = ( % 'l' => 'left', % 'r' => 'right', % 'c' => 'center', % ' ' => '', % '.' => '', % ); % if ( $opt{align} and !ref($opt{align}) ) { % $opt{align} = [ map $align{$_}, split(//, $opt{align}) ]; % } % my @aligns = @{ $opt{align} }; % foreach my $footer ( @$row ) { % $footer = &{$footer}() if ref($footer) eq 'CODE'; % my $align = shift @aligns; % my $style = ''; % $style .= "text-align: $align;" if $align; % }
<% $cstyle %>><% $a %><% $font %><% $s %><% $field %><% $es %><% $font ? '' : '' %><% $a ? '' : '' %><% $_ %>
<% $footer %>