FilterField
The FilterField
component is a text-based input component that allows users to
enter filters using an intuitive and easily understandable syntax. Since the
input is text-based, users can always enter anything they want. To provide
guidance to the user, we recommend always using the FilterField
in combination
with suggestions.
Import
import { FilterField } from '@dynatrace/strato-components-preview/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. Add a type to the
valuePredicate
of keys listed in the validatorMap
property. 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.
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. 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, 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
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
.
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
Values starting with $
are returned as type Variable
in the value node. The
validatorMap
validates variables according to variableType
. You can also 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 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.
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. |
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", caseSensitive: false) |
!= | not matchesValue(key, "value", caseSensitive: false) |
< | < |
<= | <= |
> | > |
>= | >= |
= * | isNotNull() |
!= * | isNull() |
AND | and |
OR | or |
in | in() |
not in | not in() |
*value | matchesValue(key, "*value", caseSensitive: false) |
value* | matchesValue(key, "value*", caseSensitive: false) |
*value* | matchesValue(key, "*value*", caseSensitive: false) |
~ | matchesPhrase() |
!~ | not matchesPhrase() |