# Dynamic Filter

# Dynamic Filter Definition

A dynamic filter (Dynamic Filter) is a predefined set of filter conditions for a type of object, stored in a DynamicFilter object. The legacy frontend displayed it as a filter tab above the list page, and users could click it to quickly filter data.

Status in the current version

  • The current frontend does not call the filter API, so list pages do not display any dynamic filters, and there is no "Save as filter" entry. Existing filters (including the system preset filters of the ๆถˆๆฏไธญๅฟƒ, such as ๆœช่ฏป / ่ทŸ่ธช / ้‡่ฆ) currently have no effect.
  • The menu System Config > Forms > Filters currently stays in the loading state after it is opened: the DynamicFilter object has no read/write permission requirements configured, so the object data API (/domain/DynamicFilter) returns a permission error for every user (including administrators). To maintain filters, import them via CSV.
  • If you only want a list to carry filter conditions by default, use listForm.searchConditions in the form extInfo, see Default Filter Conditions; it uses the same condition format as this page.

Filter properties are as follows:

Property Description
Name (name) Required, unique within the tenant, cannot be modified after creation
Label (label) Display name in the UI
Icon (icon) Icon displayed before the name
Display sequence (displaySequence) Smaller values come first
Description (description) Help information displayed when hovering over the name
Object type (objectType) The object type the filter applies to
Is default (isDefault) Whether this is the default filter (applied automatically by the legacy frontend when entering the list page)
Is system (isSystem) true for system preset filters; can only be set via CSV
Owner (owner) Owner of a user-defined filter; not editable in the UI
Conditions (conditions) Filter conditions in JSON format

Use the following header row for CSV import (consistent with the system preset seed data):

name(*),label,displaySequence,conditions,objectType.shortName,isDefault,description,icon,isSystem

UnreadMessageFilter,ๆœช่ฏป,1,"{""isUnRead"": {""value"": true, ""columnKey"": ""isUnRead"", ""matchMode"": ""=""}}",Message,false,ๆœช่ฏปๆถˆๆฏๅˆ—่กจ,InboxOutlined,true
1
2
3

The filter conditions are a piece of JSON describing the matching rules, in the following format:

// Description of the dynamic filter conditions below:
// 1. The status field equals SUCCESS
// 2. type is one of FINDER, UPDATE
{
  // key is the column name: status
  "status": {
    // The target column to filter
    "columnKey": "status",
    // Match rule: equals
    "matchMode": "=",
    // Target value to match: SUCCESS
    "value": "SUCCESS"
  },
  "type": { // key is the column name: type
    // The target column to filter, same as the key in the previous line
    "columnKey": "type",
    // Match rule of the filter: isOneOf (is one of the values)
    "matchMode": "isOneOf",
    // Target values of the filter: [FINDER, UPDATE]
    "value": ["FINDER", "UPDATE"]
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

The key of each condition is generally the same as columnKey; multiple conditions are combined with "AND". Match modes, rules and so on are described in detail below.

# Available Match Modes

The available match modes are listed below. If a value not in the table is passed, the backend reports the error Unsupported match mode. startsWith, endsWith, contains and notContains are case-insensitive; all other modes are case-sensitive.

Match mode Description Applicable data types
= Equal to All types except one-to-many and many-to-many associations
!= Not equal to All types except one-to-many and many-to-many associations
> Greater than Number, date
< Less than Number, date
>= Greater than or equal to Number, date
<= Less than or equal to Number, date
after After ..., same as > Date
before Before ..., same as < Date
afterOrEqual Equal to or after ..., same as >= Date
beforeOrEqual Equal to or before ..., same as <= Date
isOneOf, containsAny Is one of the values in the list All types except one-to-many and many-to-many associations
isNotAnyOf, notContainsAny Is not any of the values in the list All types except one-to-many and many-to-many associations
startsWith Starts with ... Text
endsWith Ends with ... Text
contains Contains ... Text
notContains Does not contain ... Text
isEmpty Is empty (matches only NULL, not empty strings) All types except one-to-many and many-to-many associations
isNotEmpty Is not empty (not NULL; an empty string also counts as not empty) All types except one-to-many and many-to-many associations

TIP

The legacy hasRelated and hasNoRelated are no longer supported since 1.0.

# Matching by Field Type

# Matching Associations

columnKey supports referencing fields of associated objects with dot notation, for example customer.name matches by the name of the associated customer; multiple levels of references are allowed.

# Matching Enum Fields

Enum fields are matched by the name defined in the Enum. For example, for the Enum definition below, use the three values ONLY_LABEL_FIELD, EXCLUDE_ARRAY_COLUMNS and ALL_COLUMNS for matching:

enum FetchType {
  ONLY_LABEL_FIELD("Fetch label field"),
  EXCLUDE_ARRAY_COLUMNS("Fetch columns not of type array"),
  ALL_COLUMNS("Fetch all columns");
}
1
2
3
4
5

# Matching Other Field Types

  • For boolean fields, use true and false without quotes as the match value
  • For numeric types, use the number without quotes as the match value
  • If the match value must be an array, wrap the match values in []
  • Date-time match values use the same format as the time placeholders below after substitution: yyyy-MM-dd HH:mm:ss (for example 2021-08-23 07:57:49)

# Dynamic Match Conditions

The following placeholders can be used in filter conditions; they are replaced with actual values before being returned to the frontend. The same placeholders can also be used in the extInfo of forms and form fields (${currentUserGroups} in form field extInfo is replaced with an empty list []).

Placeholder Replaced with
${currentHour} The current hour, at zero minutes and zero seconds
${currentDay} Midnight of the current date
${currentWeek} Midnight on Monday of the current week
${currentMonth} Midnight on the first day of the current month
${currentQuarter} Midnight on the first day of the current quarter
${currentYear} Midnight on January 1 of the current year
${currentUserGroups} List of role names the current user has, in the format ['ROLE_USER','ROLE_ADMIN']
${currentUsername} Username of the currently logged-in user, see the note below
${currentUserId} id of the currently logged-in user, see the note below

WARNING

  • The current version does not pass the current user's information when replacing placeholders, so ${currentUsername} and ${currentUserId} are replaced with empty strings; filtering by the current user is not possible for now.
  • The legacy ${currentOrganization} has been removed since 1.0 (the platform only has tenants, not organizations).

TIP

${currentUserGroups} is a list. During substitution it is replaced, together with the surrounding quotes, by an array such as ['ROLE_USER','ROLE_ADMIN'], so it must be used with list match modes such as isOneOf, and it must be written in JSON with quotes as "${currentUserGroups}". The example below assumes the object has a text field visibleRole that stores a role name, and only displays records whose field value is one of the roles the current user has:

{
  "visibleRole": {
    "value": "${currentUserGroups}",
    "columnKey": "visibleRole",
    "matchMode": "isOneOf"
  }
}
1
2
3
4
5
6
7
Last Updated: 9/24/2026, 2:27:35 PM