include( 'elements/search.html',
- # basic options, required
+ ###
+ # required
+ ###
+
'title' => 'Page title',
'name_singular' => 'item', #singular name for the records returned
'name' => 'items', #plural name for the records returned
# (deprecated, will be singularlized
# simplisticly)
-
- # some HTML callbacks...
- 'menubar' => '', #menubar arrayref
- 'html_init' => '', #after the header/menubar and before the pager
- 'html_form' => '', #after the pager, right before the results
- # (only shown if there are results)
- # (use this for any form-opening tag rather than
- # html_init, to avoid a nested form)
- 'html_foot' => '', #at the bottom
- 'html_posttotal' => '', #at the bottom
- # (these three can be strings or coderefs)
-
-
- #literal SQL query string (deprecated?) or qsearch hashref, required
+
+ #literal SQL query string (deprecated?) or qsearch hashref
'query' => {
'table' => 'tablename',
#everything else is optional...
#required unless 'query' is an SQL query string (shouldn't be...)
'count_query' => 'SELECT COUNT(*) FROM tablename',
-
- 'count_addl' => [], #additional count fields listref of sprintf strings
- # [ $money_char.'%.2f total paid', ],
-
+
+ ###
+ # recommended / common
+ ###
+
#listref of column labels, <TH>
- #required unless 'query' is an SQL query string
+ #recommended unless 'query' is an SQL query string
# (if not specified the database column names will be used)
- 'header' => [ '#', 'Item' ],
+ 'header' => [ '#',
+ 'Item',
+ { 'label' => 'Another Item',
+
+ },
+ ],
+
+ #listref - each item is a literal column name (or method) or coderef
+ #if not specified all columns will be shown
+ 'fields' => [
+ 'column',
+ sub { my $row = shift; $row->column; },
+ ],
+
+ #redirect if there's only one item...
+ # listref of URL base and column name (or method)
+ # or a coderef that returns the same
+ 'redirect' =>
+ ###
+ # optional
+ ###
+
+ # some HTML callbacks...
+ 'menubar' => '', #menubar arrayref
+ 'html_init' => '', #after the header/menubar and before the pager
+ 'html_form' => '', #after the pager, right before the results
+ # (only shown if there are results)
+ # (use this for any form-opening tag rather than
+ # html_init, to avoid a nested form)
+ 'html_foot' => '', #at the bottom
+ 'html_posttotal' => '', #at the bottom
+ # (these three can be strings or coderefs)
+
+ 'count_addl' => [], #additional count fields listref of sprintf strings or coderefs
+ # [ $money_char.'%.2f total paid', ],
+
+ #second (smaller) header line, currently only for HTML
+ 'header2 => [ '#',
+ 'Item',
+ { 'label' => 'Another Item',
+
+ },
+ ],
+
+ #listref of column footers
+ 'footer' => [],
+
+ #disabling things
'disable_download' => '', # set true to hide the CSV/Excel download links
+ 'disable_total' => '', # set true to hide the total"
+ 'disable_maxselect' => '', # set true to disable record/page selection
'disable_nonefound' => '', # set true to disable the "No matching Xs found"
# message
- 'disableable' => 1, # set true if this table has a "disabled" field, to
- # hide disabled records & have "show disabled" links
+ #handling "disabled" fields in the records
+ 'disableable' => 1, # set set to 1 (or column position for "disabled"
+ # status col) to enable if this table has a "disabled"
+ # field, to hide disabled records & have
+ # "show disabled/hide disabled" links
+ #(can't be used with a literal query)
'disabled_statuspos' => 3, #optional position (starting from 0) to insert
#a Status column when showing disabled records
#(query needs to be a qsearch hashref and
# header & fields need to be defined)
+
+ #handling agent virtualization
'agent_virt' => 1, # set true if this search should be agent-virtualized
'agent_null_right' => 'Access Right', #opt. right to view global records
'agent_pos' => 3, #optional position (starting from 0) to insert
#an Agent column
#(query needs to be a qsearch hashref and
# header & fields need to be defined)
+
+ # link & display properties for fields
- #listref - each item is a literal column name (or method) or coderef
- #if not specified all columns will be shown
- 'fields' => [
- 'column',
- sub { my $row = shift; $row->column; },
- ],
-
- #listref of column footers
- 'footer' => [],
-
- #listref - each item is the empty string, or a listref of ...
- 'links' =>
-
-
- 'align' => 'lrc.', #one letter for each column, left/right/center/none
- # can also pass a listref with full values:
- # [ 'left', 'right', 'center', '' ]
+ #listref - each item is the empty string,
+ # or a listref of link and method name to append,
+ # or a listref of link and coderef to run and append
+ # or a coderef that returns such a listref
+ 'links' => [],`
+
+ #listref - each item is the empty string,
+ # or a string onClick handler for the corresponding link
+ # or a coderef that returns string onClick handler
+ 'link_onclicks' => [],
+
+ #one letter for each column, left/right/center/none
+ # or pass a listref with full values: [ 'left', 'right', 'center', '' ]
+ 'align' => 'lrc.',
- #listrefs...
+ #listrefs of ( scalars or coderefs )
#currently only HTML, maybe eventually Excel too
'color' => [],
'size' => [],
- 'style' => [],
+ 'style' => [], #<B> or <I>, etc.
+ 'cell_style' => [], #STYLE= attribute of TR, very HTML-specific...
- #redirect if there's only one item...
- # listref of URL base and column name (or method)
- # or a coderef that returns the same
- 'redirect' =>
-
- #set to 1 (or column position for "disabled" status col) to enable
- #"show disabled/hide disabled" links
- #(can't be used with a literal query)
- 'disableable' => 1,
-
);
</%doc>
% } elsif ( $type =~ /\.xls$/ ) {
%
% #http_header('Content-Type' => 'application/excel' ); #eww
-% http_header('Content-Type' => 'application/vnd.ms-excel' );
% #http_header('Content-Type' => 'application/msexcel' ); #alas
+% #http_header('Content-Type' => 'application/x-msexcel' ); #?
+%
+% #http://support.microsoft.com/kb/199841
+% http_header('Content-Type' => 'application/vnd.ms-excel' );
+%
+% #http://support.microsoft.com/kb/812935
+% #http://support.microsoft.com/kb/323308
+% $HTML::Mason::Commands::r->headers_out->{'Cache-control'} = 'max-age=0';
%
% my $data = '';
% my $XLS = new IO::Scalar \$data;
<% include( '/elements/header-popup.html', $opt{'title'} ) %>
+% } elsif ( $type eq 'select' ) {
+
+ <% include( '/elements/header-popup.html', $opt{'title'} ) %>
+ <% defined($opt{'html_init'})
+ ? ( ref($opt{'html_init'})
+ ? &{$opt{'html_init'}}()
+ : $opt{'html_init'}
+ )
+ : ''
+ %>
+
% } else {
%
% my @menubar = ();
% unless ( $opt{'disable_nonefound'} ) {
No matching <% $opt{'name'} %> found.<BR>
% }
-% } else {
+% }
+%
+% if ( $total || $opt{'disableable'} ) { #hmm... and there *are* ones to show??
<TABLE>
<TR>
<FORM>
- <% $total %> total <% $opt{'name'} %>
+% if (! $opt{'disable_total'}) {
+ <% $total %> total <% $opt{'name'} %>
+% }
-% if ( $confmax && $total > $confmax && $type ne 'html-print' ) {
+% if ( $confmax && $total > $confmax
+% && ! $opt{'disable_maxselect'}
+% && $type ne 'html-print' )
+% {
% $cgi->delete('maxrecords');
% $cgi->param('_dummy', 1);
%# ( show <SELECT NAME="maxrecords" onChange="this.form.submit();">
- ( show <SELECT NAME="maxrecords" onChange="window.location = '<% $cgi->self_url %>;maxrecords=' + this.options[this.selectedIndex].value;">
% foreach my $max ( map { $_ * $confmax } qw( 1 5 10 25 ) ) {
<OPTION VALUE="<% $max %>" <% ( $maxrecords == $max ) ? 'SELECTED' : '' %>><% $max %></OPTION>
<BR>
% if ( $opt{'count_addl'} ) {
-% my $n=0; foreach my $count ( @{$opt{'count_addl'}} ) {
- <% sprintf( $count, $count_arrayref->[++$n] ) %><BR>
+% my $n=0;
+% foreach my $count ( @{$opt{'count_addl'}} ) {
+% my $data = $count_arrayref->[++$n];
+% if ( ref($count) ) {
+ <% &{ $count }( $data ) %>
+% } else {
+ <% sprintf( $count, $data ) %><BR>
+% }
% }
% }
</FORM>
% $cgi->param('_type', 'html-print');
as <A HREF="<% $cgi->self_url %>">printable copy</A>
+ <% $opt{'extra_choices_callback'}
+ ? &{$opt{'extra_choices_callback'}}($cgi->query_string)
+ : ''
+ %>
+
</TD>
% $cgi->param('_type', "html" );
% }
<% include('/elements/table-grid.html') %>
<TR>
-% foreach my $header ( @$header ) {
- <TH CLASS="grid" BGCOLOR="#cccccc"><% $header %></TH>
+% my $h2 = 0;
+% foreach my $header ( @{ $opt{header} } ) {
+% my $label = ref($header) ? $header->{label} : $header;
+% my $rowspan = 1;
+% my $style = '';
+% if ( $opt{header2} ) {
+% if ( !length($opt{header2}->[$h2]) ) {
+% $rowspan = 2;
+% splice @{ $opt{header2} }, $h2, 1;
+% } else {
+% $h2++;
+% $style = 'STYLE="border-bottom: none"'
+% }
+% }
+ <TH CLASS = "grid"
+ BGCOLOR = "#cccccc"
+ ROWSPAN = "<% $rowspan %>"
+ <% $style %>
+
+ >
+ <% $label %>
+ </TH>
% }
</TR>
+% if ( $opt{header2} ) {
+ <TR>
+% foreach my $header ( @{ $opt{header2} } ) {
+% my $label = ref($header) ? $header->{label} : $header;
+ <TH CLASS="grid" BGCOLOR="#cccccc">
+ <FONT SIZE="-1"><% $label %></FONT>
+ </TH>
+% }
+ </TR>
+% }
+
% my $bgcolor1 = '#eeeeee';
% my $bgcolor2 = '#ffffff';
% my $bgcolor;
% if ( $opt{'fields'} ) {
%
-% my $links = $opt{'links'} ? [ @{$opt{'links'}} ] : '';
-% 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 $links = $opt{'links'} ? [ @{$opt{'links'}} ] : '';
+% my $onclicks = $opt{'link_onclicks'} ? [ @{$opt{'link_onclicks'}} ] : [];
+% 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'}} ] : [];
%
% foreach my $field (
%
% my $a = '';
% if ( $links ) {
% my $link = shift @$links;
-% $link = &{$link}($row) if ref($link) eq 'CODE';
+% $link = &{$link}($row)
+% if ref($link) eq 'CODE';
+%
+% my $onclick = shift @$onclicks;
+% $onclick = &{$onclick}($row)
+% if ref($onclick) eq 'CODE';
+% $onclick = qq( onClick="$onclick") if $onclick;
+%
% if ( $link ) {
% my( $url, $method ) = @{$link};
% if ( ref($method) eq 'CODE' ) {
% } else {
% $a = $url. $row->$method();
% }
-% $a = qq(<A HREF="$a">);
+% $a = qq(<A HREF="$a"$onclick>);
% }
% }
%
% $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;
- <TD CLASS="<% $class %>" BGCOLOR="<% $bgcolor %>"<% $align %>><% $font %><% $a %><% $s %><% $field %><% $es %><% $a ? '</A>' : '' %><% $font ? '</FONT>' : '' %></TD>
+ <TD CLASS="<% $class %>" BGCOLOR="<% $bgcolor %>" <% $align %> <% $cstyle %>><% $font %><% $a %><% $s %><% $field %><% $es %><% $a ? '</A>' : '' %><% $font ? '</FONT>' : '' %></TD>
% }
%
splice @{ $opt{'color'} }, $pos, 0, '';
splice @{ $opt{'links'} }, $pos, 0, '' #[ 'agent link?', 'agentnum' ]
if $opt{'links'};
+ splice @{ $opt{'link_onclicks'} }, $pos, 0, ''
+ if $opt{'link_onclicks'};
}
sub { shift->disabled ? 'FF0000' : '00CC00'; };
splice @{ $opt{'links'} }, $pos, 0, ''
if $opt{'links'};
+ splice @{ $opt{'link_onlicks'} }, $pos, 0, ''
+ if $opt{'link_onlicks'};
}
#add show/hide disabled links
}
-my $type = $cgi->param('_type') =~ /^(csv|\w*\.xls|html(-print)?)$/
+my $type = $cgi->param('_type') =~ /^(csv|\w*\.xls|select|html(-print)?)$/
? $1 : 'html';
my $limit = '';
# run the query
-my $header = $opt{header};
+my $header = [ map { ref($_) ? $_->{'label'} : $_ } @{$opt{header}} ];
my $rows;
if ( ref($opt{query}) ) {