[Bio] / Sprout / SearchHelper.pm Repository:
ViewVC logotype

Diff of /Sprout/SearchHelper.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.37, Mon Aug 20 23:22:42 2007 UTC revision 1.44, Thu Feb 5 07:17:03 2009 UTC
# Line 19  Line 19 
19      use URI::Escape;      use URI::Escape;
20      use PageBuilder;      use PageBuilder;
21      use AliasAnalysis;      use AliasAnalysis;
22        use CGI::Cookie;
23      use FreezeThaw qw(freeze thaw);      use FreezeThaw qw(freeze thaw);
24    
25  =head1 Search Helper Base Class  =head1 Search Helper Base Class
# Line 85  Line 86 
86    
87  List of the parameters that are used to select multiple genomes.  List of the parameters that are used to select multiple genomes.
88    
89    =item notices
90    
91    A list of messages to be put in the notice file.
92    
93  =back  =back
94    
95  =head2 Adding a new Search Tool  =head2 Adding a new Search Tool
# Line 241  Line 246 
246    
247  =head3 new  =head3 new
248    
249  C<< my $shelp = SearchHelper->new($cgi); >>      my $shelp = SearchHelper->new($cgi);
250    
251  Construct a new SearchHelper object.  Construct a new SearchHelper object.
252    
# Line 258  Line 263 
263  sub new {  sub new {
264      # Get the parameters.      # Get the parameters.
265      my ($class, $cgi) = @_;      my ($class, $cgi) = @_;
266      # Check for a session ID.      # Check for a session ID. First we look in the CGI parameters.
267      my $session_id = $cgi->param("SessionID");      my $session_id = $cgi->param("SessionID");
268      my $type = "old";      my $type = "old";
269      if (! $session_id) {      if (! $session_id) {
270            # We need a session ID. Try to get it from the cookies.
271            my %cookies = fetch CGI::Cookie;
272            my $session_cookie = $cookies{$class};
273            if (! $session_cookie) {
274          Trace("No session ID found.") if T(3);          Trace("No session ID found.") if T(3);
275          # Here we're starting a new session. We create the session ID and          # Here we're starting a new session. We create the session ID and
276          # store it in the query object.              # store it in a cookie.
277          $session_id = FIGRules::NewSessionID();          $session_id = FIGRules::NewSessionID();
278          Trace("New session ID is $session_id.") if T(3);          Trace("New session ID is $session_id.") if T(3);
279                $session_cookie = new CGI::Cookie(-name => $class,
280                                                  -value => $session_id);
281                $session_cookie->bake();
282            } else {
283                # Here we're recovering an old session. The session ID is
284                # used to find any old search options lying around, but we're
285                # still considered a new session.
286                $session_id = $session_cookie->value();
287                Trace("Session $session_id recovered from cookie.") if T(3);
288            }
289            # Denote this is a new session.
290          $type = "new";          $type = "new";
291            # Put the session IS in the parameters.
292          $cgi->param(-name => 'SessionID', -value => $session_id);          $cgi->param(-name => 'SessionID', -value => $session_id);
293      } else {      } else {
294          Trace("Session ID is $session_id.") if T(3);          Trace("Session ID is $session_id.") if T(3);
# Line 303  Line 324 
324                    scriptQueue => [],                    scriptQueue => [],
325                    genomeList => undef,                    genomeList => undef,
326                    genomeParms => [],                    genomeParms => [],
327                      notices => [],
328                   };                   };
329      # Bless and return it.      # Bless and return it.
330      bless $retVal, $class;      bless $retVal, $class;
# Line 311  Line 333 
333    
334  =head3 Q  =head3 Q
335    
336  C<< my $query = $shelp->Q(); >>      my $query = $shelp->Q();
337    
338  Return the CGI query object.  Return the CGI query object.
339    
# Line 325  Line 347 
347  }  }
348    
349    
   
350  =head3 DB  =head3 DB
351    
352  C<< my $sprout = $shelp->DB(); >>      my $sprout = $shelp->DB();
353    
354  Return the Sprout database object.  Return the Sprout database object.
355    
# Line 349  Line 370 
370    
371  =head3 IsNew  =head3 IsNew
372    
373  C<< my $flag = $shelp->IsNew(); >>      my $flag = $shelp->IsNew();
374    
375  Return TRUE if this is a new session, FALSE if this is an old session. An old  Return TRUE if this is a new session, FALSE if this is an old session. An old
376  session already has search results ready to process.  session already has search results ready to process.
# Line 365  Line 386 
386    
387  =head3 ID  =head3 ID
388    
389  C<< my $sessionID = $shelp->ID(); >>      my $sessionID = $shelp->ID();
390    
391  Return the current session ID.  Return the current session ID.
392    
# Line 380  Line 401 
401    
402  =head3 FormName  =head3 FormName
403    
404  C<< my $name = $shelp->FormName(); >>      my $name = $shelp->FormName();
405    
406  Return the name of the form this helper object will generate.  Return the name of the form this helper object will generate.
407    
# Line 395  Line 416 
416    
417  =head3 QueueFormScript  =head3 QueueFormScript
418    
419  C<< $shelp->QueueFormScript($statement); >>      $shelp->QueueFormScript($statement);
420    
421  Add the specified statement to the queue of JavaScript statements that are to be  Add the specified statement to the queue of JavaScript statements that are to be
422  executed when the form has been fully defined. This is necessary because until  executed when the form has been fully defined. This is necessary because until
# Line 430  Line 451 
451    
452  =head3 FormStart  =head3 FormStart
453    
454  C<< my $html = $shelp->FormStart($title); >>      my $html = $shelp->FormStart($title);
455    
456  Return the initial section of a form designed to perform another search of the  Return the initial section of a form designed to perform another search of the
457  same type. The form header is included along with hidden fields to persist the  same type. The form header is included along with hidden fields to persist the
# Line 460  Line 481 
481      # Start the form. Note we use the override option on the Class value, in      # Start the form. Note we use the override option on the Class value, in
482      # case the Advanced button was used.      # case the Advanced button was used.
483      my $retVal = "<div class=\"search\">\n" .      my $retVal = "<div class=\"search\">\n" .
484                   $cgi->start_form(-method => 'POST',                   CGI::start_form(-method => 'POST',
485                                    -action => $cgi->url(-relative => 1),                                    -action => "$FIG_Config::cgi_url/wiki/rest.cgi/NmpdrPlugin/search",
486                                    -name => $self->FormName()) .                                    -name => $self->FormName()) .
487                   $cgi->hidden(-name => 'Class',                   CGI::hidden(-name => 'Class',
488                                -value => $self->{class},                                -value => $self->{class}) .
489                                -override => 1) .                   CGI::hidden(-name => 'SPROUT',
                  $cgi->hidden(-name => 'SPROUT',  
490                                -value => 1) .                                -value => 1) .
491                   $cgi->h3("$title" . Hint($self->{class}, "Click here for more information."));                   CGI::h3("$title" . Hint($self->{class}, "Click here for more information."));
492      # Put in an anchor tag in case there's a table of contents.      # Put in an anchor tag in case there's a table of contents.
493      my $anchorName = $self->FormName();      my $anchorName = $self->FormName();
494      $retVal .= "<a name=\"$anchorName\"></a>\n";      $retVal .= "<a name=\"$anchorName\"></a>\n";
# Line 478  Line 498 
498    
499  =head3 FormEnd  =head3 FormEnd
500    
501  C<< my $htmlText = $shelp->FormEnd(); >>      my $htmlText = $shelp->FormEnd();
502    
503  Return the HTML text for closing a search form. This closes both the C<form> and  Return the HTML text for closing a search form. This closes both the C<form> and
504  C<div> tags.  C<div> tags.
# Line 510  Line 530 
530    
531  =head3 SetMessage  =head3 SetMessage
532    
533  C<< $shelp->SetMessage($msg); >>      $shelp->SetMessage($msg);
534    
535  Store the specified text as the result message. The result message is displayed  Store the specified text as the result message. The result message is displayed
536  if an invalid parameter value is specified.  if an invalid parameter value is specified.
# Line 534  Line 554 
554    
555  =head3 Message  =head3 Message
556    
557  C<< my $text = $shelp->Message(); >>      my $text = $shelp->Message();
558    
559  Return the result message. The result message is displayed if an invalid parameter  Return the result message. The result message is displayed if an invalid parameter
560  value is specified.  value is specified.
# Line 550  Line 570 
570    
571  =head3 OpenSession  =head3 OpenSession
572    
573  C<< $shelp->OpenSession($rhelp); >>      $shelp->OpenSession($rhelp);
574    
575  Set up the session cache file and write out the column headers.  Set up the session cache file and write out the column headers.
576  This method should not be called until all the columns have  This method should not be called until all the columns have
# Line 585  Line 605 
605    
606  =head3 GetCacheFileName  =head3 GetCacheFileName
607    
608  C<< my $fileName = $shelp->GetCacheFileName(); >>      my $fileName = $shelp->GetCacheFileName();
609    
610  Return the name to be used for this session's cache file.  Return the name to be used for this session's cache file.
611    
# Line 600  Line 620 
620    
621  =head3 GetTempFileName  =head3 GetTempFileName
622    
623  C<< my $fileName = $shelp->GetTempFileName($type); >>      my $fileName = $shelp->GetTempFileName($type);
624    
625  Return the name to be used for a temporary file of the specified type. The  Return the name to be used for a temporary file of the specified type. The
626  name is computed from the session name with the type as a suffix.  name is computed from the session name with the type as a suffix.
# Line 631  Line 651 
651    
652  =head3 WriteColumnHeaders  =head3 WriteColumnHeaders
653    
654  C<< $shelp->WriteColumnHeaders(@colNames); >>      $shelp->WriteColumnHeaders(@colNames);
655    
656  Write out the column headers for the current search session. The column headers  Write out the column headers for the current search session. The column headers
657  are sent to the cache file, and then the cache is re-opened as a sort pipe and  are sent to the cache file, and then the cache is re-opened as a sort pipe and
# Line 666  Line 686 
686      $self->{fileHandle} = Open(undef, "| sort | cut --fields=2- >>$fileName");      $self->{fileHandle} = Open(undef, "| sort | cut --fields=2- >>$fileName");
687  }  }
688    
689    =head3 SetNotice
690    
691        $shelp->SetNotice($message);
692    
693    This method creates a notice that will be displayed on the search results
694    page. After the search is complete, notices are placed in a small temporary
695    file that is checked by the results display engine.
696    
697    =over 4
698    
699    =item message
700    
701    Message to write to the notice file.
702    
703    =back
704    
705    =cut
706    
707    sub SetNotice {
708        # Get the parameters.
709        my ($self, $message) = @_;
710        # Save the message.
711        push @{$self->{notices}}, $message;
712    }
713    
714    
715  =head3 ReadColumnHeaders  =head3 ReadColumnHeaders
716    
717  C<< my @colHdrs = $shelp->ReadColumnHeaders($fh); >>      my @colHdrs = $shelp->ReadColumnHeaders($fh);
718    
719  Read the column headers from the specified file handle. The column headers are  Read the column headers from the specified file handle. The column headers are
720  frozen strings intermixed with frozen hash references. The strings represent  frozen strings intermixed with frozen hash references. The strings represent
# Line 700  Line 746 
746    
747  =head3 WriteColumnData  =head3 WriteColumnData
748    
749  C<< $shelp->WriteColumnData($key, @colValues); >>      $shelp->WriteColumnData($key, @colValues);
750    
751  Write a row of column values to the current search session. It is assumed that  Write a row of column values to the current search session. It is assumed that
752  the session file is already open for output.  the session file is already open for output.
# Line 729  Line 775 
775    
776  =head3 CloseSession  =head3 CloseSession
777    
778  C<< $shelp->CloseSession(); >>      $shelp->CloseSession();
779    
780  Close the session file.  Close the session file.
781    
# Line 747  Line 793 
793          my $cgi = $self->Q();          my $cgi = $self->Q();
794          $self->PrintLine("Output formatting complete.<br />");          $self->PrintLine("Output formatting complete.<br />");
795      }      }
796        # Check for notices.
797        my @notices = @{$self->{notices}};
798        if (scalar @notices) {
799            # We have some, so put then in a notice file.
800            my $noticeFile = $self->GetTempFileName('notices');
801            my $nh = Open(undef, ">$noticeFile");
802            print $nh join("\n", @notices, "");
803            close $nh;
804            $self->PrintLine(scalar(@notices) . " notices saved.<br />");
805        }
806  }  }
807    
808  =head3 OrganismData  =head3 OrganismData
809    
810  C<< my ($orgName, $group) = $shelp->Organism($genomeID); >>      my ($orgName, $group) = $shelp->Organism($genomeID);
811    
812  Return the name and status of the organism corresponding to the specified genome ID.  Return the name and status of the organism corresponding to the specified genome ID.
813  For performance reasons, this information is cached in a special hash table, so we  For performance reasons, this information is cached in a special hash table, so we
# Line 803  Line 859 
859    
860  =head3 Organism  =head3 Organism
861    
862  C<< my $orgName = $shelp->Organism($genomeID); >>      my $orgName = $shelp->Organism($genomeID);
863    
864  Return the name of the relevant organism. The name is computed from the genus,  Return the name of the relevant organism. The name is computed from the genus,
865  species, and unique characterization. A cache is used to improve performance.  species, and unique characterization. A cache is used to improve performance.
# Line 833  Line 889 
889    
890  =head3 ComputeFASTA  =head3 ComputeFASTA
891    
892  C<< my $fasta = $shelp->ComputeFASTA($desiredType, $sequence, $flankingWidth); >>      my $fasta = $shelp->ComputeFASTA($desiredType, $sequence, $flankingWidth, $comments);
893    
894  Parse a sequence input and convert it into a FASTA string of the desired type with  Parse a sequence input and convert it into a FASTA string of the desired type with
895  the desired flanking width.  the desired flanking width.
# Line 860  Line 916 
916  protein translation of a feature doesn't always match the DNA and is taken directly  protein translation of a feature doesn't always match the DNA and is taken directly
917  from the database.  from the database.
918    
919    =item comments
920    
921    Comment string to be added to the FASTA header.
922    
923  =item RETURN  =item RETURN
924    
925  Returns a string in FASTA format representing the content of the desired sequence with  Returns a string in FASTA format representing the content of the desired sequence with
# Line 872  Line 932 
932    
933  sub ComputeFASTA {  sub ComputeFASTA {
934      # Get the parameters.      # Get the parameters.
935      my ($self, $desiredType, $sequence, $flankingWidth) = @_;      my ($self, $desiredType, $sequence, $flankingWidth, $comment) = @_;
936      # Declare the return variable. If an error occurs, it will remain undefined.      # Declare the return variable. If an error occurs, it will remain undefined.
937      my $retVal;      my $retVal;
938      # This variable will be cleared if an error is detected.      # This variable will be cleared if an error is detected.
# Line 903  Line 963 
963                  # In an emergency, fall back to the original ID.                  # In an emergency, fall back to the original ID.
964                  $fastaLabel = $fid;                  $fastaLabel = $fid;
965              }              }
966                # Add any specified comments.
967                if ($comment) {
968                    $fastaLabel .= " $comment";
969                }
970              # Now proceed according to the sequence type.              # Now proceed according to the sequence type.
971              if ($desiredType =~ /prot/) {              if ($desiredType =~ /prot/) {
972                  # We want protein, so get the translation.                  # We want protein, so get the translation.
# Line 994  Line 1058 
1058    
1059  =head3 SubsystemTree  =head3 SubsystemTree
1060    
1061  C<< my $tree = SearchHelper::SubsystemTree($sprout, %options); >>      my $tree = SearchHelper::SubsystemTree($sprout, %options);
1062    
1063  This method creates a subsystem selection tree suitable for passing to  This method creates a subsystem selection tree suitable for passing to
1064  L</SelectionTree>. Each leaf node in the tree will have a link to the  L</SelectionTree>. Each leaf node in the tree will have a link to the
# Line 1052  Line 1116 
1116              push @subs, $classLess;              push @subs, $classLess;
1117          }          }
1118      }      }
1119        # Get the seedviewer URL.
1120        my $svURL = $FIG_Config::linkinSV || "$FIG_Config::cgi_url/seedviewer.cgi";
1121        Trace("Seed Viewer URL is $svURL.") if T(3);
1122      # Declare the return variable.      # Declare the return variable.
1123      my @retVal = ();      my @retVal = ();
1124      # Each element in @subs represents a leaf node, so as we loop through it we will be      # Each element in @subs represents a leaf node, so as we loop through it we will be
# Line 1126  Line 1193 
1193              if ($optionThing->{links}) {              if ($optionThing->{links}) {
1194                  # Compute the link value.                  # Compute the link value.
1195                  my $linkable = uri_escape($id);                  my $linkable = uri_escape($id);
1196                  $nodeContent->{link} = "../FIG/display_subsys.cgi?ssa_name=$linkable;request=show_ssa;sort=by_phylo;show_clusters=1;SPROUT=1";                  $nodeContent->{link} = "$svURL?page=Subsystems;subsystem=$linkable";
1197              }              }
1198              if ($optionThing->{radio}) {              if ($optionThing->{radio}) {
1199                  # Compute the radio value.                  # Compute the radio value.
# Line 1144  Line 1211 
1211    
1212  =head3 NmpdrGenomeMenu  =head3 NmpdrGenomeMenu
1213    
1214  C<< my $htmlText = $shelp->NmpdrGenomeMenu($menuName, $multiple, \@selected, $rows); >>      my $htmlText = $shelp->NmpdrGenomeMenu($menuName, $multiple, \@selected, $rows);
1215    
1216  This method creates a hierarchical HTML menu for NMPDR genomes organized by category. The  This method creates a hierarchical HTML menu for NMPDR genomes organized by category. The
1217  category indicates the low-level NMPDR group. Organizing the genomes in this way makes it  category indicates the low-level NMPDR group. Organizing the genomes in this way makes it
# Line 1173  Line 1240 
1240    
1241  =item crossMenu (optional)  =item crossMenu (optional)
1242    
1243  If specified, is presumed to be the name of another genome menu whose contents  This is currently not supported.
 are to be mutually exclusive with the contents of this menu. As a result, instead  
 of the standard onChange event, the onChange event will deselect any entries in  
 the other menu.  
1244    
1245  =item RETURN  =item RETURN
1246    
# Line 1196  Line 1260 
1260      if (! defined $rows) {      if (! defined $rows) {
1261          $rows = ($multiple ? 10 : 1);          $rows = ($multiple ? 10 : 1);
1262      }      }
1263      # Create the multiple tag.      # Get a comma-delimited list of the preselected genomes.
1264      my $multipleTag = ($multiple ? " multiple" : "");      my $preselected = "";
1265      # Get the form name.      if ($selected) {
1266      my $formName = $self->FormName();          $preselected = join(", ", @$selected);
1267      # Check to see if we already have a genome list in memory.      }
1268      my $groupHash;      # Ask Sprout for a genome menu.
1269      my @groups;      my $retVal = $sprout->GenomeMenu(name => $menuName,
1270      my $nmpdrGroupCount;                                       multiSelect => $multiple,
1271      my $genomes = $self->{genomeList};                                       selected => $preselected,
1272      if (defined $genomes) {                                       size => $rows);
         # We have a list ready to use.  
         $groupHash = $genomes;  
         @groups = @{$self->{groupList}};  
         $nmpdrGroupCount = $self->{groupCount};  
     } else {  
         # Get a list of all the genomes in group order. In fact, we only need them ordered  
         # by name (genus,species,strain), but putting primary-group in front enables us to  
         # take advantage of an existing index.  
         my @genomeList = $sprout->GetAll(['Genome'],  
                                          "ORDER BY Genome(primary-group), Genome(genus), Genome(species), Genome(unique-characterization)",  
                                          [], ['Genome(primary-group)', 'Genome(id)',  
                                               'Genome(genus)', 'Genome(species)',  
                                               'Genome(unique-characterization)',  
                                               'Genome(taxonomy)']);  
         # Create a hash to organize the genomes by group. Each group will contain a list of  
         # 2-tuples, the first element being the genome ID and the second being the genome  
         # name.  
         my %gHash = ();  
         for my $genome (@genomeList) {  
             # Get the genome data.  
             my ($group, $genomeID, $genus, $species, $strain, $taxonomy) = @{$genome};  
             # Compute and cache its name and display group.  
             my ($name, $displayGroup, $domain) = $self->SaveOrganismData($group, $genomeID, $genus, $species,  
                                                                          $strain, $taxonomy);  
             # Push the genome into the group's list. Note that we use the real group  
             # name here, not the display group name.  
             push @{$gHash{$group}}, [$genomeID, $name, $domain];  
         }  
         # We are almost ready to unroll the menu out of the group hash. The final step is to separate  
         # the supporting genomes by domain. First, we sort the NMPDR groups.  
         @groups = sort grep { $_ ne $FIG_Config::otherGroup } keys %gHash;  
         # Remember the number of NMPDR groups.  
         $nmpdrGroupCount = scalar @groups;  
         # Loop through the supporting genomes, classifying them by domain. We'll also keep a list  
         # of the domains found.  
         my @otherGenomes = @{$gHash{$FIG_Config::otherGroup}};  
         my @domains = ();  
         for my $genomeData (@otherGenomes) {  
             my ($genomeID, $name, $domain) = @{$genomeData};  
             if (exists $gHash{$domain}) {  
                 push @{$gHash{$domain}}, $genomeData;  
             } else {  
                 $gHash{$domain} = [$genomeData];  
                 push @domains, $domain;  
             }  
         }  
         # Add the domain groups at the end of the main group list. The main group list will now  
         # contain all the categories we need to display the genomes.  
         push @groups, sort @domains;  
         # Delete the supporting group.  
         delete $gHash{$FIG_Config::otherGroup};  
         # Save the genome list for future use.  
         $self->{genomeList} = \%gHash;  
         $self->{groupList} = \@groups;  
         $self->{groupCount} = $nmpdrGroupCount;  
         $groupHash = \%gHash;  
     }  
     # Next, create a hash that specifies the pre-selected entries. Note that we need to deal  
     # with the possibility of undefined values in the incoming list.  
     my %selectedHash = ();  
     if (defined $selected) {  
         %selectedHash = map { $_ => 1 } grep { defined($_) } @{$selected};  
     }  
     # Now it gets complicated. We need a way to mark all the NMPDR genomes. We take advantage  
     # of the fact they come first in the list. We'll accumulate a count of the NMPDR genomes  
     # and use that to make the selections.  
     my $nmpdrCount = 0;  
     # Create the type counters.  
     my $groupCount = 1;  
     # Compute the ID for the status display.  
     my $divID = "${formName}_${menuName}_status";  
     # Compute the JavaScript call for updating the status.  
     my $showSelect = "showSelected($menuName, '$divID', 1000);";  
     # If multiple selection is supported, create an onChange event.  
     my $onChange = "";  
     if ($cross) {  
         # Here we have a paired menu. Selecting something in our menu unselects it in the  
         # other and redisplays the status of both.  
         $onChange = " onChange=\"crossUnSelect($menuName, '$divID', $cross, '${formName}_${cross}_status', 1000)\"";  
     } elsif ($multiple) {  
         # This is an unpaired menu, so all we do is redisplay our status.  
         $onChange = " onChange=\"$showSelect\"";  
     }  
     # Create the SELECT tag and stuff it into the output array.  
     my @lines = ("<SELECT name=\"$menuName\"$onChange$multipleTag size=\"$rows\">");  
     # Loop through the groups.  
     for my $group (@groups) {  
         # Create the option group tag.  
         my $tag = "<OPTGROUP label=\"$group\">";  
         push @lines, "  $tag";  
         # Get the genomes in the group.  
         for my $genome (@{$groupHash->{$group}}) {  
             # Count this organism if it's NMPDR.  
             if ($nmpdrGroupCount > 0) {  
                 $nmpdrCount++;  
             }  
             # Get the organism ID, name, and domain.  
             my ($genomeID, $name, $domain) = @{$genome};  
             # See if it's selected.  
             my $select = ($selectedHash{$genomeID} ? " selected" : "");  
             # Generate the option tag.  
             my $optionTag = "<OPTION class=\"$domain\" value=\"$genomeID\"$select>$name <em>($genomeID)</em></OPTION>";  
             push @lines, "    $optionTag";  
         }  
         # Close the option group.  
         push @lines, "  </OPTGROUP>";  
         # Record this group in the nmpdrGroup count. When that gets to 0, we've finished the NMPDR  
         # groups.  
         $nmpdrGroupCount--;  
     }  
     # Close the SELECT tag.  
     push @lines, "</SELECT>";  
     # Check for multiple selection.  
     if ($multiple) {  
         # Multi-select is on, so we need to add some selection helpers. First is  
         # the search box. This allows the user to type text and have all genomes containing  
         # the text selected automatically.  
         my $searchThingName = "${menuName}_SearchThing";  
         push @lines, "<br />" .  
                      "<INPUT type=\"button\" name=\"MacroSearch\" class=\"button\" value=\"Select genomes containing\" onClick=\"selectViaSearch($menuName, $searchThingName); $showSelect\" />&nbsp;" .  
                      "<INPUT type=\"text\" name=\"$searchThingName\" size=\"30\" />" . Hint("Genome Control",  
                                                                                             "Enter a genome number, then click the button to the left " .  
                                                                                             "in order to select the genome with that number. " .  
                                                                                             "Enter a genus, species, or strain and click the " .  
                                                                                             "button to select all genomes with that genus, species, " .  
                                                                                             "or strain name.");  
         # Next are the buttons to set and clear selections.  
         push @lines, "<br />";  
         push @lines, "<INPUT type=\"button\" name=\"ClearAll\" class=\"bigButton\"  value=\"Clear All\" onClick=\"clearAll($menuName); $showSelect\" />";  
         push @lines, "<INPUT type=\"button\" name=\"SelectAll\" class=\"bigButton\" value=\"Select All\" onClick=\"selectAll($menuName); $showSelect\" />";  
         push @lines, "<INPUT type=\"button\" name=\"NMPDROnly\" class=\"bigButton\"  value=\"Select NMPDR\" onClick=\"selectSome($menuName, $nmpdrCount, true); $showSelect\" />";  
         # push @lines, "<INPUT type=\"button\" name=\"OtherOnly\" class=\"bigButton\" value=\"Select Supporting\" onClick=\"selectSome($menuName, $nmpdrCount, false); $showSelect\" />";  
         # Add the status display, too.  
         push @lines, "<DIV id=\"$divID\" class=\"selectStatus\"></DIV>";  
         # Queue to update the status display when the form loads. We need to modify the show statement  
         # slightly because the queued statements are executed outside the form. This may seem like a lot of  
         # trouble, but we want all of the show statement calls to be generated from a single line of code,  
         # in case we decide to twiddle the parameters.  
         $showSelect =~ s/showSelected\(/showSelected\(thisForm\./;  
         $self->QueueFormScript($showSelect);  
         # Finally, add this parameter to the list of genome parameters. This enables us to  
         # easily find all the parameters used to select one or more genomes.  
         push @{$self->{genomeParms}}, $menuName;  
     }  
     # Assemble all the lines into a string.  
     my $retVal = join("\n", @lines, "");  
1273      # Return the result.      # Return the result.
1274      return $retVal;      return $retVal;
1275  }  }
1276    
1277  =head3 PropertyMenu  =head3 PropertyMenu
1278    
1279  C<< my $htmlText = $shelp->PropertyMenu($menuName, $selected, $force); >>      my $htmlText = $shelp->PropertyMenu($menuName, $selected, $force);
1280    
1281  Generate a property name dropdown menu.  Generate a property name dropdown menu.
1282    
# Line 1400  Line 1318 
1318      # Get all the property names, putting them after the null choice if one exists.      # Get all the property names, putting them after the null choice if one exists.
1319      push @propNames, $sprout->GetChoices('Property', 'property-name');      push @propNames, $sprout->GetChoices('Property', 'property-name');
1320      # Create a menu from them.      # Create a menu from them.
1321      my $retVal = $cgi->popup_menu(-name=> $menuName, -values => \@propNames,      my $retVal = CGI::popup_menu(-name=> $menuName, -values => \@propNames,
1322                                    -default => $selected);                                    -default => $selected);
1323      # Return the result.      # Return the result.
1324      return $retVal;      return $retVal;
# Line 1408  Line 1326 
1326    
1327  =head3 MakeTable  =head3 MakeTable
1328    
1329  C<< my $htmlText = $shelp->MakeTable(\@rows); >>      my $htmlText = $shelp->MakeTable(\@rows);
1330    
1331  Create a table from a group of table rows. The table rows must be fully pre-formatted: in  Create a table from a group of table rows. The table rows must be fully pre-formatted: in
1332  other words, each must have the TR and TD tags included.  other words, each must have the TR and TD tags included.
# Line 1462  Line 1380 
1380          }          }
1381      }      }
1382      # Create the table.      # Create the table.
1383      my $retVal = $cgi->table({border => 2, cellspacing => 2,      my $retVal = CGI::table({border => 2, cellspacing => 2,
1384                                width => 700, class => 'search'},                                width => 700, class => 'search'},
1385                               @{$rows});                               @{$rows});
1386      # Return the result.      # Return the result.
# Line 1471  Line 1389 
1389    
1390  =head3 SubmitRow  =head3 SubmitRow
1391    
1392  C<< my $htmlText = $shelp->SubmitRow($caption); >>      my $htmlText = $shelp->SubmitRow($caption);
1393    
1394  Returns the HTML text for the row containing the page size control  Returns the HTML text for the row containing the page size control
1395  and the submit button. All searches should have this row somewhere  and the submit button. All searches should have this row somewhere
# Line 1503  Line 1421 
1421      # Get the current feature ID type.      # Get the current feature ID type.
1422      my $aliasType = $self->GetPreferredAliasType();      my $aliasType = $self->GetPreferredAliasType();
1423      # Create the rows.      # Create the rows.
1424      my $retVal = $cgi->Tr($cgi->td("Identifier Type "),      my $retVal = CGI::Tr(CGI::td("Identifier Type "),
1425                            $cgi->td({ colspan => 2 },                            CGI::td({ colspan => 2 },
1426                                     $cgi->popup_menu(-name => 'AliasType',                                     CGI::popup_menu(-name => 'AliasType',
1427                                                      -values => ['FIG', AliasAnalysis::AliasTypes() ],                                                      -values => ['FIG', AliasAnalysis::AliasTypes() ],
1428                                                      -default => $aliasType) .                                                      -default => $aliasType) .
1429                                     Hint("Identifier type", "Specify how you want gene names to be displayed."))) .                                     Hint("Identifier Type", "Specify how you want gene names to be displayed."))) .
1430                   "\n" .                   "\n" .
1431                   $cgi->Tr($cgi->td("Results/Page"),                   CGI::Tr(CGI::td("Results/Page"),
1432                            $cgi->td($cgi->popup_menu(-name => 'PageSize',                            CGI::td(CGI::popup_menu(-name => 'PageSize',
1433                                                      -values => [10, 25, 50, 100, 1000],                                                      -values => [10, 25, 50, 100, 1000],
1434                                                      -default => $pageSize)),                                                      -default => $pageSize)),
1435                            $cgi->td($cgi->submit(-class => 'goButton',                            CGI::td(CGI::submit(-class => 'goButton',
1436                                                  -name => 'Search',                                                  -name => 'Search',
1437                                                  -value => $realCaption)));                                                  -value => $realCaption)));
1438      # Return the result.      # Return the result.
# Line 1523  Line 1441 
1441    
1442  =head3 GetGenomes  =head3 GetGenomes
1443    
1444  C<< my @genomeList = $shelp->GetGenomes($parmName); >>      my @genomeList = $shelp->GetGenomes($parmName);
1445    
1446  Return the list of genomes specified by the specified CGI query parameter.  Return the list of genomes specified by the specified CGI query parameter.
1447  If the request method is POST, then the list of genome IDs is returned  If the request method is POST, then the list of genome IDs is returned
# Line 1565  Line 1483 
1483      return @retVal;      return @retVal;
1484  }  }
1485    
 =head3 GetHelpText  
   
 C<< my $htmlText = $shelp->GetHelpText(); >>  
   
 Get the help text for this search. The help text is stored in files on the template  
 server. The help text for a specific search is taken from a file named  
 C<SearchHelp_>I<class>C<.inc> in the template directory C<$FIG_Config::template_url>.  
 There are also three standard help files: C<SearchHelp1_Filtering.inc> describes the  
 feature filtering performed by the B<RHFeatures> object, C<SearchHelp1_GenomeControl.inc>  
 describes how to use a multiple-selection genome control, and C<SearchHelp1_Standard.inc>  
 describes the standard controls for a search, such as page size, URL display, and  
 external alias display.  
   
 =cut  
   
 sub GetHelpText {  
     # Get the parameters.  
     my ($self) = @_;  
     # Create a list to hold the pieces of the help.  
     my @helps = ();  
     # Get the template directory URL.  
     my $urlBase = $FIG_Config::template_url;  
     # Start with the specific help.  
     my $class = $self->{class};  
     push @helps, PageBuilder::GetPage("$urlBase/SearchHelp_$class.inc");  
     # Add the genome control help if needed.  
     if (scalar @{$self->{genomeParms}}) {  
         push @helps, PageBuilder::GetPage("$urlBase/SearchHelp1_GenomeControl.inc");  
     }  
     # Next the filter help.  
     if ($self->{filtered}) {  
         push @helps, PageBuilder::GetPage("$urlBase/SearchHelp1_Filtering.inc");  
     }  
     # Finally, the standard help.  
     push @helps, PageBuilder::GetPage("$urlBase/SearchHelp1_Standard.inc");  
     # Assemble the pieces.  
     my $retVal = join("\n<p>&nbsp;</p>\n", @helps);  
     # Return the result.  
     return $retVal;  
 }  
   
1486  =head3 ComputeSearchURL  =head3 ComputeSearchURL
1487    
1488  C<< my $url = $shelp->ComputeSearchURL(%overrides); >>      my $url = $shelp->ComputeSearchURL(%overrides);
1489    
1490  Compute the GET-style URL for the current search. In order for this to work, there  Compute the GET-style URL for the current search. In order for this to work, there
1491  must be a copy of the search form on the current page. This will always be the  must be a copy of the search form on the current page. This will always be the
# Line 1641  Line 1518 
1518      my $cgi = $self->Q();      my $cgi = $self->Q();
1519      my $sprout = $self->DB();      my $sprout = $self->DB();
1520      # Start with the full URL.      # Start with the full URL.
1521      my $retVal = $cgi->url(-full => 1);      my $retVal = "$FIG_Config::cgi_url/SearchSkeleton.cgi";
1522      # Get all the query parameters in a hash.      # Get all the query parameters in a hash.
1523      my %parms = $cgi->Vars();      my %parms = $cgi->Vars();
1524      # Now we need to do some fixing. Each multi-valued parameter is encoded as a string with null      # Now we need to do some fixing. Each multi-valued parameter is encoded as a string with null
# Line 1701  Line 1578 
1578    
1579  =head3 AdvancedClassList  =head3 AdvancedClassList
1580    
1581  C<< my @classes = SearchHelper::AdvancedClassList(); >>      my @classes = SearchHelper::AdvancedClassList();
1582    
1583  Return a list of advanced class names. This list is used to generate the directory  Return a list of advanced class names. This list is used to generate the directory
1584  of available searches on the search page.  of available searches on the search page.
# Line 1724  Line 1601 
1601    
1602  =head3 SelectionTree  =head3 SelectionTree
1603    
1604  C<< my $htmlText = SearchHelper::SelectionTree($cgi, \%tree, %options); >>      my $htmlText = SearchHelper::SelectionTree($cgi, \%tree, %options);
1605    
1606  Display a selection tree.  Display a selection tree.
1607    
# Line 1833  Line 1710 
1710  =item nodeImageClosed  =item nodeImageClosed
1711    
1712  URL of the image to display next to the tree nodes when they are collapsed. Clicking  URL of the image to display next to the tree nodes when they are collapsed. Clicking
1713  on the image will expand a section of the tree. The default is C<../FIG/Html/plus.gif>.  on the image will expand a section of the tree. The default is C<plus.gif>.
1714    
1715  =item nodeImageOpen  =item nodeImageOpen
1716    
1717  URL of the image to display next to the tree nodes when they are expanded. Clicking  URL of the image to display next to the tree nodes when they are expanded. Clicking
1718  on the image will collapse a section of the tree. The default is C<../FIG/Html/minus.gif>.  on the image will collapse a section of the tree. The default is C<minus.gif>.
1719    
1720  =item style  =item style
1721    
# Line 1878  Line 1755 
1755      my ($cgi, $tree, %options) = @_;      my ($cgi, $tree, %options) = @_;
1756      # Get the options.      # Get the options.
1757      my $optionThing = Tracer::GetOptions({ name => 'selection',      my $optionThing = Tracer::GetOptions({ name => 'selection',
1758                                             nodeImageClosed => '../FIG/Html/plus.gif',                                             nodeImageClosed => "$FIG_Config::cgi_url/Html/plus.gif",
1759                                             nodeImageOpen => '../FIG/Html/minus.gif',                                             nodeImageOpen => "$FIG_Config::cgi_url/Html/minus.gif",
1760                                             style => 'tree',                                             style => 'tree',
1761                                             target => '_self',                                             target => '_self',
1762                                             selected => undef},                                             selected => undef},
# Line 1898  Line 1775 
1775              Confess("Hash reference found at start of selection tree. The tree as a whole cannot have attributes, only tree nodes.");              Confess("Hash reference found at start of selection tree. The tree as a whole cannot have attributes, only tree nodes.");
1776          } else {          } else {
1777              # Here we have a real tree. Apply the tree style.              # Here we have a real tree. Apply the tree style.
1778              push @retVal, $cgi->start_div({ class => $optionThing->{style} });              push @retVal, CGI::start_div({ class => $optionThing->{style} });
1779              # Give us a DIV ID.              # Give us a DIV ID.
1780              my $divID = GetDivID($optionThing->{name});              my $divID = GetDivID($optionThing->{name});
1781              # Show the tree.              # Show the tree.
1782              push @retVal, ShowBranch($cgi, "(root)", $divID, $tree, $optionThing, 'block');              push @retVal, ShowBranch($cgi, "(root)", $divID, $tree, $optionThing, 'block');
1783              # Close the DIV block.              # Close the DIV block.
1784              push @retVal, $cgi->end_div();              push @retVal, CGI::end_div();
1785          }          }
1786      }      }
1787      # Return the result.      # Return the result.
# Line 1913  Line 1790 
1790    
1791  =head3 ShowBranch  =head3 ShowBranch
1792    
1793  C<< my @htmlLines = SearchHelper::ShowBranch($cgi, $label, $id, $branch, $options, $displayType); >>      my @htmlLines = SearchHelper::ShowBranch($cgi, $label, $id, $branch, $options, $displayType);
1794    
1795  This is a recursive method that displays a branch of the tree.  This is a recursive method that displays a branch of the tree.
1796    
# Line 1962  Line 1839 
1839      # Declare the return variable.      # Declare the return variable.
1840      my @retVal = ();      my @retVal = ();
1841      # Start the branch.      # Start the branch.
1842      push @retVal, $cgi->start_ul({ id => $id, style => "display:$displayType" });      push @retVal, CGI::start_ul({ id => $id, style => "display:$displayType" });
1843      # Check for the hash and choose the start location accordingly.      # Check for the hash and choose the start location accordingly.
1844      my $i0 = (ref $branch->[0] eq 'HASH' ? 1 : 0);      my $i0 = (ref $branch->[0] eq 'HASH' ? 1 : 0);
1845      # Get the list length.      # Get the list length.
# Line 2008  Line 1885 
1885                      # If we have children, create the child list with a recursive call.                      # If we have children, create the child list with a recursive call.
1886                      if ($hasChildren) {                      if ($hasChildren) {
1887                          Trace("Processing children of $myLabel.") if T(4);                          Trace("Processing children of $myLabel.") if T(4);
1888                          push @childHtml, ShowBranch($cgi, $myLabel, $myID, $myContent, $options, 'none');                          push @childHtml, ShowBranch($cgi, $myLabel, $myID, $myContent, $options, 'block');
1889                          Trace("Children of $myLabel finished.") if T(4);                          Trace("Children of $myLabel finished.") if T(4);
1890                      }                      }
1891                  }                  }
# Line 2020  Line 1897 
1897              # closed images.              # closed images.
1898              my @images = ($options->{nodeImageOpen}, $options->{nodeImageClosed});              my @images = ($options->{nodeImageOpen}, $options->{nodeImageClosed});
1899              my $image = $images[$hasChildren];              my $image = $images[$hasChildren];
1900              my $prefixHtml = $cgi->img({src => $image, id => "${myID}img"});              my $prefixHtml = CGI::img({src => $image, id => "${myID}img"});
1901              if ($hasChildren) {              if ($hasChildren) {
1902                  # If there are children, we wrap the image in a toggle hyperlink.                  # If there are children, we wrap the image in a toggle hyperlink.
1903                  $prefixHtml = $cgi->a({ onClick => "javascript:treeToggle('$myID','$images[0]', '$images[1]')" },                  $prefixHtml = CGI::a({ onClick => "javascript:treeToggle('$myID','$images[0]', '$images[1]')" },
1904                                        $prefixHtml);                                        $prefixHtml);
1905              }              }
1906              # Now the radio button, if any. Note we use "defined" in case the user wants the              # Now the radio button, if any. Note we use "defined" in case the user wants the
# Line 2040  Line 1917 
1917                  if (defined $options->{selected} && $options->{selected} eq $attrHash->{value}) {                  if (defined $options->{selected} && $options->{selected} eq $attrHash->{value}) {
1918                      $radioParms->{checked} = undef;                      $radioParms->{checked} = undef;
1919                  }                  }
1920                  $prefixHtml .= $cgi->input($radioParms);                  $prefixHtml .= CGI::input($radioParms);
1921              }              }
1922              # Next, we format the label.              # Next, we format the label.
1923              my $labelHtml = $myLabel;              my $labelHtml = $myLabel;
1924              Trace("Formatting tree node for \"$myLabel\".") if T(4);              Trace("Formatting tree node for \"$myLabel\".") if T(4);
1925              # Apply a hyperlink if necessary.              # Apply a hyperlink if necessary.
1926              if (defined $attrHash->{link}) {              if (defined $attrHash->{link}) {
1927                  $labelHtml = $cgi->a({ href => $attrHash->{link}, target => $options->{target} },                  $labelHtml = CGI::a({ href => $attrHash->{link}, target => $options->{target} },
1928                                       $labelHtml);                                       $labelHtml);
1929              }              }
1930              # Finally, roll up the child HTML. If there are no children, we'll get a null string              # Finally, roll up the child HTML. If there are no children, we'll get a null string
1931              # here.              # here.
1932              my $childHtml = join("\n", @childHtml);              my $childHtml = join("\n", @childHtml);
1933              # Now we have all the pieces, so we can put them together.              # Now we have all the pieces, so we can put them together.
1934              push @retVal, $cgi->li("$prefixHtml$labelHtml$childHtml");              push @retVal, CGI::li("$prefixHtml$labelHtml$childHtml");
1935          }          }
1936      }      }
1937      # Close the tree branch.      # Close the tree branch.
1938      push @retVal, $cgi->end_ul();      push @retVal, CGI::end_ul();
1939      # Return the result.      # Return the result.
1940      return @retVal;      return @retVal;
1941  }  }
1942    
1943  =head3 GetDivID  =head3 GetDivID
1944    
1945  C<< my $idString = SearchHelper::GetDivID($name); >>      my $idString = SearchHelper::GetDivID($name);
1946    
1947  Return a new HTML ID string.  Return a new HTML ID string.
1948    
# Line 2096  Line 1973 
1973    
1974  =head3 PrintLine  =head3 PrintLine
1975    
1976  C<< $shelp->PrintLine($message); >>      $shelp->PrintLine($message);
1977    
1978  Print a line of CGI output. This is used during the operation of the B<Find> method while  Print a line of CGI output. This is used during the operation of the B<Find> method while
1979  searching, so the user sees progress in real-time.  searching, so the user sees progress in real-time.
# Line 2114  Line 1991 
1991  sub PrintLine {  sub PrintLine {
1992      # Get the parameters.      # Get the parameters.
1993      my ($self, $message) = @_;      my ($self, $message) = @_;
1994      # Send them to the output.      # Send the message to the output.
1995      print "$message\n";      print "$message\n";
1996  }  }
1997    
1998  =head3 GetHelper  =head3 GetHelper
1999    
2000  C<< my $shelp = SearchHelper::GetHelper($parm, $type => $className); >>      my $shelp = SearchHelper::GetHelper($parm, $type => $className);
2001    
2002  Return a helper object with the given class name. If no such class exists, an  Return a helper object with the given class name. If no such class exists, an
2003  error will be thrown.  error will be thrown.
# Line 2166  Line 2043 
2043          # Commit suicide if it didn't work.          # Commit suicide if it didn't work.
2044          if (! defined $retVal) {          if (! defined $retVal) {
2045              die "Could not find a $type handler of type $className.";              die "Could not find a $type handler of type $className.";
2046            } else {
2047                # Perform any necessary subclass initialization.
2048                $retVal->Initialize();
2049          }          }
2050      };      };
2051      # Check for errors.      # Check for errors.
# Line 2178  Line 2058 
2058    
2059  =head3 SaveOrganismData  =head3 SaveOrganismData
2060    
2061  C<< my ($name, $displayGroup, $domain) = $shelp->SaveOrganismData($group, $genomeID, $genus, $species, $strain, $taxonomy); >>      my ($name, $displayGroup, $domain) = $shelp->SaveOrganismData($group, $genomeID, $genus, $species, $strain, $taxonomy);
2062    
2063  Format the name of an organism and the display version of its group name. The incoming  Format the name of an organism and the display version of its group name. The incoming
2064  data should be the relevant fields from the B<Genome> record in the database. The  data should be the relevant fields from the B<Genome> record in the database. The
# Line 2252  Line 2132 
2132    
2133  =head3 ValidateKeywords  =head3 ValidateKeywords
2134    
2135  C<< my $okFlag = $shelp->ValidateKeywords($keywordString, $required); >>      my $okFlag = $shelp->ValidateKeywords($keywordString, $required);
2136    
2137  Insure that a keyword string is reasonably valid. If it is invalid, a message will be  Insure that a keyword string is reasonably valid. If it is invalid, a message will be
2138  set.  set.
# Line 2302  Line 2182 
2182    
2183  =head3 TuningParameters  =head3 TuningParameters
2184    
2185  C<< my $options = $shelp->TuningParameters(%parmHash); >>      my $options = $shelp->TuningParameters(%parmHash);
2186    
2187  Retrieve tuning parameters from the CGI query object. The parameter is a hash that maps parameter names  Retrieve tuning parameters from the CGI query object. The parameter is a hash that maps parameter names
2188  to their default values. The parameters and their values will be returned as a hash reference.  to their default values. The parameters and their values will be returned as a hash reference.
# Line 2345  Line 2225 
2225    
2226  =head3 GetPreferredAliasType  =head3 GetPreferredAliasType
2227    
2228  C<< my $type = $shelp->GetPreferredAliasType(); >>      my $type = $shelp->GetPreferredAliasType();
2229    
2230  Return the preferred alias type for the current session. This information is stored  Return the preferred alias type for the current session. This information is stored
2231  in the C<AliasType> parameter of the CGI query object, and the default is C<FIG>  in the C<AliasType> parameter of the CGI query object, and the default is C<FIG>
# Line 2363  Line 2243 
2243      return $retVal;      return $retVal;
2244  }  }
2245    
2246    =head3 Hint
2247    
2248        my $htmlText = SearchHelper::Hint($wikiPage, $hintText);
2249    
2250    Return the HTML for a small question mark that displays the specified hint text when it is clicked.
2251    This HTML can be put in forms to provide a useful hinting mechanism.
2252    
2253    =over 4
2254    
2255    =item wikiPage
2256    
2257    Name of the wiki page to be popped up when the hint mark is clicked.
2258    
2259    =item hintText
2260    
2261    Text to display for the hint. It is raw html, but may not contain any double quotes.
2262    
2263    =item RETURN
2264    
2265    Returns the html for the hint facility. The resulting html shows a small button-like thing that
2266    uses the standard FIG popup technology.
2267    
2268    =back
2269    
2270    =cut
2271    
2272    sub Hint {
2273        # Get the parameters.
2274        my ($wikiPage, $hintText) = @_;
2275        # Ask Sprout to draw the hint button for us.
2276        return Sprout::Hint($wikiPage, $hintText);
2277    }
2278    
2279    
2280    
2281  =head2 Virtual Methods  =head2 Virtual Methods
2282    
2283    =head3 HeaderHtml
2284    
2285        my $html = $shelp->HeaderHtml();
2286    
2287    Generate HTML for the HTML header. If extra styles or javascript are required,
2288    they should go in here.
2289    
2290    =cut
2291    
2292    sub HeaderHtml {
2293        return "";
2294    }
2295    
2296  =head3 Form  =head3 Form
2297    
2298  C<< my $html = $shelp->Form(); >>      my $html = $shelp->Form($mode);
2299    
2300  Generate the HTML for a form to request a new search.  Generate the HTML for a form to request a new search. If the subclass does not
2301    override this method, then the search is formless, and must be started from an
2302    external page.
2303    
2304    =cut
2305    
2306    sub Form {
2307        # Get the parameters.
2308        my ($self) = @_;
2309        return "";
2310    }
2311    
2312  =head3 Find  =head3 Find
2313    
2314  C<< my $resultCount = $shelp->Find(); >>      my $resultCount = $shelp->Find();
2315    
2316  Conduct a search based on the current CGI query parameters. The search results will  Conduct a search based on the current CGI query parameters. The search results will
2317  be written to the session cache file and the number of results will be  be written to the session cache file and the number of results will be
# Line 2391  Line 2329 
2329    
2330  =head3 Description  =head3 Description
2331    
2332  C<< my $htmlText = $shelp->Description(); >>      my $htmlText = $shelp->Description();
2333    
2334  Return a description of this search. The description is used for the table of contents  Return a description of this search. The description is used for the table of contents
2335  on the main search tools page. It may contain HTML, but it should be character-level,  on the main search tools page. It may contain HTML, but it should be character-level,
# Line 2408  Line 2346 
2346    
2347  =head3 SearchTitle  =head3 SearchTitle
2348    
2349  C<< my $titleHtml = $shelp->SearchTitle(); >>      my $titleHtml = $shelp->SearchTitle();
2350    
2351  Return the display title for this search. The display title appears above the search results.  Return the display title for this search. The display title appears above the search results.
2352  If no result is returned, no title will be displayed. The result should be an html string  If no result is returned, no title will be displayed. The result should be an html string
# Line 2427  Line 2365 
2365    
2366  =head3 DefaultColumns  =head3 DefaultColumns
2367    
2368  C<< $shelp->DefaultColumns($rhelp); >>      $shelp->DefaultColumns($rhelp);
2369    
2370  Store the default columns in the result helper. The default action is just to ask  Store the default columns in the result helper. The default action is just to ask
2371  the result helper for its default columns, but this may be changed by overriding  the result helper for its default columns, but this may be changed by overriding
# Line 2452  Line 2390 
2390      $rhelp->SetColumns(@cols);      $rhelp->SetColumns(@cols);
2391  }  }
2392    
 =head3 Hint  
2393    
2394  C<< my $htmlText = SearchHelper::Hint($wikiPage, $hintText); >>  =head3 Initialize
2395    
2396  Return the HTML for a small question mark that displays the specified hint text when it is clicked.      $shelp->Initialize();
 This HTML can be put in forms to provide a useful hinting mechanism.  
2397    
2398  =over 4  Perform any initialization required after construction of the helper.
2399    
2400  =item wikiPage  =cut
2401    
2402    sub Initialize {
2403        # The default is to do nothing.
2404    }
2405    
2406  Name of the wiki page to be popped up when the hint maek is clicked.  =head3 GetResultHelper
2407    
2408  =item hintText      my $rhelp = $shelp->GetResultHelper($className);
2409    
2410  Text to display for the hint. It is raw html, but may not contain any double quotes.  Return a result helper for this search helper. The default action is to create
2411    a result helper from scratch; however, if the subclass has an internal result
2412    helper it can override this method to return it without having to create a new
2413    one.
2414    
2415    =over 4
2416    
2417    =item className
2418    
2419    Result helper class name.
2420    
2421  =item RETURN  =item RETURN
2422    
2423  Returns the html for the hint facility. The resulting html shows a small button-like thing that  Returns a result helper of the specified class connected to this search helper.
 uses the standard FIG popup technology.  
2424    
2425  =back  =back
2426    
2427  =cut  =cut
2428    
2429  sub Hint {  sub GetResultHelper {
2430      # Get the parameters.      # Get the parameters.
2431      my ($wikiPage, $hintText) = @_;      my ($self, $className) = @_;
2432      # Escape the single quotes in the hint text.      # Create the helper.
2433      my $quotedText = $hintText;      my $retVal = GetHelper($self, RH => $className);
2434      $quotedText =~ s/'/\\'/g;      # return it.
     # Convert the wiki page name to a URL.  
     my $wikiURL = ucfirst $wikiPage;  
     $wikiURL =~ s/ /_/g;  
     $wikiURL = "../wiki/index.php/$wikiURL";  
     # Create the html.  
     my $retVal = "&nbsp;<input type=\"button\" class=\"hintbutton\" onMouseOver=\"javascript:if (!this.tooltip) { " .  
                  "this.tooltip = new Popup_Tooltip(this, 'Search Hint', '$quotedText', '', 1); this.tooltip.addHandler(); } " .  
                  "return false;\" value=\"?\" onClick=\"javascript:window.open('$wikiURL', 'nmpdrHelp');\" />";  
     # Return it.  
2435      return $retVal;      return $retVal;
2436  }  }
2437    
   
2438  1;  1;

Legend:
Removed from v.1.37  
changed lines
  Added in v.1.44

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3