@ea-lab/reactive-json-docs 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/public/rjbuild/docs/core/attributeTransformer/setAttributeValue.md +107 -14
- package/public/rjbuild/docs/core/attributeTransformer/setAttributeValue.yaml +124 -12
- package/public/rjbuild/docs/core/example/DataFilter-example-direct-array.md +211 -0
- package/public/rjbuild/docs/core/example/DataFilter-example-direct-array.yaml +323 -0
- package/public/rjbuild/docs/core/example/bulk-actions.yaml +2 -2
- package/public/rjbuild/docs/core/example/button-wrapper-pattern.md +99 -0
- package/public/rjbuild/docs/core/example/button-wrapper-pattern.yaml +132 -0
- package/public/rjbuild/docs/core/example/conditional-field-with-dual-update.md +209 -0
- package/public/rjbuild/docs/core/example/conditional-field-with-dual-update.yaml +74 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ea-lab/reactive-json-docs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Complete documentation for Reactive-JSON - Components, examples and LLM-parsable guides",
|
|
5
5
|
"main": "public/rjbuild/docs/index.yaml",
|
|
6
6
|
"files": [
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"private": false,
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@craco/craco": "^7.1.0",
|
|
29
|
-
"@ea-lab/reactive-json": "^1.
|
|
29
|
+
"@ea-lab/reactive-json": "^1.3.0",
|
|
30
30
|
"@ea-lab/reactive-json-chartjs": "^1.0.0",
|
|
31
31
|
"@npmcli/fs": "^4.0.0",
|
|
32
32
|
"@reduxjs/toolkit": "^2.6.1",
|
|
@@ -8,42 +8,73 @@ Dynamically sets or modifies the value of an HTML attribute before rendering. Th
|
|
|
8
8
|
|
|
9
9
|
```yaml
|
|
10
10
|
attributeTransforms:
|
|
11
|
-
# Add CSS class
|
|
11
|
+
# Add CSS class (string mode)
|
|
12
12
|
- what: setAttributeValue
|
|
13
13
|
name: "class"
|
|
14
14
|
value: "active"
|
|
15
15
|
|
|
16
|
-
# Replace attribute value
|
|
16
|
+
# Replace attribute value (string mode)
|
|
17
17
|
- what: setAttributeValue
|
|
18
18
|
name: "data-status"
|
|
19
19
|
mode: "replace"
|
|
20
20
|
value: ~.currentStatus
|
|
21
|
+
|
|
22
|
+
# Merge style object (object mode)
|
|
23
|
+
- what: setAttributeValue
|
|
24
|
+
name: "style"
|
|
25
|
+
value:
|
|
26
|
+
borderColor: "#3b82f6"
|
|
27
|
+
backgroundColor: "#ffffff"
|
|
21
28
|
```
|
|
22
29
|
|
|
23
30
|
## Properties
|
|
24
31
|
|
|
25
32
|
- **name** *(string, required)*: The name of the attribute to modify.
|
|
26
33
|
- **mode** *(string, optional)*: The modification mode. Default: `"append"`.
|
|
27
|
-
- `"append"`: Adds the value to the existing attribute value (space-separated).
|
|
34
|
+
- `"append"`: Adds the value to the existing attribute value (space-separated for strings, merges properties for objects).
|
|
28
35
|
- `"replace"`: Completely replaces the existing attribute value.
|
|
29
|
-
- **value** *(string, required)*: The value to set or append. Supports template evaluation (e.g., `~.dynamicValue`, `~~.globalValue`).
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
36
|
+
- **value** *(string | object, required)*: The value to set or append. Supports template evaluation (e.g., `~.dynamicValue`, `~~.globalValue`).
|
|
37
|
+
- **String mode**: When `value` is a string, operates in string mode for simple attributes like `class`, `data-*`, etc.
|
|
38
|
+
- **Object mode**: When `value` is an object, operates in object mode for complex attributes like `style`. In append mode, merges properties property by property.
|
|
39
|
+
- **preventDuplicateValues** *(boolean, optional)*: When `true` (default), prevents duplicate values when using append mode (applies to string mode and string properties in object mode).
|
|
40
|
+
- **separator** *(string, optional)*: The separator used between values in string mode. Default: `" "` (space).
|
|
32
41
|
|
|
33
42
|
## Behavior
|
|
34
43
|
|
|
44
|
+
The transformer operates in two distinct modes based on the `value` type:
|
|
45
|
+
|
|
46
|
+
### String Mode (when `value` is a string)
|
|
47
|
+
|
|
35
48
|
- **Append mode**: Adds the new value to the existing attribute, separated by the specified separator.
|
|
36
49
|
- **Replace mode**: Completely overwrites the existing attribute value.
|
|
37
50
|
- **Duplicate prevention**: In append mode, prevents adding duplicate values when enabled.
|
|
38
51
|
|
|
52
|
+
### Object Mode (when `value` is an object)
|
|
53
|
+
|
|
54
|
+
- **Replace mode**: Completely replaces the entire object attribute.
|
|
55
|
+
- **Append mode**: Merges properties property by property:
|
|
56
|
+
- Starts from the current object attribute
|
|
57
|
+
- For each property in `value`, applies the same logic as string mode:
|
|
58
|
+
- If both current and new values are strings: appends them (respecting `preventDuplicateValues`)
|
|
59
|
+
- Otherwise: replaces the property with the new value (new value has precedence)
|
|
60
|
+
- Handles nested objects recursively
|
|
61
|
+
- Works on a copy to avoid mutation issues
|
|
62
|
+
|
|
63
|
+
### Undefined Values
|
|
64
|
+
|
|
65
|
+
- **Append mode**: `undefined` values are ignored, keeping the current attribute unchanged.
|
|
66
|
+
- **Replace mode**: `undefined` is assigned to the attribute.
|
|
67
|
+
|
|
39
68
|
## Common Use Cases
|
|
40
69
|
|
|
41
|
-
- **Dynamic CSS classes**: Adding/removing CSS classes based on state.
|
|
42
|
-
- **Data attributes**: Setting data-* attributes for JavaScript integration.
|
|
43
|
-
- **ARIA attributes**: Dynamically updating accessibility attributes.
|
|
44
|
-
- **Style attributes**: Modifying inline styles conditionally.
|
|
70
|
+
- **Dynamic CSS classes**: Adding/removing CSS classes based on state (string mode).
|
|
71
|
+
- **Data attributes**: Setting data-* attributes for JavaScript integration (string mode).
|
|
72
|
+
- **ARIA attributes**: Dynamically updating accessibility attributes (string mode).
|
|
73
|
+
- **Style attributes**: Modifying inline styles conditionally (object mode). Merge style properties without losing existing ones.
|
|
74
|
+
|
|
75
|
+
## Examples
|
|
45
76
|
|
|
46
|
-
|
|
77
|
+
### String Mode Example
|
|
47
78
|
|
|
48
79
|
```yaml
|
|
49
80
|
renderView:
|
|
@@ -91,11 +122,73 @@ data:
|
|
|
91
122
|
input_data: ""
|
|
92
123
|
```
|
|
93
124
|
|
|
125
|
+
### Object Mode Example (Style Merging)
|
|
126
|
+
|
|
127
|
+
```yaml
|
|
128
|
+
renderView:
|
|
129
|
+
- type: div
|
|
130
|
+
attributes:
|
|
131
|
+
style:
|
|
132
|
+
padding: "10px"
|
|
133
|
+
border: "2px solid #007bff"
|
|
134
|
+
borderRadius: "4px"
|
|
135
|
+
attributeTransforms:
|
|
136
|
+
# Merge additional style properties without losing existing ones
|
|
137
|
+
- what: setAttributeValue
|
|
138
|
+
name: "style"
|
|
139
|
+
value:
|
|
140
|
+
borderColor: "#3b82f6"
|
|
141
|
+
backgroundColor: "#f0f0f0"
|
|
142
|
+
when: ~.isHighlighted
|
|
143
|
+
is: true
|
|
144
|
+
# Result when isHighlighted is true:
|
|
145
|
+
# style: {
|
|
146
|
+
# padding: "10px",
|
|
147
|
+
# border: "2px solid #007bff",
|
|
148
|
+
# borderRadius: "4px",
|
|
149
|
+
# borderColor: "#3b82f6",
|
|
150
|
+
# backgroundColor: "#f0f0f0"
|
|
151
|
+
# }
|
|
152
|
+
|
|
153
|
+
data:
|
|
154
|
+
isHighlighted: false
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Object Mode Replace Example
|
|
158
|
+
|
|
159
|
+
```yaml
|
|
160
|
+
renderView:
|
|
161
|
+
- type: div
|
|
162
|
+
attributes:
|
|
163
|
+
style:
|
|
164
|
+
padding: "10px"
|
|
165
|
+
border: "2px solid #007bff"
|
|
166
|
+
attributeTransforms:
|
|
167
|
+
# Completely replace the style object
|
|
168
|
+
- what: setAttributeValue
|
|
169
|
+
name: "style"
|
|
170
|
+
mode: "replace"
|
|
171
|
+
value:
|
|
172
|
+
backgroundColor: "#ffffff"
|
|
173
|
+
color: "#000000"
|
|
174
|
+
# Result:
|
|
175
|
+
# style: {
|
|
176
|
+
# backgroundColor: "#ffffff",
|
|
177
|
+
# color: "#000000"
|
|
178
|
+
# }
|
|
179
|
+
# (original padding and border are lost)
|
|
180
|
+
```
|
|
181
|
+
|
|
94
182
|
## Notes
|
|
95
183
|
|
|
96
184
|
- **Pre-render execution**: This transformer modifies attributes before the component renders, ensuring child components receive the transformed attributes.
|
|
97
|
-
- **
|
|
98
|
-
- **
|
|
99
|
-
- **
|
|
185
|
+
- **Mode detection**: The transformer automatically detects whether to use string mode or object mode based on the `value` type after template evaluation.
|
|
186
|
+
- **Append mode behavior**:
|
|
187
|
+
- **String mode**: Respects existing attribute values, adding new values separated by the specified separator.
|
|
188
|
+
- **Object mode**: Merges properties property by property, applying string append logic where both values are strings, otherwise replacing with the new value.
|
|
189
|
+
- **Replace mode**: Use when you need complete control over the attribute value. In object mode, completely replaces the entire object.
|
|
190
|
+
- **Duplicate prevention**: Only applies to append mode, and works for string values in both string mode and object mode.
|
|
191
|
+
- **Object merging**: In object mode append, nested objects are merged recursively. Properties that don't match the expected format for append are replaced (new value has precedence).
|
|
100
192
|
- **Template evaluation**: The value property supports full template evaluation including `~.localData`, `~~.globalData`, `~>nearestKey`, and `~~>globalKey` patterns.
|
|
101
193
|
- **Conditional execution**: Supports the same condition system as actions (`when`, `is`, `isEmpty`, `isNotEmpty`, etc.).
|
|
194
|
+
- **Undefined handling**: `undefined` values are ignored in append mode but assigned in replace mode.
|
|
@@ -12,16 +12,23 @@ renderView:
|
|
|
12
12
|
- type: TabbedSerializer
|
|
13
13
|
yamlSerializedContent: |
|
|
14
14
|
attributeTransforms:
|
|
15
|
-
# Add CSS class
|
|
15
|
+
# Add CSS class (string mode)
|
|
16
16
|
- what: setAttributeValue
|
|
17
17
|
name: "class"
|
|
18
18
|
value: "active"
|
|
19
19
|
|
|
20
|
-
# Replace attribute value
|
|
20
|
+
# Replace attribute value (string mode)
|
|
21
21
|
- what: setAttributeValue
|
|
22
22
|
name: "data-status"
|
|
23
23
|
mode: "replace"
|
|
24
24
|
value: ~.currentStatus
|
|
25
|
+
|
|
26
|
+
# Merge style object (object mode)
|
|
27
|
+
- what: setAttributeValue
|
|
28
|
+
name: "style"
|
|
29
|
+
value:
|
|
30
|
+
borderColor: "#3b82f6"
|
|
31
|
+
backgroundColor: "#ffffff"
|
|
25
32
|
|
|
26
33
|
- type: Markdown
|
|
27
34
|
content: |
|
|
@@ -44,8 +51,14 @@ renderView:
|
|
|
44
51
|
- `"replace"`: Completely replaces the existing attribute value
|
|
45
52
|
- term:
|
|
46
53
|
code: value
|
|
47
|
-
after: "(string, required)"
|
|
48
|
-
details:
|
|
54
|
+
after: "(string | object, required)"
|
|
55
|
+
details:
|
|
56
|
+
type: Markdown
|
|
57
|
+
content: |
|
|
58
|
+
The value to set or append. Supports template evaluation (e.g., `~.dynamicValue`, `~~.globalValue`).
|
|
59
|
+
|
|
60
|
+
- **String mode**: When `value` is a string, operates in string mode for simple attributes like `class`, `data-*`, etc.
|
|
61
|
+
- **Object mode**: When `value` is an object, operates in object mode for complex attributes like `style`. In append mode, merges properties property by property.
|
|
49
62
|
- term:
|
|
50
63
|
code: preventDuplicateValues
|
|
51
64
|
after: "(boolean, optional)"
|
|
@@ -65,16 +78,36 @@ renderView:
|
|
|
65
78
|
|
|
66
79
|
## Behavior
|
|
67
80
|
|
|
81
|
+
The transformer operates in two distinct modes based on the `value` type:
|
|
82
|
+
|
|
83
|
+
### String Mode (when `value` is a string)
|
|
84
|
+
|
|
68
85
|
- **Append mode**: Adds the new value to the existing attribute, separated by the specified separator.
|
|
69
86
|
- **Replace mode**: Completely overwrites the existing attribute value.
|
|
70
87
|
- **Duplicate prevention**: In append mode, prevents adding duplicate values when enabled.
|
|
71
88
|
|
|
89
|
+
### Object Mode (when `value` is an object)
|
|
90
|
+
|
|
91
|
+
- **Replace mode**: Completely replaces the entire object attribute.
|
|
92
|
+
- **Append mode**: Merges properties property by property:
|
|
93
|
+
- Starts from the current object attribute
|
|
94
|
+
- For each property in `value`, applies the same logic as string mode:
|
|
95
|
+
- If both current and new values are strings: appends them (respecting `preventDuplicateValues`)
|
|
96
|
+
- Otherwise: replaces the property with the new value (new value has precedence)
|
|
97
|
+
- Handles nested objects recursively
|
|
98
|
+
- Works on a copy to avoid mutation issues
|
|
99
|
+
|
|
100
|
+
### Undefined Values
|
|
101
|
+
|
|
102
|
+
- **Append mode**: `undefined` values are ignored, keeping the current attribute unchanged.
|
|
103
|
+
- **Replace mode**: `undefined` is assigned to the attribute.
|
|
104
|
+
|
|
72
105
|
## Common Use Cases
|
|
73
106
|
|
|
74
|
-
- **Dynamic CSS classes**: Adding/removing CSS classes based on state.
|
|
75
|
-
- **Data attributes**: Setting data-* attributes for JavaScript integration.
|
|
76
|
-
- **ARIA attributes**: Dynamically updating accessibility attributes.
|
|
77
|
-
- **Style attributes**: Modifying inline styles conditionally.
|
|
107
|
+
- **Dynamic CSS classes**: Adding/removing CSS classes based on state (string mode).
|
|
108
|
+
- **Data attributes**: Setting data-* attributes for JavaScript integration (string mode).
|
|
109
|
+
- **ARIA attributes**: Dynamically updating accessibility attributes (string mode).
|
|
110
|
+
- **Style attributes**: Modifying inline styles conditionally (object mode). Merge style properties without losing existing ones.
|
|
78
111
|
|
|
79
112
|
- type: RjBuildDescriber
|
|
80
113
|
title: "SetAttributeValue Action Examples"
|
|
@@ -134,11 +167,90 @@ renderView:
|
|
|
134
167
|
data:
|
|
135
168
|
input_data: ""
|
|
136
169
|
|
|
170
|
+
- type: RjBuildDescriber
|
|
171
|
+
title: "Object Mode Example - Style Merging"
|
|
172
|
+
description:
|
|
173
|
+
- type: Markdown
|
|
174
|
+
content: |
|
|
175
|
+
This example demonstrates how to use `setAttributeValue` in object mode to merge style properties without losing existing ones.
|
|
176
|
+
|
|
177
|
+
**Expected behavior:**
|
|
178
|
+
- The div has initial styles (padding, border, borderRadius)
|
|
179
|
+
- When `isHighlighted` is true, additional style properties are merged
|
|
180
|
+
- The original styles are preserved, and new properties are added
|
|
181
|
+
- Try toggling the highlight to see the style merge in action
|
|
182
|
+
|
|
183
|
+
toDescribe:
|
|
184
|
+
renderView:
|
|
185
|
+
- type: div
|
|
186
|
+
attributes:
|
|
187
|
+
style:
|
|
188
|
+
padding: "10px"
|
|
189
|
+
border: "2px solid #007bff"
|
|
190
|
+
borderRadius: "4px"
|
|
191
|
+
attributeTransforms:
|
|
192
|
+
# Merge additional style properties without losing existing ones
|
|
193
|
+
- what: setAttributeValue
|
|
194
|
+
name: "style"
|
|
195
|
+
value:
|
|
196
|
+
borderColor: "#3b82f6"
|
|
197
|
+
backgroundColor: "#f0f0f0"
|
|
198
|
+
when: ~.isHighlighted
|
|
199
|
+
is: true
|
|
200
|
+
content: "Click to toggle highlight"
|
|
201
|
+
|
|
202
|
+
- type: button
|
|
203
|
+
content: "Toggle Highlight"
|
|
204
|
+
actions:
|
|
205
|
+
- what: setData
|
|
206
|
+
on: click
|
|
207
|
+
path: ~.isHighlighted
|
|
208
|
+
value: <reactive-json:not>~~.isHighlighted</reactive-json:not>
|
|
209
|
+
|
|
210
|
+
data:
|
|
211
|
+
isHighlighted: false
|
|
212
|
+
|
|
213
|
+
- type: RjBuildDescriber
|
|
214
|
+
title: "Object Mode Replace Example"
|
|
215
|
+
description:
|
|
216
|
+
- type: Markdown
|
|
217
|
+
content: |
|
|
218
|
+
This example demonstrates how to completely replace a style object using `mode: "replace"`.
|
|
219
|
+
|
|
220
|
+
**Expected behavior:**
|
|
221
|
+
- The div has initial styles (padding, border)
|
|
222
|
+
- When replace mode is used, the entire style object is replaced
|
|
223
|
+
- Original styles are lost, only the new styles remain
|
|
224
|
+
|
|
225
|
+
toDescribe:
|
|
226
|
+
renderView:
|
|
227
|
+
- type: div
|
|
228
|
+
attributes:
|
|
229
|
+
style:
|
|
230
|
+
padding: "10px"
|
|
231
|
+
border: "2px solid #007bff"
|
|
232
|
+
attributeTransforms:
|
|
233
|
+
# Completely replace the style object
|
|
234
|
+
- what: setAttributeValue
|
|
235
|
+
name: "style"
|
|
236
|
+
mode: "replace"
|
|
237
|
+
value:
|
|
238
|
+
backgroundColor: "#ffffff"
|
|
239
|
+
color: "#000000"
|
|
240
|
+
content: "This div's style was completely replaced"
|
|
241
|
+
|
|
137
242
|
- type: Markdown
|
|
138
243
|
content: |
|
|
139
244
|
## Notes
|
|
140
245
|
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
-
|
|
144
|
-
|
|
246
|
+
- **Pre-render execution**: This transformer modifies attributes before the component renders, ensuring child components receive the transformed attributes.
|
|
247
|
+
- **Mode detection**: The transformer automatically detects whether to use string mode or object mode based on the `value` type after template evaluation.
|
|
248
|
+
- **Append mode behavior**:
|
|
249
|
+
- **String mode**: Respects existing attribute values, adding new values separated by the specified separator.
|
|
250
|
+
- **Object mode**: Merges properties property by property, applying string append logic where both values are strings, otherwise replacing with the new value.
|
|
251
|
+
- **Replace mode**: Use when you need complete control over the attribute value. In object mode, completely replaces the entire object.
|
|
252
|
+
- **Duplicate prevention**: Only applies to append mode, and works for string values in both string mode and object mode.
|
|
253
|
+
- **Object merging**: In object mode append, nested objects are merged recursively. Properties that don't match the expected format for append are replaced (new value has precedence).
|
|
254
|
+
- **Template evaluation**: The value property supports full template evaluation including `~.localData`, `~~.globalData`, `~>nearestKey`, and `~~>globalKey` patterns.
|
|
255
|
+
- **Conditional execution**: Supports the same condition system as actions (`when`, `is`, `isEmpty`, `isNotEmpty`, etc.).
|
|
256
|
+
- **Undefined handling**: `undefined` values are ignored in append mode but assigned in replace mode.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# DataFilter Example: Filtering Direct Array Items
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to use `DataFilter` with arrays where each item is a direct object (not wrapped in a namespace property). This is useful when working with data from APIs that return arrays of objects directly.
|
|
4
|
+
|
|
5
|
+
## Use Case
|
|
6
|
+
|
|
7
|
+
When your data structure is a direct array of objects like:
|
|
8
|
+
```yaml
|
|
9
|
+
data:
|
|
10
|
+
rows:
|
|
11
|
+
- id: 1
|
|
12
|
+
label: "Operation 1"
|
|
13
|
+
done: "done"
|
|
14
|
+
operation: "create"
|
|
15
|
+
- id: 2
|
|
16
|
+
label: "Operation 2"
|
|
17
|
+
done: "pending"
|
|
18
|
+
operation: "update"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Instead of:
|
|
22
|
+
```yaml
|
|
23
|
+
data:
|
|
24
|
+
rows:
|
|
25
|
+
- item:
|
|
26
|
+
id: 1
|
|
27
|
+
label: "Operation 1"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Solution
|
|
31
|
+
|
|
32
|
+
Use an existing property that is present in all items (like `id`) as the `subjectsWithProperty` namespace. In `whenFilterableData`, reference properties directly without the namespace prefix.
|
|
33
|
+
|
|
34
|
+
**Important**: When using string values for filtering (like status), use a special value like `"all"` to represent "no filter" instead of an empty string, as empty strings can cause issues with select elements.
|
|
35
|
+
|
|
36
|
+
## Complete Example
|
|
37
|
+
|
|
38
|
+
```yaml
|
|
39
|
+
renderView:
|
|
40
|
+
- type: DataFilter
|
|
41
|
+
context: global
|
|
42
|
+
filters:
|
|
43
|
+
- subjectsWithProperty: id
|
|
44
|
+
andConditions:
|
|
45
|
+
# Filter by status (string)
|
|
46
|
+
- orConditions:
|
|
47
|
+
- when: ~~._filters.done
|
|
48
|
+
is: "all"
|
|
49
|
+
- whenFilterableData: done
|
|
50
|
+
is: ~~._filters.done
|
|
51
|
+
|
|
52
|
+
# Filter by operation type (text search with contains)
|
|
53
|
+
- orConditions:
|
|
54
|
+
- when: ~~._filters.operation
|
|
55
|
+
is: ""
|
|
56
|
+
- andConditions:
|
|
57
|
+
- whenFilterableData: operation
|
|
58
|
+
isNotEmpty: true
|
|
59
|
+
- when: ~~._filters.operation
|
|
60
|
+
isNotEmpty: true
|
|
61
|
+
- whenFilterableData: operation
|
|
62
|
+
contains: ~~._filters.operation
|
|
63
|
+
|
|
64
|
+
# Filter by label (text search with contains)
|
|
65
|
+
- orConditions:
|
|
66
|
+
- when: ~~._filters.label
|
|
67
|
+
is: ""
|
|
68
|
+
- andConditions:
|
|
69
|
+
- whenFilterableData: label
|
|
70
|
+
isNotEmpty: true
|
|
71
|
+
- when: ~~._filters.label
|
|
72
|
+
isNotEmpty: true
|
|
73
|
+
- whenFilterableData: label
|
|
74
|
+
contains: ~~._filters.label
|
|
75
|
+
content:
|
|
76
|
+
- type: Switch
|
|
77
|
+
content: ~~.rows
|
|
78
|
+
singleOption:
|
|
79
|
+
load: operationRow
|
|
80
|
+
|
|
81
|
+
templates:
|
|
82
|
+
operationRow:
|
|
83
|
+
- type: tr
|
|
84
|
+
content:
|
|
85
|
+
- type: td
|
|
86
|
+
content: ~.id
|
|
87
|
+
- type: td
|
|
88
|
+
content: ~.label
|
|
89
|
+
- type: td
|
|
90
|
+
content: ~.done
|
|
91
|
+
- type: td
|
|
92
|
+
content: ~.operation
|
|
93
|
+
|
|
94
|
+
data:
|
|
95
|
+
rows:
|
|
96
|
+
- id: 1
|
|
97
|
+
label: "Operation 1"
|
|
98
|
+
done: "done"
|
|
99
|
+
operation: "create"
|
|
100
|
+
- id: 2
|
|
101
|
+
label: "Operation 2"
|
|
102
|
+
done: "pending"
|
|
103
|
+
operation: "update"
|
|
104
|
+
- id: 3
|
|
105
|
+
label: "Operation 3"
|
|
106
|
+
done: "done"
|
|
107
|
+
operation: "create"
|
|
108
|
+
_filters:
|
|
109
|
+
done: "all"
|
|
110
|
+
label: ""
|
|
111
|
+
operation: ""
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Key Points
|
|
115
|
+
|
|
116
|
+
1. **Namespace Selection**: Choose a property that exists in all items (e.g., `id`, `name`, `key`). This property acts as the identifier for DataFilter to recognize filterable items.
|
|
117
|
+
|
|
118
|
+
2. **Direct Property Access**: In `whenFilterableData`, reference properties directly:
|
|
119
|
+
- ✅ `whenFilterableData: label` (correct)
|
|
120
|
+
- ❌ `whenFilterableData: id.label` (incorrect - don't use namespace prefix)
|
|
121
|
+
|
|
122
|
+
3. **String-based Filtering**: When using select elements for filtering, use a special value like `"all"` to represent "no filter" instead of an empty string:
|
|
123
|
+
```yaml
|
|
124
|
+
- orConditions:
|
|
125
|
+
- when: ~~._filters.done
|
|
126
|
+
is: "all" # Shows all items
|
|
127
|
+
- whenFilterableData: done
|
|
128
|
+
is: ~~._filters.done # Filters by exact match
|
|
129
|
+
```
|
|
130
|
+
This avoids issues where select elements might not properly handle empty string values.
|
|
131
|
+
|
|
132
|
+
4. **Text Search**: For text search with `contains`, ensure both the filter value and the data property are not empty:
|
|
133
|
+
```yaml
|
|
134
|
+
- orConditions:
|
|
135
|
+
- when: ~~._filters.label
|
|
136
|
+
is: "" # Shows all when empty
|
|
137
|
+
- andConditions:
|
|
138
|
+
- whenFilterableData: label
|
|
139
|
+
isNotEmpty: true
|
|
140
|
+
- when: ~~._filters.label
|
|
141
|
+
isNotEmpty: true
|
|
142
|
+
- whenFilterableData: label
|
|
143
|
+
contains: ~~._filters.label
|
|
144
|
+
```
|
|
145
|
+
The `andConditions` wrapper ensures that both the data property and filter value are not empty before attempting the `contains` comparison.
|
|
146
|
+
|
|
147
|
+
5. **Template Access**: In templates, access properties directly without namespace:
|
|
148
|
+
- ✅ `~.label`, `~.done`, `~.operation`
|
|
149
|
+
- ❌ `~.id.label` (incorrect)
|
|
150
|
+
|
|
151
|
+
## Filter Types Demonstrated
|
|
152
|
+
|
|
153
|
+
- **Select Filter with "All" option**: Using `is: "all"` to show all items when a special "all" value is selected
|
|
154
|
+
- **Exact String Match**: Using `is` for exact string matching (e.g., status filtering)
|
|
155
|
+
- **Text Search**: Using `contains` for substring matching (case-insensitive) with proper empty checks
|
|
156
|
+
|
|
157
|
+
## Additional Template Techniques
|
|
158
|
+
|
|
159
|
+
**Conditional Display in Templates**: The example uses `hide` actions to conditionally display badges based on data values. This is a common pattern for showing different UI elements based on data state:
|
|
160
|
+
|
|
161
|
+
```yaml
|
|
162
|
+
- type: span
|
|
163
|
+
content: "Done"
|
|
164
|
+
actions:
|
|
165
|
+
- what: hide
|
|
166
|
+
when: ~.done
|
|
167
|
+
isNot: "done" # Hide if status is not "done"
|
|
168
|
+
- type: span
|
|
169
|
+
content: "Pending"
|
|
170
|
+
actions:
|
|
171
|
+
- what: hide
|
|
172
|
+
when: ~.done
|
|
173
|
+
isNot: "pending" # Hide if status is not "pending"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
This technique is used in the example to display colored status badges, but it's not part of the DataFilter pattern itself - it's just a way to enhance the visual display of filtered data.
|
|
177
|
+
|
|
178
|
+
## Filter Patterns
|
|
179
|
+
|
|
180
|
+
### Pattern 1: Select Filter with "All" Option
|
|
181
|
+
```yaml
|
|
182
|
+
- orConditions:
|
|
183
|
+
- when: ~~._filters.status
|
|
184
|
+
is: "all" # Special value for "show all"
|
|
185
|
+
- whenFilterableData: status
|
|
186
|
+
is: ~~._filters.status # Exact match filter
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Pattern 2: Text Input Filter (Empty String Check)
|
|
190
|
+
```yaml
|
|
191
|
+
- orConditions:
|
|
192
|
+
- when: ~~._filters.search
|
|
193
|
+
is: "" # Empty string means "show all"
|
|
194
|
+
- andConditions:
|
|
195
|
+
- whenFilterableData: searchField
|
|
196
|
+
isNotEmpty: true
|
|
197
|
+
- when: ~~._filters.search
|
|
198
|
+
isNotEmpty: true
|
|
199
|
+
- whenFilterableData: searchField
|
|
200
|
+
contains: ~~._filters.search
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Notes
|
|
204
|
+
|
|
205
|
+
- The `subjectsWithProperty` value (`id` in this example) must exist in every item of the array
|
|
206
|
+
- DataFilter filters the data before rendering, so no `hide` actions are needed in templates
|
|
207
|
+
- All filter conditions use `orConditions` with an empty/"all" check first, allowing "show all" when filters are empty or set to "all"
|
|
208
|
+
- For select elements, prefer using a special value like `"all"` instead of empty strings to avoid UI issues
|
|
209
|
+
- For text inputs, empty strings (`""`) work fine for the "show all" condition
|
|
210
|
+
- When using `contains` for text search, always wrap the condition in `andConditions` with `isNotEmpty` checks to avoid errors with empty values
|
|
211
|
+
|