FilterField
FilterField is an advanced, text-based filtering component. It supports
complex data filtering with intuitive filter field syntax and auto-suggestions.
Import
import { FilterField } from '@dynatrace/strato-components/filters';
Demo
FilterField uses a simple and intuitive
filter field syntax.
When the user begins to type, a dropdown with suggestions for the next key,
value, or operator appears. See Usage for best practices to
implement the component.
Validate user input
To validate user input, set restrictions for keys, comparison operators, and
values using the validatorMap property. FilterField will highlight errors
and show appropriate suggestions in the suggestions overlay as long as the
autoSuggestions property of the FilterField is set to true.
Define valid keys
You can define a list of keys in the validatorMap property to be interpreted
as valid. For any keys that aren't in the list, FilterField will show an
error. By setting the exhaustive property of validatorMap to false, users
can enter any key without triggering an error.
Define key types
You can set one or multiple types for FilterField keys and thus restrict the
list of comparison operators and values that will be accepted. Set the
valueType property on a FilterFieldKeySuggestionConfig in the
keyPredicates array. The type must be set for each key individually. The type
can't be set for all keys globally.
To overwrite the type restriction of a comparison operator, set the allowed comparison operators for that key.
Available types and their comparison operators are:
| Type | Comparison operators |
|---|---|
Any | equals, not-equals, less-than, less-or-equal, greater-than, greater-or-equal, in, not in, exists, not-exists |
Boolean | equals, not-equals, exists, not-exists |
Duration | equals, not-equals, less-than, less-or-equal, greater-than, greater-or-equal, in, not in, exists, not-exists |
Number | equals, not-equals, less-than, less-or-equal, greater-than, greater-or-equal, in, not in, exists, not-exists |
String | equals, not-equals, in, not in, exists, not-exists, starts-with, not-starts-with, ends-with, not-ends-with, contains, not-contains |
Define values for keys
For any key in the validatorMap property, you can define a list of values that
are valid by passing an array to the valuePredicate. FilterField will return
an error for any value that isn't on the list.
If, in addition to a list of values, you pass a key type as a valuePredicate,
FilterField will accept any value that is in the list and of that key type.
Additional and custom types
In addition to the built-in types (Number, String, Boolean, Duration,
JSONPath, IPAddress, UID, Timestamp, SmartscapeId), you can register
custom types using the customTypes prop. Custom types let you define
domain-specific validation logic and can be referenced in the validatorMap
just like built-in types by using { type: 'CustomTypeName' } in the
valuePredicate.
Each custom type requires a validation function that returns true when a value
is valid for that type. Optionally, you can provide an icon to display in the
suggestions overlay.
Suggestion Ordering
By default, key and value suggestions from the validatorMap are sorted
alphabetically for string values, numerically in ascending order for numbers,
and by unit order (smallest to largest, e.g. ns, ms, s, m, h) then
numerically within the same unit for durations. When the user types, suggestions
are reordered by match relevance: exact matches appear first, followed by
starts-with, and then contains or ends-with matches. Within each relevance tier,
alphabetical or ascending order is preserved.
To preserve the original order defined in keyPredicates and valuePredicate,
set sortSuggestions: false on the validatorMap. Relevance-based sorting when
the user is typing remains active regardless of this setting.
Suggest full statements when typing values
Complete filter statements (key, operator, value) can be suggested automatically
based on typed input. This allows users to type a value like error and
immediately see suggestions like status = error without needing to know the
key name first.
To enable this feature, add suggestStatementOnValueMatch to the key predicate
in your validatorMap. The property accepts either:
true— Enables statement suggestions for all values defined in thevaluePredicatearray (suggestions are displayed for exact matches, starts-with, ends-with, and contains matches)- A function — A custom match function that receives the current token and
returns
trueif a statement suggestion should be shown
Statement suggestions always use the = (equals) comparison operator. If
multiple keys have the same value configured, suggestions for all matching keys
will be shown.
Define fallback keys for free-text search
The fallbackKey property allows you to define commonly used keys that generate
suggestions using the currently typed token as the value. This is useful when
you want users to search within specific fields without knowing the exact key
name.
To enable this feature, add fallbackKey to the key predicate in your
validatorMap. The property accepts either:
true— Generates statement suggestions using thematches-phrase(~) operator- An array of comparison operators — Generates one statement suggestion for each specified operator
When a user starts typing in an empty FilterField, suggestions like
content ~ typed-value are shown, allowing quick searches in common fields.
The difference to suggestStatementOnValueMatch is that fallbackKey uses the
currently typed token as the value regardless of whether it matches predefined
values, while suggestStatementOnValueMatch only suggests statements when the
typed value matches values defined in the valuePredicate.
Add display labels and descriptions to suggestions
You can enrich key and value suggestions from the validatorMap with a
displayValue (a human-readable label shown instead of the raw value) and
details (a secondary description). Both are optional and only affect the
suggestion overlay — they have no effect on validation or the applied filter
value.
For keys — add displayValue and details directly to the
FilterFieldKeySuggestionConfig object in keyPredicates.
For values — replace string, number, boolean, or duration entries in
valuePredicate with a FilterFieldRichValuePredicate object. Set value to
the actual filter value that gets applied. displayValue and details are
optional.
Group key suggestions
Key suggestions from the validatorMap can be organized into labeled groups
using FilterFieldKeySuggestionGroupConfig objects in the keyPredicates
array.
The keyPredicates property accepts an array of key names (strings),
FilterFieldKeySuggestionConfig objects, or
FilterFieldKeySuggestionGroupConfig objects. The array format is required to
use key suggestion groups.
Group value suggestions
Value suggestions for a key can be organized into labeled groups by replacing
string or number entries in valuePredicate with
FilterFieldValueSuggestionGroupConfig objects.
Specify validation logic
To validate a value according to a particular logic, pass a validator function
to the valuePredicate. This allows you to write a custom error message in case
of an error. You can also use this approach to check whether a value follows a
particular pattern.
Make sure to pass only pure or cached functions and avoid calling
convertStringToFilterFieldTree in combination with a validatorMap inside of
the validator function, as this may cause infinite loops.
Define comparison operators
The validatorMap property lets you define a list of comparison operators
globally (for all keys) or individually (per key). For any comparison operator
that isn't defined in the list, FilterField will show an error.
If you define comparison operators globally, be aware that the key types may also narrow down the list of allowed comparison operators. If you define comparison operators specifically for a key, they will overwrite restrictions set by the type of the key.
Work with syntax tree
FilterField provides a tokenized version of the entered value and groups
statements that are connected by the same logical operator. As the logical AND
takes precedence over the logical OR, the statements a = 1 b = 2 OR c = 3
will be grouped as follows:
Each statement is represented by a node holding the key, operator, and value of
the statement, provided as properties of the statement node. Depending on the
type of value and operator used, additional information (e.g. starts-with,
contains) is provided in the syntax tree.
If there is an error in the syntax, a node with type Error is included in the
syntax tree and the accompanying isValid flag is set to false.
Explicit logical operator nodes
Explicit logical operators are included in the syntax tree so it can be
converted back into a string without losing information. The logical operator
needed to evaluate a group of statements is included on the Group node. Ignore
logical operators in the children array of groups.
Convert string to syntax tree
Use the convertStringToFilterFieldTree utility to convert a string into a
FilterTree. Setting the value programmatically doesn't trigger the onChange
callback. Use the provided utility function for the converted syntax tree and
filter data.
Convert syntax tree to string
Use the convertFilterFieldTreeToString utility to convert a syntax tree to a
string.
We can't guarantee that converting a string to a tree and back yields the exact
same result. The value of every node (except for Error nodes) doesn't
contain escape characters (both wrapping doublequotes and backslashes). Hence,
the simple value foo may be written "foo", \f\o\o, or using any other
combination of escape characters. With the textValue of tree nodes being
optional for the conversion util input, it is impossible to re-build the exact
same string as the original input for certain trees unless the textValue is
included.
This example demonstrates the conversion from string to tree, and back:
Customize comparison operator suggestions
With the autoSuggestions prop set to true, relevant operator suggestions are
added automatically. To customize the suggestions, omit autoSuggestions and
use the returned autoSuggestions in the onSuggest callback. The onSuggest
callback provides the information you need to determine which suggestions to
show.
Escape characters in suggestions
FilterField uses space as a delimiter between keys, comparison operators,
values, and statements. Learn the
filter field syntax.
To avoid invalid syntax when suggestions are applied, use the value prop and
the children of the FilterField.Suggestion component. The value is used to
apply the suggestion, while the children are used to render the suggestion in
the overlay.
In general, the following characters need to be escaped, either by wrapping the
whole value in double quotes, or by using a \ to escape single characters:
-
- Asterisk
- , Comma
- () Parentheses
- ! Exclamation
- < > Angles
- = Equals
- " Quote
- $ Dollar sign
- : Colon
- [] Brackets
- ~ Tilde
When the insertion strategy for suggestions is set to replace-token, the
applied value is automatically escaped, if needed.
The following examples are also valid for keys:
- Exact match of comparison operator
foo = \=foo = \<foo = ">"foo = "!="
- Starts with / ends with operator in value
foo = *"ba*r"(ends withba*r)foo = ba\*r*(starts withba*r)foo = *"ba*r"*(containsba*r)
- Space in value
foo = "b a r"foo = b\ ar
Programmatically escape suggestion values
The escapeFilterFieldSuggestion utility allows you to escape suggestion
values. This is the same function applied internally by the FilterField,
making it ideal for verifying that manually escaped values match the expected
format.
Group suggestions
If there are many suggestions that fit into different categories, you can use
FilterField.SuggestionGroup to separate them visually. Use the
FilterField.SuggestionGroupLabel to add short labels above the groups.
Load suggestions async
To load suggestions async and display a loading state in the suggestions
overlay, set the loading prop on FilterField.Suggestions.
Limit suggestions shown
To limit the number of default suggestions rendered, provide the
defaultSuggestionsCount config. You can set limits for an empty and a filled
FilterField.
If the suggestions exceed the limit, a show more / less button will be rendered to expand / collapse the remaining suggestions.
Persist recent and pinned filters
To enhance user experience and streamline workflows, FilterField supports
persisting recent and pinned filters across sessions. This feature stores
user-defined filters in the Dynatrace platform's userAppState, allowing users
to quickly reapply commonly used filters.
To enable this feature, set the filterNamespace prop on the FilterField
component. This string value acts as a unique identifier for the storage scope.
Filters are persisted per user and namespace, ensuring isolation between
different use cases or components under the keys
strato-FilterField-pinnedFilters-{filterNameSpace} and
strato-FilterField-recentFilters-{filterNameSpace}.
If your application uses namespaced recent and pinned filters that are no longer relevant or supported, it is your responsibility to explicitly clean them up in the application code. The system does not automatically remove unused namespaces from the userAppState.
Use the FilterField in a form
The user can submit a filter statement using Enter or Ctrl / Cmd + Enter.
This triggers the onFilter callback, which provides the string representation
of the value, the syntax tree, and its validity state. Clearing the
FilterField also triggers the onFilter callback.
FilterField can be displayed in a form. By default, the form shows a set of
error messages based on the entered value, rendered as tooltips. Use the
FormField to make the error state visible and add an error message beneath the
FilterField. Learn about using the FormField
here.
To provide the same functionality for pointer users, add a dedicated button next
to the FilterField, as outlined in Usage.
Variables
Variables are a default feature of every FilterField. Any value starting with
$ is automatically interpreted as a variable and returned as type Variable
in the value node.
Use the validatorMap to allow only specific variables or variable patterns.
Enable matches phrase (~)
To enable matches phrase comparison operators (~ and !~), provide a
validatorMap with matches-phrase or not-matches-phrase in the list of
allowed operators. You can enable comparison operators globally, for all keys at
once, or for individual keys. Matches phrase comparison operators are compatible
with keys of the type Any and String, or any type that you list as an
allowed comparison operator for a key.
For details on mapping matches-phrase and not-matches-phrase to a DQL
command, and when to use different comparison operators, see the documentation
on translation to DQL.
Enable search (* ~)
To enable the search operator (* ~), set searchConversion: true in the
parserConfig prop. While the matches phrase comparison operator is used to
search in a specific field, the search operator is used to look for matches in
the whole record.
For details on mapping search to a DQL command, and when to use different
comparison operators, see the documentation on
translation to DQL.
Enable JSONPath filtering
JSONPath filtering lets users target nested JSON data using JSONPath
expressions. To enable JSONPath filtering, set jsonPathConversion: true in the
parserConfig prop and add { type: 'JSONPath' } to the valuePredicate array
in your validator map. You can combine JSONPath with other types, such as
{type: Number} or specific values, for flexible filtering. When combined, the
filter key appears twice in the suggestions: once with $. notation for
JSONPath, and once without for the expected type.
Change insertion strategy
FilterField uses
filter field syntax
to parse the user's input and transform it into tokens. Each token represents a
filter key, value, comparison operator, or logical operator.
By default, applying a suggestion replaces the token that the cursor is
currently positioned on with the value of the suggestion. Use the
insertionStrategy prop to alter the behavior.
The following replacement strategies are supported:
| Strategy | Behavior |
|---|---|
replace-token (default) | Replace the token at the cursor position. |
replace-statement | Replace the whole statement at the cursor position. |
replace-all | Replace the whole filter. |
insert | Insert at the cursor position without any replacements. |
React to pasted content
To react to pasted content, implement an onSuggest callback and check whether
pastedContent is included in the provided suggestion types. When it is, you
can offer suggestions based on the pasted content, optionally using insertion
strategies like replace-statement or replace-all to turn the raw pasted
content into a full statement.
Map FilterField syntax to DQL
To ensure predictable and consistent behavior for end users, map FilterField syntax to Dynatrace Query Language (DQL) using these equivalents:
| FilterField syntax | DQL equivalent |
|---|---|
= | matchesValue(key, "value") |
!= | not matchesValue(key, "value") |
< | < |
<= | <= |
> | > |
>= | >= |
= * | isNotNull() |
!= * | isNull() |
AND | and |
OR | or |
in | matchesValue(key, array("value1", "value2")) |
not in | not matchesValue(key, array("value1", "value2")) |
*value | matchesValue(key, "*value") |
value* | matchesValue(key, "value*") |
*value* | matchesValue(key, "*value*") |
~ | matchesPhrase(key, "*value*") |
!~ | not matchesPhrase(key, "*value*") |
* ~ | search "value" |