Sample Page - Record Highlighting - Highlighting Records with Common Properties - Search Results

This sample demonstrates record-level highlighting where you need to examine all of the records visible on a page in order to determine the highlight effect. Typically this is used when you want to highlight records that have something in common.

To get the effect shown here you need to reimplement reimplement both the hookHighlighting_PrepareForRecordset and hookHighlighting_GetForRecord hooks.

The hookHighlighting_PrepareForRecordset hook is called once for the page, and is passed the primary keys of all the records on the page (i.e. their record IDs) plus a map containing all the field values for those records. Your code can then analyse the records to determine the highlights you want to add, and then store the results of this analysis - i.e. your highlighting 'state information' for all the records in a temporary map (also supplied as an argument). This map is then in turn passed to each subsequent call to hookHighlighting_GetForRecord, where your custom code retrieves the particular highlight needed for each record, and applies it.

This mechanism can be used to apply any of the highlighting visual effects.

In this example, it is used to highlight those animals that share the same birth year, using unique background colours.

Note the legend that appears beneath the main page content.

To see how the same code can highlight a pedigree page, click here.

Show/Hide Sample Code

# Hook function to prepare highlighting for a record set.
# This is called in a report that has highlighting support
# AFTER the records have been fetched from the db but BEFORE
# any output has occurred.
#
# This is the opportunity for any highlighting method that needs to
# 'see' all the records in order to determine highlighting.
# Ie highlighting that depends on the data of more than one record.
# E.g. is you wanted to apply a separate background
# colour to all animals that have a given attribute in common. 
# E.g. all animals of the same colour, etc.
#
# Arg 1 - table suffix
# Arg 2 - reference to map holding decoded highlight definition
# Arg 3 - context
# Arg 4 - reference to map of field values
# Arg 5 - reference to array holding ordered keys of the record set
# Arg 6 - field name prefix
# Arg 7 - reference to map into which highlighting state can be stored
# OPTIONAL
# Arg 8 - reference to map for future additional arguments; possibly undefined
sub hookHighlighting_PrepareForRecordset {
   my ($strTableSuffix, $rmHighlightingDef, $strContext, $rmFieldValues,
       $raKeys, $strFldPrefix, $rmState, $rmArgsEx) = @_;

   # You probably dont want to interfere with the correct working of
   # pedserve's internally defined highlighting methods.
   # So what you should do is make your highlighting definition
   # identifiable - by including terms that you can test
   # for here. Then you can defer to the default implementation when
   # necessary.
   
   my $fUseStdImpl = 1;

   # Trivial example that checks for the term 'myhighlighting=yes'
   # in the highlighting definition, and if present handles it here.
   # To use this, you would have to define a highlighting during the
   # script startup with a call to &pdsSetHighlightingDef() e.g. 
   #   &pdsSetHighlightingDef('A_myhighlighting', 
   #            'label=Highlight DOB;myhighlighting=yes;');
   # Note also the check against $strTableSuffix to ensure this is
   # only used with animal records, and the check that this is not
   # a pedserve-private definition:
   if (!defined($$rmHighlightingDef{'pdsprivate'}) &&
       $strTableSuffix eq 'A' && 
       defined($$rmHighlightingDef{'myhighlighting'}) &&
       $$rmHighlightingDef{'myhighlighting'} eq 'yes') {
      # Dont defer to standard implementation below:
      $fUseStdImpl = 0;

      # This example is going to apply a unique background colour 
      # to all animals that share the same year of birth.
      # You could use the same method e.g. to a colour field to 
      # highlight all animals with the same coat colour.
      my %mBirthYearOccurrences = ();
      for (my $i = 0; $i < scalar(@$raKeys); $i++) {
         my $nPrimaryKey = $$raKeys[$i];
         # Extract the date of birth field value from the
         # field results map:
         my $date = $$rmFieldValues{$nPrimaryKey.':'.$strFldPrefix.'A_DOB'};
         # Skip if there is none:
         next if !defined($date) || $date eq '';
         # Extract the year part:
         my $strBirthYear = substr($date, 0, 4);
         # Increment a count of the no. of times we have seen
         # this birth year:
         $mBirthYearOccurrences{$strBirthYear}++;
      }

      # Now we create a unique background style for each birth
      # year that's been seen twice or more in the data:
      my $nNextStyle = 0;
      foreach my $strBirthYear (keys(%mBirthYearOccurrences)) {
         next if $mBirthYearOccurrences{$strBirthYear} <= 1;
         # Create a unique background CSS style, and store it
         # in the supplied state info map, keyed by the birth year:
         $$rmState{$strBirthYear} = &pdsGetUniqueBackgroundInlineStyle($nNextStyle++);
      }

      # Thats all we do here. Now turn to the related code in
      # &hookHighlighting_GetForRecord(), which is where the
      # unique backgrounds we have created get used.
   }

   # If the above code has not handled this highlighting definition itself,
   # defer to the standard implementation:
   if ($fUseStdImpl) {
      &pdsHookStdImpl_Highlighting_PrepareForRecordset($strTableSuffix, 
           $rmHighlightingDef, $strContext, $rmFieldValues, 
           $raKeys, $strFldPrefix, $rmState, $rmArgsEx);
   }
}

# Hook function to apply highlighting for a record - storing
# the required highlighting decorations in a supplied map.
#
# Arg 1 - table suffix
# Arg 2 - reference to map holding decoded highlight definition
# Arg 3 - context
# Arg 4 - reference to map into which highlight effects are to be stored
# Arg 5 - reference to map of field values
# Arg 6 - primary key
# Arg 7 - field name prefix
# Arg 8 - reference to map into which highlighting state can be
#         stored for the current panel
# OPTIONAL
# Arg 9 - reference to map for future additional arguments; possibly undefined
sub hookHighlighting_GetForRecord {
   my ($strTableSuffix, $rmHighlightingDef, $strContext, $rmEffects,
       $rmFieldValues, $nPrimaryKey, $strFldPrefix, $rmState, $rmArgsEx) = @_;
   
   # You probably dont want to interfere with the correct working of
   # pedserve's internally defined highlighting methods.
   # So what you should do is make your highlighting definition
   # identifiable - by including terms that you can test
   # for here. Then you can defer to the default implementation when
   # necessary.
   
   my $fUseStdImpl = 1;

   # Example that checks for the term 'myhighlighting=yes' in
   # the highlighting definition, and if present handles it here.
   # To use this, you would have to define a highlighting during
   # the script startup with a call to &pdsSetHighlightingDef() e.g. 
   #   &pdsSetHighlightingDef('A_myhighlighting',
   #      'label=Highlight DOB;myhighlighting=yes;');
   # Note also the check against $strTableSuffix to ensure this is
   # only used with animal records, and the check that this is
   # not a pedserve-private definition:
   if (!defined($$rmHighlightingDef{'pdsprivate'}) &&
       $strTableSuffix eq 'A' && 
       defined($$rmHighlightingDef{'myhighlighting'}) &&
       $$rmHighlightingDef{'myhighlighting'} eq 'yes') {
      # Dont defer to standard implementation below:
      $fUseStdImpl = 0;

      # This demonstrates record-level highlighting by giving
      # a separate background colour to animals that share the same
      # birth year.

      # Extract the date of birth field value from the
      # field results map:
      my $date = $$rmFieldValues{$nPrimaryKey.':'.$strFldPrefix.'A_DOB'};
      if (defined($date) && $date ne '') {
         # This animal has its DOB set.
         # Extract the year part:
         my $strYear = substr($date, 0, 4);
        
         # Get any stored inline background colour
         # for this birth year:
         my $strInlineStyle = $$rmState{$strYear};

         # Store it in the effects map if we have one:
         if (defined($strInlineStyle) && $strInlineStyle ne '') {
             $$rmEffects{'inlinestyle_css'} = $strInlineStyle;
             # Set up an entry for the highlighting legend:
             $$rmEffects{'inlinestyle_legend'} =
               $::g_q->escapeHTML("Born in $strYear");
         }
      }
   }

   # If the above code has not handled this highlighting definition itself,
   # defer to the standard implementation:
   if ($fUseStdImpl) {
      &pdsHookStdImpl_Highlighting_GetForRecord(
         $strTableSuffix, $rmHighlightingDef, $strContext, $rmEffects,
         $rmFieldValues, $nPrimaryKey, $strFldPrefix, $rmState, $rmArgsEx);
   }
}

This custom highlighting method uses the date of birth field ('A_DOB'). When Pedserve fetches data from the database, it does not automatically fetch all the fields - it only fetches those it needs. For this reason, when your custom highlighting method is selected, you need to take steps to ensure that Pedserve will pull any fields you need. You do this by reimplementing the hookHighlighting_GetExtraFlds hook:

Show/Hide Sample Code

# Hook function to return extra fields that are required by a given
# highlighting method.
#
# Arg 1 - table suffix
# Arg 2 - reference to map holding decoded highlight definition
# Arg 3 - context
# Arg 4 - field name prefix
# OPTIONAL
# Arg 4 - reference to map for future additional arguments; possibly undefined
sub hookHighlighting_GetExtraFlds {
   my ($strTableSuffix, $rmHighlightingDef, 
       $strContext, $strFldPrefix, $rmArgsEx) = @_;
   
   # You probably dont want to interfere with the correct working
   # of pedserve's internally defined highlighting methods.
   # So what you should do is make your highlighting definition
   # identifiable - by including terms that you can test
   # for here. Then you can defer to the default implementation
   # when necessary.
   
   my $fUseStdImpl = 1;
   my $strReturn = '';

   # Trivial example that checks for the term 'myhighlighting=yes'
   # in the highlighting definition, and if present returns a specific
   # field name. To use this, you would have to define a highlighting
   # method during the script startup with a call to
   # &pdsSetHighlightingDef() e.g. 
   #   &pdsSetHighlightingDef('A_myhighlighting',
   #                    'label=Highlight DOB;myhighlighting=yes;');
   # Note also the check against $strTableSuffix to ensure this is only
   # used with animal records, and
   # the check that this is not a pedserve-private definition:
   if (!defined($$rmHighlightingDef{'pdsprivate'}) &&
       $strTableSuffix eq 'A' && 
       defined($$rmHighlightingDef{'myhighlighting'}) &&
       $$rmHighlightingDef{'myhighlighting'} eq 'yes') {
      # Dont defer to standard implementation below:
      $fUseStdImpl = 0;

      # Set the fields to return:
      # (this example will use the date of birth field to apply specific
      # highlights for given dates etc)
      $strReturn = $strFldPrefix.'A_DOB';
   }

   # If the above code has not handled this highlighting definition itself,
   # defer to the standard implementation:
   if ($fUseStdImpl) {
      $strReturn = &pdsHookStdImpl_Highlighting_GetExtraFlds($strTableSuffix,
                    $rmHighlightingDef, $strContext, $strFldPrefix, $rmArgsEx);
   }
   
   return $strReturn;
}
Record Highlighting - Highlighting Records with Common Properties - Search Results

This screen shot was taken from the Standfast Golden Retriever Database