checkpoint tax editors and correct a blunder
[freeside.git] / httemplate / search / elements / search.html
index f310388..40c71d8 100644 (file)
@@ -4,7 +4,10 @@ Example:
 
   include( 'elements/search.html',
 
-    # basic options, required
+    ###
+    # required
+    ###
+
     'title'         => 'Page title',
     
     'name_singular' => 'item',  #singular name for the records returned
@@ -12,20 +15,8 @@ Example:
     '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...
@@ -44,66 +35,112 @@ Example:
    
     #required unless 'query' is an SQL query string (shouldn't be...)
     'count_query' => 'SELECT COUNT(*) FROM tablename',
+
+    ###
+    # recommended / common
+    ###
+
+    #listref of column labels, <TH>
+    #recommended unless 'query' is an SQL query string
+    # (if not specified the database column names will be used)
+    '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', ],
    
-    #listref of column labels, <TH>
-    #required unless 'query' is an SQL query string
-    # (if not specified the database column names will be used)
-    'header'      => [ '#', 'Item' ],
-   
+    #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>
@@ -165,7 +202,7 @@ Example:
 %   #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;
 %   my $workbook = Spreadsheet::WriteExcel->new($XLS)
@@ -256,6 +293,17 @@ Example:
 
         <% 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 = ();
@@ -284,7 +332,9 @@ Example:
 %       unless ( $opt{'disable_nonefound'} ) { 
           No matching <% $opt{'name'} %> found.<BR>
 %       } 
-%     } else { 
+%     }
+%
+%     if ( $total || $opt{'disableable'} ) { #hmm... and there *are* ones to show??
 
         <TABLE>
           <TR>
@@ -293,14 +343,18 @@ Example:
 
               <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>
@@ -349,6 +403,11 @@ Example:
 %               $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" ); 
 %           } 
@@ -381,11 +440,42 @@ Example:
               <% 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;
@@ -402,11 +492,13 @@ Example:
 
 %                   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 (
 %
@@ -489,7 +581,14 @@ Example:
 %                       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' ) {
@@ -497,7 +596,7 @@ Example:
 %                           } else {
 %                             $a = $url. $row->$method();
 %                           }
-%                           $a = qq(<A HREF="$a">);
+%                           $a = qq(<A HREF="$a"$onclick>);
 %                         }
 %                       }
 %
@@ -520,8 +619,13 @@ Example:
 %                         $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>
 
 %                     } 
 %
@@ -626,6 +730,8 @@ if ( $opt{'agent_virt'} ) {
     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'};
 
   }
 
@@ -661,6 +767,8 @@ if ( $opt{'disableable'} ) {
       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
@@ -679,7 +787,7 @@ if ( $opt{'disableable'} ) {
 
 }
 
-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 = '';
@@ -728,7 +836,7 @@ unless ( $type =~ /^(csv|\w*\.xls)$/ ) {
 
 # run the query
 
-my $header = $opt{header};
+my $header = [ map { ref($_) ? $_->{'label'} : $_ } @{$opt{header}} ];
 my $rows;
 if ( ref($opt{query}) ) {