source/web/extras/components/dashlets/audit-application.js
/**
       * This is the searchbox filter function.
       * The complete results will be filtered out according to the query before being returned for display.
       *
       * @method applyRegexFilterOnResponse
       * @param  {object} req    the request
       * @param  {object} res    the response
       */
This is the searchbox filter function.
The complete results will be filtered out according to the query before being returned for display.

@method applyRegexFilterOnResponse
@param  {object} req    the request
@param  {object} res    the response
This is the searchbox filter function . The complete results will be filtered out according to the query before being returned for display . @method applyRegexFilterOnResponse @param { object } req the request @param { object } res the response
function AuditApplication_applyRegexFilterOnResponse(req,res)
      {
         var output = {};
         var input    = res.results || [];
         var filtered = [];
         var i,l=input.length;
         function indexOfWrapper(array,string_to_match)
         {
            if (array.indexOf)
               return array.indexOf(string_to_match);
            else
            {
               for(var index=0 ; index < array.length ; index++)
               {
                  if (array[index] === string_to_match)
                  return index;
               }
               return -1;
            }
         }
         if (req)
         {
            var querystring=req.replace("&searchWithinResults=","");
            var negation_predicate_present=false;
            var firstchar=querystring.substr(0,1);
            if (firstchar == "+" || firstchar == "-")
            {
               querystring = querystring.substr(1);
               if (firstchar == "-")
                  negation_predicate_present=true;
            }
            var splittedQueryElements = querystring.split(":");
            var isColonSeparated=splittedQueryElements.length > 1;
            var field=isColonSeparated ? splittedQueryElements.shift() : "values";
            var to_match = isColonSeparated ? splittedQueryElements.join(":") : querystring;
            var to_match = to_match.replace(":",":\\s*");
            var re_to_match;
            try
            {
               re_to_match = new RegExp(to_match,"mi");
               output.regexStatus="valid";
            }
            catch(e)
            {
               switch the search background to valid.no need for hasClass, YUI dom already does this internally
               output.regexStatus="invalid";
               output.filtered=filtered
               return output;
            }
            for (i = 0 ; i < l; ++i)
            {
               special case : match date instances to the current display format (see formatter for time column)
               if (input[i][field] instanceof Date)
                  input[i][field] = YAHOO.util.Date.format(input[i][field], { format: "%e/%m/%y %H:%M"} );
                just in case, trim existing markers coming from the data and replace with a space, although unlikely
                as the markers have been specifically chosen to be non-character codepoints
               var field_value = (input[i][field]+"").trimHighlightMarkers(" ");
               var remainder = field_value; start with the whole string. trim off as we go along matches
               var at_least_one_match = false;
               var previous_remaining_match;
               var matching_strings = [];
               var deferred_matching_strings = [];
                use unassignable/non-characters unicode codepoints as markers. see unicode.org/charts/PDF/uFFF0.pdf
                they won't need to be escaped throughout the string
               var highlight_open_marker ='\uFFFE';
               var highlight_close_marker ='\uFFFF';
               while(remaining_match=re_to_match.exec(remainder))  null if no match
               {
                  at_least_one_match=true;
                   matching strings is used to keep track of what strings we have already highlighted in the
                   current row. indexOf needs Javascript 1.6, so use a wrapper to ensure support
                  var alreadyHighlighted = (indexOfWrapper(matching_strings,remaining_match[0]) != -1);
                  if (   (re_to_match.exec(remainder) && !negation_predicate_present )
                    ||   (!re_to_match.exec(remainder) && negation_predicate_present ) )
                   simulated XOR, equivalent to above.
                   no match regex will be a null
                   negated each element is necesary to force non-booleans (e.g null) into a boolean
                   note : formatting here should be kept to the minimum, as this is the data that will be searched upon by the local filter box
                      see the columDef's formatter above for displaying other data than the data actually contained by this array element
                  if ( (!remaining_match != !negation_predicate_present) && !alreadyHighlighted)
                  {
                      replace() replaces the first occurrence, so only use remaining_match[0].
                      if there are other matches, they will be dealt with as we move along the string
                     var remaining_match_regex = remaining_match[0].sanitizeforHighlighting();
                     if (remaining_match[0])
                     {
                         rematch against the remainder to determine the match count at the current position
                        var remainder_matches=remainder.match(new RegExp(remaining_match_regex,"g"));
                        if (remainder_matches)
                        {
                           if (remainder_matches.length > 1)
                           {
                              defer the regex replace until the last match for this particular remaining_match_regex.
                               the idea is to avoid replacing bits that will be replaced by an encompassing match later
                               in the string. don't defer the same match twice.
                              if (indexOfWrapper(deferred_matching_strings,remaining_match[0]) == -1)
                              deferred_matching_strings.push(remaining_match[0]);
                           }
                           else
                           {
                               the match is the furthest along on the string. do a global replace
                               to replace this match and any other previous matches that may have been skipped/deferred
                              field_value=field_value.replace(new RegExp(remaining_match_regex,"g"),highlight_open_marker+remaining_match[0]+highlight_close_marker);
                              matching_strings.push(remaining_match[0]);
                           }
                        }
                     }
                  }
                  trim to keep the rest of the string after the current match index
                   break out of the loop if there is no remainder, or the remainder has not changed
                   likely $ or ^ only, respectively, in that case
                   also make sure we've gone through the entire input string, even if this current portion does not match
                  var new_remainder=remainder.substr(remaining_match[0].length ==0 ? 1 : remaining_match.index + remaining_match[0].length);
                  if (!new_remainder || remainder == new_remainder)
                     break;
                  else
                     remainder = new_remainder;
                   for the next iteration
                  previous_remaining_match=remaining_match;
               }
                all this additional highlighting work is unnecessary if we're looking for negated matches,
                as there will be no highlighting for those
               if (!negation_predicate_present)
               {
                   We've moved across the whole string. Go back and replace what we've deferred, if any
                  for(var deferred_index = 0; deferred_index < deferred_matching_strings.length; deferred_index++)
                  {
                     if (indexOfWrapper(matching_strings,deferred_matching_strings[deferred_index]) == -1)
                     {
                        var deferred_regex = new RegExp(deferred_matching_strings[deferred_index].sanitizeforHighlighting(),"g")
                        field_value=field_value.replace(deferred_regex,highlight_open_marker+deferred_matching_strings[deferred_index]+highlight_close_marker);
                     }
                  }
                   eliminate potential useless successive close open and open close markers
                  field_value= field_value.replace(new RegExp(highlight_close_marker+highlight_open_marker,"g"),"")
                                          .replace(new RegExp(highlight_open_marker+highlight_close_marker,"g"),"");
                   marker block elision : eliminate nested markers, that are already enclosed in a larger mark block
                   replace the field value with the elided version
                  input[i][field]=field_value.elideHighlightMarkers(highlight_open_marker, highlight_close_marker);
               }
                finally, push or not the result to the filtered array
               if (!at_least_one_match != !negation_predicate_present)  simulated XOR
                  filtered.push(input[i]);   add it to the list of "visible" results
            }
            output.filtered = filtered;
         }
         else
         {
            we're back to an empty filter. remove the invalid-regex styling, if present
            output.regexStatus="empty";
            output.filtered=input;
         }
         return output;
      }
function AuditApplication_applyRegexFilterOnResponse ( req , res ) { var output = { } ; var input = res . results || [ ] ; var filtered = [ ] ; var i , l = input . length ; function indexOfWrapper ( array , string_to_match ) { if ( array . indexOf ) return array . indexOf ( string_to_match ) ; else { for ( var index = 0 ; index < array . length ; index ++ ) { if ( array [ index ] === string_to_match ) return index ; } return - 1 ; } } if ( req ) { var querystring = req . replace ( "&searchWithinResults=" , "" ) ; var negation_predicate_present = false ; var firstchar = querystring . substr ( 0 , 1 ) ; if ( firstchar == "+" || firstchar == "-" ) { querystring = querystring . substr ( 1 ) ; if ( firstchar == "-" ) negation_predicate_present = true ; } var splittedQueryElements = querystring . split ( ":" ) ; var isColonSeparated = splittedQueryElements . length > 1 ; var field = isColonSeparated ? splittedQueryElements . shift ( ) : "values" ; var to_match = isColonSeparated ? splittedQueryElements . join ( ":" ) : querystring ; var to_match = to_match . replace ( ":" , ":\\s*" ) ; var re_to_match ; try { re_to_match = new RegExp ( to_match , "mi" ) ; output . regexStatus = "valid" ; } catch ( e ) { output . regexStatus = "invalid" ; output . filtered = filtered return output ; } for ( i = 0 ; i < l ; ++ i ) { if ( input [ i ] [ field ] instanceof Date ) input [ i ] [ field ] = YAHOO . util . Date . format ( input [ i ] [ field ] , { format : "%e/%m/%y %H:%M" } ) ; var field_value = ( input [ i ] [ field ] + "" ) . trimHighlightMarkers ( " " ) ; var remainder = field_value ; var at_least_one_match = false ; var previous_remaining_match ; var matching_strings = [ ] ; var deferred_matching_strings = [ ] ; var highlight_open_marker = '\uFFFE' ; var highlight_close_marker = '\uFFFF' ; while ( remaining_match = re_to_match . exec ( remainder ) ) { at_least_one_match = true ; var alreadyHighlighted = ( indexOfWrapper ( matching_strings , remaining_match [ 0 ] ) != - 1 ) ; if ( ( ! remaining_match != ! negation_predicate_present ) && ! alreadyHighlighted ) { var remaining_match_regex = remaining_match [ 0 ] . sanitizeforHighlighting ( ) ; if ( remaining_match [ 0 ] ) { var remainder_matches = remainder . match ( new RegExp ( remaining_match_regex , "g" ) ) ; if ( remainder_matches ) { if ( remainder_matches . length > 1 ) { if ( indexOfWrapper ( deferred_matching_strings , remaining_match [ 0 ] ) == - 1 ) deferred_matching_strings . push ( remaining_match [ 0 ] ) ; } else { field_value = field_value . replace ( new RegExp ( remaining_match_regex , "g" ) , highlight_open_marker + remaining_match [ 0 ] + highlight_close_marker ) ; matching_strings . push ( remaining_match [ 0 ] ) ; } } } } var new_remainder = remainder . substr ( remaining_match [ 0 ] . length == 0 ? 1 : remaining_match . index + remaining_match [ 0 ] . length ) ; if ( ! new_remainder || remainder == new_remainder ) break ; else remainder = new_remainder ; previous_remaining_match = remaining_match ; } if ( ! negation_predicate_present ) { for ( var deferred_index = 0 ; deferred_index < deferred_matching_strings . length ; deferred_index ++ ) { if ( indexOfWrapper ( matching_strings , deferred_matching_strings [ deferred_index ] ) == - 1 ) { var deferred_regex = new RegExp ( deferred_matching_strings [ deferred_index ] . sanitizeforHighlighting ( ) , "g" ) field_value = field_value . replace ( deferred_regex , highlight_open_marker + deferred_matching_strings [ deferred_index ] + highlight_close_marker ) ; } } field_value = field_value . replace ( new RegExp ( highlight_close_marker + highlight_open_marker , "g" ) , "" ) . replace ( new RegExp ( highlight_open_marker + highlight_close_marker , "g" ) , "" ) ; input [ i ] [ field ] = field_value . elideHighlightMarkers ( highlight_open_marker , highlight_close_marker ) ; } if ( ! at_least_one_match != ! negation_predicate_present ) filtered . push ( input [ i ] ) ; } output . filtered = filtered ; } else { output . regexStatus = "empty" ; output . filtered = input ; } return output ; }
This is the searchbox filter function.
This is the searchbox filter function .
// Array.indexOf requires Javascript 1.6. not all supported browsers support this at present, so wrap it. // or do it the old-fashioned way //remove inserted searchWithinResults query param // inclusion is the default, if is start with a + strip it. // no real need to escape since user can use the field to "really" search for a +, eg: field:+ // search style : id:614. if a ":" is present in the query, assume the first part is the field to search on // if none specified, search is performed on the values field // if colon separated get first item and remove it from the array // there is sometimes some spurious spaces just after the field definitions. trim them. // regex flags : //    m : multiline. match ^ and $ against the beginning and end of each line //    i : case insensitive. Remove the i here to make the search box case-sensitive //    Note : the 'g' global flag is not needed here. The while 'exec' loop below will take care of the potential multiple matches. // //switch the search background to valid.no need for hasClass, YUI dom already does this internally //special case : match date instances to the current display format (see formatter for time column) // just in case, trim existing markers coming from the data and replace with a space, although unlikely // as the markers have been specifically chosen to be non-character codepoints //start with the whole string. trim off as we go along matches // use unassignable/non-characters unicode codepoints as markers. see unicode.org/charts/PDF/uFFF0.pdf // they won't need to be escaped throughout the string // null if no match // matching strings is used to keep track of what strings we have already highlighted in the // current row. indexOf needs Javascript 1.6, so use a wrapper to ensure support //if (   (re_to_match.exec(remainder) && !negation_predicate_present ) //  ||   (!re_to_match.exec(remainder) && negation_predicate_present ) ) // simulated XOR, equivalent to above. // no match regex will be a null // negated each element is necesary to force non-booleans (e.g null) into a boolean // note : formatting here should be kept to the minimum, as this is the data that will be searched upon by the local filter box //    see the columDef's formatter above for displaying other data than the data actually contained by this array element // replace() replaces the first occurrence, so only use remaining_match[0]. // if there are other matches, they will be dealt with as we move along the string // rematch against the remainder to determine the match count at the current position //defer the regex replace until the last match for this particular remaining_match_regex. // the idea is to avoid replacing bits that will be replaced by an encompassing match later // in the string. don't defer the same match twice. // the match is the furthest along on the string. do a global replace // to replace this match and any other previous matches that may have been skipped/deferred //trim to keep the rest of the string after the current match index // break out of the loop if there is no remainder, or the remainder has not changed // likely $ or ^ only, respectively, in that case // also make sure we've gone through the entire input string, even if this current portion does not match // for the next iteration // all this additional highlighting work is unnecessary if we're looking for negated matches, // as there will be no highlighting for those // We've moved across the whole string. Go back and replace what we've deferred, if any // eliminate potential useless successive close open and open close markers // marker block elision : eliminate nested markers, that are already enclosed in a larger mark block // replace the field value with the elided version // finally, push or not the result to the filtered array // simulated XOR // add it to the list of "visible" results //we're back to an empty filter. remove the invalid-regex styling, if present