@ea-lab/reactive-json-docs 0.1.2
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/README-npm.md +49 -0
- package/README.md +86 -0
- package/package.json +79 -0
- package/public/rjbuild/component-doc/chartjs/components.yaml +252 -0
- package/public/rjbuild/component-doc/chartjs/overview.yaml +51 -0
- package/public/rjbuild/component-doc/core/action/HashChangeListener.md +90 -0
- package/public/rjbuild/component-doc/core/action/HashChangeListener.yaml +124 -0
- package/public/rjbuild/component-doc/core/action/Hide.md +22 -0
- package/public/rjbuild/component-doc/core/action/Hide.yaml +60 -0
- package/public/rjbuild/component-doc/core/action/MessageListener.md +93 -0
- package/public/rjbuild/component-doc/core/action/MessageListener.yaml +153 -0
- package/public/rjbuild/component-doc/core/action/Popover.md +26 -0
- package/public/rjbuild/component-doc/core/action/Popover.yaml +100 -0
- package/public/rjbuild/component-doc/core/action/ReactOnEvent.md +81 -0
- package/public/rjbuild/component-doc/core/action/ReactOnEvent.yaml +133 -0
- package/public/rjbuild/component-doc/core/action/Redirect.md +20 -0
- package/public/rjbuild/component-doc/core/action/Redirect.yaml +68 -0
- package/public/rjbuild/component-doc/core/action/Tooltip.md +22 -0
- package/public/rjbuild/component-doc/core/action/Tooltip.yaml +90 -0
- package/public/rjbuild/component-doc/core/action/VisuallyHide.md +21 -0
- package/public/rjbuild/component-doc/core/action/VisuallyHide.yaml +62 -0
- package/public/rjbuild/component-doc/core/action/index.md +214 -0
- package/public/rjbuild/component-doc/core/action/index.yaml +278 -0
- package/public/rjbuild/component-doc/core/element/form/CheckBoxField.md +276 -0
- package/public/rjbuild/component-doc/core/element/form/CheckBoxField.yaml +338 -0
- package/public/rjbuild/component-doc/core/element/form/DateField.md +189 -0
- package/public/rjbuild/component-doc/core/element/form/DateField.yaml +264 -0
- package/public/rjbuild/component-doc/core/element/form/NumberField.md +136 -0
- package/public/rjbuild/component-doc/core/element/form/NumberField.yaml +103 -0
- package/public/rjbuild/component-doc/core/element/form/SelectField.md +304 -0
- package/public/rjbuild/component-doc/core/element/form/SelectField.yaml +360 -0
- package/public/rjbuild/component-doc/core/element/form/TextAreaField.md +134 -0
- package/public/rjbuild/component-doc/core/element/form/TextAreaField.yaml +146 -0
- package/public/rjbuild/component-doc/core/element/form/TextField.md +129 -0
- package/public/rjbuild/component-doc/core/element/form/TextField.yaml +147 -0
- package/public/rjbuild/component-doc/core/element/form/formElementsCommon.md +106 -0
- package/public/rjbuild/component-doc/core/element/form/index.md +50 -0
- package/public/rjbuild/component-doc/core/element/form/index.yaml +96 -0
- package/public/rjbuild/component-doc/core/element/html/AccordionItem.yaml +47 -0
- package/public/rjbuild/component-doc/core/element/html/FolderSortableTree.yaml +81 -0
- package/public/rjbuild/component-doc/core/element/html/FormatNumeral.yaml +58 -0
- package/public/rjbuild/component-doc/core/element/html/Html.yaml +67 -0
- package/public/rjbuild/component-doc/core/element/html/LabelFromValue.yaml +54 -0
- package/public/rjbuild/component-doc/core/element/html/Modal.yaml +93 -0
- package/public/rjbuild/component-doc/core/element/html/PreformattedMarkup.yaml +37 -0
- package/public/rjbuild/component-doc/core/element/html/SortableTreeItemCollapseButton.yaml +92 -0
- package/public/rjbuild/component-doc/core/element/html/Tabs.yaml +57 -0
- package/public/rjbuild/component-doc/core/element/special/BootstrapElement.md +17 -0
- package/public/rjbuild/component-doc/core/element/special/BootstrapElement.yaml +18 -0
- package/public/rjbuild/component-doc/core/element/special/Count.md +37 -0
- package/public/rjbuild/component-doc/core/element/special/Count.yaml +325 -0
- package/public/rjbuild/component-doc/core/element/special/DataFilter.md +149 -0
- package/public/rjbuild/component-doc/core/element/special/DataFilter.yaml +315 -0
- package/public/rjbuild/component-doc/core/element/special/DelayedActions.md +51 -0
- package/public/rjbuild/component-doc/core/element/special/DelayedActions.yaml +55 -0
- package/public/rjbuild/component-doc/core/element/special/PageControls.md +126 -0
- package/public/rjbuild/component-doc/core/element/special/PageControls.yaml +133 -0
- package/public/rjbuild/component-doc/core/element/special/Phantom.md +31 -0
- package/public/rjbuild/component-doc/core/element/special/Phantom.yaml +34 -0
- package/public/rjbuild/component-doc/core/element/special/ReactiveJsonSubroot.md +27 -0
- package/public/rjbuild/component-doc/core/element/special/ReactiveJsonSubroot.yaml +51 -0
- package/public/rjbuild/component-doc/core/element/special/Switch.md +262 -0
- package/public/rjbuild/component-doc/core/element/special/Switch.yaml +348 -0
- package/public/rjbuild/component-doc/core/example/accordion.md +96 -0
- package/public/rjbuild/component-doc/core/example/accordion.yaml +64 -0
- package/public/rjbuild/component-doc/core/example/dynamic-content.md +197 -0
- package/public/rjbuild/component-doc/core/example/dynamic-content.yaml +237 -0
- package/public/rjbuild/component-doc/core/example/html.md +66 -0
- package/public/rjbuild/component-doc/core/example/html.yaml +83 -0
- package/public/rjbuild/component-doc/core/example/website.yaml +1663 -0
- package/public/rjbuild/component-doc/core/reaction/addData.md +96 -0
- package/public/rjbuild/component-doc/core/reaction/addData.yaml +133 -0
- package/public/rjbuild/component-doc/core/reaction/fetchData.md +60 -0
- package/public/rjbuild/component-doc/core/reaction/fetchData.yaml +156 -0
- package/public/rjbuild/component-doc/core/reaction/index.md +236 -0
- package/public/rjbuild/component-doc/core/reaction/index.yaml +254 -0
- package/public/rjbuild/component-doc/core/reaction/moveData.md +68 -0
- package/public/rjbuild/component-doc/core/reaction/moveData.yaml +71 -0
- package/public/rjbuild/component-doc/core/reaction/postMessage.md +63 -0
- package/public/rjbuild/component-doc/core/reaction/postMessage.yaml +68 -0
- package/public/rjbuild/component-doc/core/reaction/redirectNow.md +37 -0
- package/public/rjbuild/component-doc/core/reaction/redirectNow.yaml +37 -0
- package/public/rjbuild/component-doc/core/reaction/removeData.md +78 -0
- package/public/rjbuild/component-doc/core/reaction/removeData.yaml +56 -0
- package/public/rjbuild/component-doc/core/reaction/setClipboardData.md +44 -0
- package/public/rjbuild/component-doc/core/reaction/setClipboardData.yaml +41 -0
- package/public/rjbuild/component-doc/core/reaction/setData.md +93 -0
- package/public/rjbuild/component-doc/core/reaction/setData.yaml +85 -0
- package/public/rjbuild/component-doc/core/reaction/submitData.md +138 -0
- package/public/rjbuild/component-doc/core/reaction/submitData.yaml +141 -0
- package/public/rjbuild/component-doc/core/reaction/triggerEvent.md +59 -0
- package/public/rjbuild/component-doc/core/reaction/triggerEvent.yaml +59 -0
- package/public/rjbuild/component-doc/index.yaml +13 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# SelectField
|
|
2
|
+
|
|
3
|
+
The `SelectField` component renders a dropdown selection field using React Bootstrap. It supports both static and dynamic options, automatic data binding, and intelligent value type handling for different data types including strings, booleans, numbers, and null values.
|
|
4
|
+
|
|
5
|
+
## Properties
|
|
6
|
+
|
|
7
|
+
- `dataLocation` (string, optional): Path to bind the field value in the data context
|
|
8
|
+
- `defaultFieldValue` (any, optional): Default value when no data is present
|
|
9
|
+
- `label` (string, optional): Field label text (supports template evaluation)
|
|
10
|
+
- `options` (array, optional): Static array of option objects with `label` and `value` properties
|
|
11
|
+
- `dynamicOptions` (string, optional): Template path to dynamic options array
|
|
12
|
+
- `allowEmptyStringAsValue` (boolean, optional): Preserve empty strings as `""` instead of converting to `undefined` (default: false)
|
|
13
|
+
- `attributes` (object, optional): Attributes applied to the Form.Group container
|
|
14
|
+
- `inputAttributes` (object, optional): Attributes applied directly to the select element
|
|
15
|
+
- `actions` (array, optional): Actions to execute based on field state
|
|
16
|
+
|
|
17
|
+
## Option Format
|
|
18
|
+
|
|
19
|
+
Each option object must have:
|
|
20
|
+
- `label` (string): Display text for the option
|
|
21
|
+
- `value` (any): The actual value to store when selected
|
|
22
|
+
|
|
23
|
+
## Data Management
|
|
24
|
+
|
|
25
|
+
The component automatically synchronizes its value with the global data context. It handles different value types intelligently:
|
|
26
|
+
|
|
27
|
+
### Value Type Conversion
|
|
28
|
+
- **Empty strings**: Become `undefined` by default, or preserved as `""` if `allowEmptyStringAsValue: true`
|
|
29
|
+
- **Boolean strings**: "true" becomes boolean `true`, "false" becomes boolean `false`
|
|
30
|
+
- **Null string**: "null" becomes `null`
|
|
31
|
+
- **Other values**: Matched by string comparison and converted to their original type
|
|
32
|
+
|
|
33
|
+
### Key Feature: Empty String Handling
|
|
34
|
+
|
|
35
|
+
SelectField makes an important distinction between "no selection made" and "explicit selection of empty value":
|
|
36
|
+
|
|
37
|
+
- **Default behavior**: `value: ""` → stored as `undefined`
|
|
38
|
+
- Semantic meaning: "User hasn't made a selection yet"
|
|
39
|
+
- Useful for validation and conditional logic
|
|
40
|
+
- **With `allowEmptyStringAsValue: true`**: `value: ""` → stored as `""`
|
|
41
|
+
- Semantic meaning: "User explicitly selected the empty option"
|
|
42
|
+
- Useful when empty string is a legitimate business value
|
|
43
|
+
|
|
44
|
+
This distinction is crucial for validation logic and conditional actions in reactive-json.
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
# Example: Default behavior (recommended for most cases)
|
|
48
|
+
options:
|
|
49
|
+
- label: "Choose category..." # Placeholder option
|
|
50
|
+
value: "" # → undefined = "not selected"
|
|
51
|
+
- label: "Technology"
|
|
52
|
+
value: "tech" # → "tech"
|
|
53
|
+
- label: "No category" # Business choice
|
|
54
|
+
value: "none" # → "none" = explicit empty choice
|
|
55
|
+
|
|
56
|
+
# Example: When empty string is a business value
|
|
57
|
+
allowEmptyStringAsValue: true
|
|
58
|
+
options:
|
|
59
|
+
- label: "No description" # Legitimate business choice
|
|
60
|
+
value: "" # → "" = valid empty value
|
|
61
|
+
- label: "Brief description"
|
|
62
|
+
value: "brief" # → "brief"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Data Storage
|
|
66
|
+
- Single value selection only (for multiple selection, use CheckBoxField)
|
|
67
|
+
- Automatically updates the data context when selection changes
|
|
68
|
+
- Preserves the original data type of the selected option value
|
|
69
|
+
|
|
70
|
+
## Basic SelectField Usage
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
renderView:
|
|
74
|
+
- type: SelectField
|
|
75
|
+
dataLocation: ~.priority
|
|
76
|
+
label: "Priority:"
|
|
77
|
+
options:
|
|
78
|
+
- label: "Select priority"
|
|
79
|
+
value: ""
|
|
80
|
+
- label: "Low"
|
|
81
|
+
value: "low"
|
|
82
|
+
- label: "Medium"
|
|
83
|
+
value: "medium"
|
|
84
|
+
- label: "High"
|
|
85
|
+
value: "high"
|
|
86
|
+
|
|
87
|
+
data:
|
|
88
|
+
priority: ""
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Boolean and Special Values
|
|
92
|
+
|
|
93
|
+
```yaml
|
|
94
|
+
renderView:
|
|
95
|
+
- type: SelectField
|
|
96
|
+
dataLocation: ~.isPublic
|
|
97
|
+
label: "Visibility:"
|
|
98
|
+
options:
|
|
99
|
+
- label: "Select visibility"
|
|
100
|
+
value: ""
|
|
101
|
+
- label: "Public"
|
|
102
|
+
value: true
|
|
103
|
+
- label: "Private"
|
|
104
|
+
value: false
|
|
105
|
+
- label: "Draft"
|
|
106
|
+
value: "draft"
|
|
107
|
+
|
|
108
|
+
data:
|
|
109
|
+
isPublic: ""
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Dynamic Options
|
|
113
|
+
|
|
114
|
+
```yaml
|
|
115
|
+
renderView:
|
|
116
|
+
- type: SelectField
|
|
117
|
+
dataLocation: ~.country
|
|
118
|
+
label: "Country:"
|
|
119
|
+
dynamicOptions: ~.availableCountries
|
|
120
|
+
|
|
121
|
+
data:
|
|
122
|
+
country: ""
|
|
123
|
+
availableCountries:
|
|
124
|
+
- label: "Select country"
|
|
125
|
+
value: ""
|
|
126
|
+
- label: "France"
|
|
127
|
+
value: "fr"
|
|
128
|
+
- label: "United States"
|
|
129
|
+
value: "us"
|
|
130
|
+
- label: "Canada"
|
|
131
|
+
value: "ca"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Conditional Display
|
|
135
|
+
|
|
136
|
+
```yaml
|
|
137
|
+
renderView:
|
|
138
|
+
- type: SelectField
|
|
139
|
+
dataLocation: ~.userRole
|
|
140
|
+
label: "Role:"
|
|
141
|
+
options:
|
|
142
|
+
- label: "Select role"
|
|
143
|
+
value: ""
|
|
144
|
+
- label: "Administrator"
|
|
145
|
+
value: "admin"
|
|
146
|
+
- label: "User"
|
|
147
|
+
value: "user"
|
|
148
|
+
- type: SelectField
|
|
149
|
+
dataLocation: ~.permissions
|
|
150
|
+
label: "Permissions:"
|
|
151
|
+
dynamicOptions: ~.rolePermissions
|
|
152
|
+
actions:
|
|
153
|
+
- what: hide
|
|
154
|
+
when: ~.userRole
|
|
155
|
+
isEmpty: true
|
|
156
|
+
|
|
157
|
+
data:
|
|
158
|
+
userRole: ""
|
|
159
|
+
permissions: ""
|
|
160
|
+
rolePermissions:
|
|
161
|
+
- label: "Select permissions"
|
|
162
|
+
value: ""
|
|
163
|
+
- label: "Read only"
|
|
164
|
+
value: "read"
|
|
165
|
+
- label: "Read/Write"
|
|
166
|
+
value: "write"
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Empty String Handling
|
|
170
|
+
|
|
171
|
+
This example demonstrates the difference between default behavior and `allowEmptyStringAsValue: true`:
|
|
172
|
+
|
|
173
|
+
```yaml
|
|
174
|
+
renderView:
|
|
175
|
+
# Default behavior: "" becomes undefined
|
|
176
|
+
- type: SelectField
|
|
177
|
+
dataLocation: ~.category
|
|
178
|
+
label: "Category (default behavior):"
|
|
179
|
+
options:
|
|
180
|
+
- label: "Select category..."
|
|
181
|
+
value: "" # → undefined
|
|
182
|
+
- label: "Technology"
|
|
183
|
+
value: "tech"
|
|
184
|
+
- label: "No category"
|
|
185
|
+
value: "none" # Explicit "empty" choice
|
|
186
|
+
|
|
187
|
+
# With allowEmptyStringAsValue: "" is preserved
|
|
188
|
+
- type: SelectField
|
|
189
|
+
dataLocation: ~.description
|
|
190
|
+
label: "Description (preserve empty):"
|
|
191
|
+
allowEmptyStringAsValue: true
|
|
192
|
+
options:
|
|
193
|
+
- label: "No description"
|
|
194
|
+
value: "" # → ""
|
|
195
|
+
- label: "Brief"
|
|
196
|
+
value: "brief"
|
|
197
|
+
- label: "Detailed"
|
|
198
|
+
value: "detailed"
|
|
199
|
+
|
|
200
|
+
data:
|
|
201
|
+
category: "" # Will become undefined after first selection
|
|
202
|
+
description: "" # Will stay "" when "No description" selected
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Static Options
|
|
206
|
+
|
|
207
|
+
```yaml
|
|
208
|
+
renderView:
|
|
209
|
+
- type: SelectField
|
|
210
|
+
dataLocation: ~.priority
|
|
211
|
+
label: "Priority:"
|
|
212
|
+
options:
|
|
213
|
+
- label: "Select priority"
|
|
214
|
+
value: ""
|
|
215
|
+
- label: "Low"
|
|
216
|
+
value: "low"
|
|
217
|
+
- label: "Medium"
|
|
218
|
+
value: "medium"
|
|
219
|
+
- label: "High"
|
|
220
|
+
value: "high"
|
|
221
|
+
|
|
222
|
+
data:
|
|
223
|
+
priority: ""
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Complete Examples
|
|
227
|
+
|
|
228
|
+
### Static Options
|
|
229
|
+
```yaml
|
|
230
|
+
renderView:
|
|
231
|
+
- type: SelectField
|
|
232
|
+
dataLocation: ~.priority
|
|
233
|
+
label: "Priority:"
|
|
234
|
+
options:
|
|
235
|
+
- label: "Select priority"
|
|
236
|
+
value: ""
|
|
237
|
+
- label: "Low"
|
|
238
|
+
value: "low"
|
|
239
|
+
- label: "Medium"
|
|
240
|
+
value: "medium"
|
|
241
|
+
- label: "High"
|
|
242
|
+
value: "high"
|
|
243
|
+
|
|
244
|
+
data:
|
|
245
|
+
priority: ""
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Dynamic Options
|
|
249
|
+
```yaml
|
|
250
|
+
renderView:
|
|
251
|
+
- type: SelectField
|
|
252
|
+
dataLocation: ~.country
|
|
253
|
+
label: "Country:"
|
|
254
|
+
dynamicOptions: ~.availableCountries
|
|
255
|
+
|
|
256
|
+
data:
|
|
257
|
+
country: ""
|
|
258
|
+
availableCountries:
|
|
259
|
+
- label: "Select country"
|
|
260
|
+
value: ""
|
|
261
|
+
- label: "France"
|
|
262
|
+
value: "fr"
|
|
263
|
+
- label: "United States"
|
|
264
|
+
value: "us"
|
|
265
|
+
- label: "Canada"
|
|
266
|
+
value: "ca"
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Input Attributes
|
|
270
|
+
|
|
271
|
+
The component supports custom attributes via `inputAttributes`:
|
|
272
|
+
|
|
273
|
+
```yaml
|
|
274
|
+
renderView:
|
|
275
|
+
- type: SelectField
|
|
276
|
+
dataLocation: ~.category
|
|
277
|
+
label: "Category:"
|
|
278
|
+
options:
|
|
279
|
+
- label: "Select category"
|
|
280
|
+
value: ""
|
|
281
|
+
- label: "Category A"
|
|
282
|
+
value: "a"
|
|
283
|
+
- label: "Category B"
|
|
284
|
+
value: "b"
|
|
285
|
+
inputAttributes:
|
|
286
|
+
required: true
|
|
287
|
+
style:
|
|
288
|
+
fontSize: "16px"
|
|
289
|
+
|
|
290
|
+
data:
|
|
291
|
+
category: ""
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Limitations
|
|
295
|
+
|
|
296
|
+
### Technical Limitations
|
|
297
|
+
- **Single selection only**: For multiple selection, use CheckBoxField
|
|
298
|
+
- **Value conversion**: Option values are converted to strings for HTML compatibility, then back to original types
|
|
299
|
+
- **Complex values**: Objects cannot be used as option values
|
|
300
|
+
- **No option groups**: `<optgroup>` is not supported
|
|
301
|
+
- **Simple labels only**: Template evaluation in labels is limited to simple string values
|
|
302
|
+
- **No built-in validation**: Beyond basic required field checking
|
|
303
|
+
- **No search/filtering**: Built-in search capabilities are not available
|
|
304
|
+
- **Bug with null values**: Options with `value: null` don't display as selected correctly (implementation issue)
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
renderView:
|
|
2
|
+
- type: Markdown
|
|
3
|
+
content: |
|
|
4
|
+
# SelectField
|
|
5
|
+
|
|
6
|
+
The `SelectField` component renders a dropdown selection field using React Bootstrap. It supports both static and dynamic options, automatic data binding, and intelligent value type handling for different data types including strings, booleans, numbers, and null values.
|
|
7
|
+
|
|
8
|
+
## Properties
|
|
9
|
+
|
|
10
|
+
- `dataLocation` (string, optional): Path to bind the field value in the data context
|
|
11
|
+
- `defaultFieldValue` (any, optional): Default value when no data is present
|
|
12
|
+
- `label` (string, optional): Field label text (supports template evaluation)
|
|
13
|
+
- `options` (array, optional): Static array of option objects with `label` and `value` properties
|
|
14
|
+
- `dynamicOptions` (string, optional): Template path to dynamic options array
|
|
15
|
+
- `allowEmptyStringAsValue` (boolean, optional): Preserve empty strings as `""` instead of converting to `undefined` (default: false)
|
|
16
|
+
- `attributes` (object, optional): Attributes applied to the Form.Group container
|
|
17
|
+
- `inputAttributes` (object, optional): Attributes applied directly to the select element
|
|
18
|
+
- `actions` (array, optional): Actions to execute based on field state
|
|
19
|
+
|
|
20
|
+
## Option Format
|
|
21
|
+
|
|
22
|
+
Each option object must have:
|
|
23
|
+
- `label` (string): Display text for the option
|
|
24
|
+
- `value` (any): The actual value to store when selected
|
|
25
|
+
|
|
26
|
+
## Data Management
|
|
27
|
+
|
|
28
|
+
The component automatically synchronizes its value with the global data context. It handles different value types intelligently:
|
|
29
|
+
|
|
30
|
+
### Value Type Conversion
|
|
31
|
+
- **Empty strings**: Become `undefined` by default, or preserved as `""` if `allowEmptyStringAsValue: true`
|
|
32
|
+
- **Boolean strings**: "true" becomes boolean `true`, "false" becomes boolean `false`
|
|
33
|
+
- **Null string**: "null" becomes `null`
|
|
34
|
+
- **Other values**: Matched by string comparison and converted to their original type
|
|
35
|
+
|
|
36
|
+
### Key Feature: Empty String Handling
|
|
37
|
+
|
|
38
|
+
SelectField makes an important distinction between "no selection made" and "explicit selection of empty value":
|
|
39
|
+
|
|
40
|
+
- **Default behavior**: `value: ""` → stored as `undefined`
|
|
41
|
+
- Semantic meaning: "User hasn't made a selection yet"
|
|
42
|
+
- Useful for validation and conditional logic
|
|
43
|
+
- **With `allowEmptyStringAsValue: true`**: `value: ""` → stored as `""`
|
|
44
|
+
- Semantic meaning: "User explicitly selected the empty option"
|
|
45
|
+
- Useful when empty string is a legitimate business value
|
|
46
|
+
|
|
47
|
+
This distinction is crucial for validation logic and conditional actions in reactive-json.
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
# Example: Default behavior (recommended for most cases)
|
|
51
|
+
options:
|
|
52
|
+
- label: "Choose category..." # Placeholder option
|
|
53
|
+
value: "" # → undefined = "not selected"
|
|
54
|
+
- label: "Technology"
|
|
55
|
+
value: "tech" # → "tech"
|
|
56
|
+
- label: "No category" # Business choice
|
|
57
|
+
value: "none" # → "none" = explicit empty choice
|
|
58
|
+
|
|
59
|
+
# Example: When empty string is a business value
|
|
60
|
+
allowEmptyStringAsValue: true
|
|
61
|
+
options:
|
|
62
|
+
- label: "No description" # Legitimate business choice
|
|
63
|
+
value: "" # → "" = valid empty value
|
|
64
|
+
- label: "Brief description"
|
|
65
|
+
value: "brief" # → "brief"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Data Storage
|
|
69
|
+
- Single value selection only (for multiple selection, use CheckBoxField)
|
|
70
|
+
- Automatically updates the data context when selection changes
|
|
71
|
+
- Preserves the original data type of the selected option value
|
|
72
|
+
|
|
73
|
+
- type: RjBuildDescriber
|
|
74
|
+
title: "Basic SelectField Usage"
|
|
75
|
+
description: "Simple dropdown with static options and different value types"
|
|
76
|
+
toDescribe:
|
|
77
|
+
renderView:
|
|
78
|
+
- type: SelectField
|
|
79
|
+
dataLocation: ~.priority
|
|
80
|
+
label: "Priority:"
|
|
81
|
+
options:
|
|
82
|
+
- label: "Select priority"
|
|
83
|
+
value: ""
|
|
84
|
+
- label: "Low"
|
|
85
|
+
value: "low"
|
|
86
|
+
- label: "Medium"
|
|
87
|
+
value: "medium"
|
|
88
|
+
- label: "High"
|
|
89
|
+
value: "high"
|
|
90
|
+
- type: div
|
|
91
|
+
content:
|
|
92
|
+
- "Selected value: "
|
|
93
|
+
- type: strong
|
|
94
|
+
content: ~.priority
|
|
95
|
+
actions:
|
|
96
|
+
- what: hide
|
|
97
|
+
when: ~.priority
|
|
98
|
+
isEmpty: true
|
|
99
|
+
data:
|
|
100
|
+
priority: ""
|
|
101
|
+
|
|
102
|
+
- type: RjBuildDescriber
|
|
103
|
+
title: "Boolean and Special Values"
|
|
104
|
+
description: "SelectField with boolean and string values affecting interface behavior"
|
|
105
|
+
toDescribe:
|
|
106
|
+
renderView:
|
|
107
|
+
- type: SelectField
|
|
108
|
+
dataLocation: ~.isPublic
|
|
109
|
+
label: "Visibility:"
|
|
110
|
+
options:
|
|
111
|
+
- label: "Select visibility"
|
|
112
|
+
value: ""
|
|
113
|
+
- label: "Public"
|
|
114
|
+
value: true
|
|
115
|
+
- label: "Private"
|
|
116
|
+
value: false
|
|
117
|
+
- label: "Draft"
|
|
118
|
+
value: "draft"
|
|
119
|
+
- type: div
|
|
120
|
+
content: "🌍 This content is public"
|
|
121
|
+
attributes:
|
|
122
|
+
style:
|
|
123
|
+
color: "green"
|
|
124
|
+
fontWeight: "bold"
|
|
125
|
+
actions:
|
|
126
|
+
- what: hide
|
|
127
|
+
when: ~.isPublic
|
|
128
|
+
isNot: true
|
|
129
|
+
- type: div
|
|
130
|
+
content: "🔒 This content is private"
|
|
131
|
+
attributes:
|
|
132
|
+
style:
|
|
133
|
+
color: "red"
|
|
134
|
+
fontWeight: "bold"
|
|
135
|
+
actions:
|
|
136
|
+
- what: hide
|
|
137
|
+
when: ~.isPublic
|
|
138
|
+
isNot: false
|
|
139
|
+
- type: div
|
|
140
|
+
content: "📝 This content is in draft mode"
|
|
141
|
+
attributes:
|
|
142
|
+
style:
|
|
143
|
+
color: "orange"
|
|
144
|
+
fontWeight: "bold"
|
|
145
|
+
actions:
|
|
146
|
+
- what: hide
|
|
147
|
+
when: ~.isPublic
|
|
148
|
+
isNot: "draft"
|
|
149
|
+
data:
|
|
150
|
+
isPublic: ""
|
|
151
|
+
|
|
152
|
+
- type: RjBuildDescriber
|
|
153
|
+
title: "Dynamic Options"
|
|
154
|
+
description: "SelectField with options loaded from data using dynamicOptions"
|
|
155
|
+
toDescribe:
|
|
156
|
+
renderView:
|
|
157
|
+
- type: SelectField
|
|
158
|
+
dataLocation: ~.country
|
|
159
|
+
label: "Country:"
|
|
160
|
+
dynamicOptions: ~.availableCountries
|
|
161
|
+
- type: div
|
|
162
|
+
content:
|
|
163
|
+
- "Selected: "
|
|
164
|
+
- type: strong
|
|
165
|
+
content: ~.country
|
|
166
|
+
actions:
|
|
167
|
+
- what: hide
|
|
168
|
+
when: ~.country
|
|
169
|
+
isEmpty: true
|
|
170
|
+
data:
|
|
171
|
+
country: ""
|
|
172
|
+
availableCountries:
|
|
173
|
+
- label: "Select country"
|
|
174
|
+
value: ""
|
|
175
|
+
- label: "France"
|
|
176
|
+
value: "fr"
|
|
177
|
+
- label: "United States"
|
|
178
|
+
value: "us"
|
|
179
|
+
- label: "Canada"
|
|
180
|
+
value: "ca"
|
|
181
|
+
|
|
182
|
+
- type: RjBuildDescriber
|
|
183
|
+
title: "Conditional Display"
|
|
184
|
+
description: "Hiding SelectField based on another field's value using hide action"
|
|
185
|
+
toDescribe:
|
|
186
|
+
renderView:
|
|
187
|
+
- type: SelectField
|
|
188
|
+
dataLocation: ~.userRole
|
|
189
|
+
label: "Role:"
|
|
190
|
+
options:
|
|
191
|
+
- label: "Select role"
|
|
192
|
+
value: ""
|
|
193
|
+
- label: "Administrator"
|
|
194
|
+
value: "admin"
|
|
195
|
+
- label: "User"
|
|
196
|
+
value: "user"
|
|
197
|
+
- type: SelectField
|
|
198
|
+
dataLocation: ~.permissions
|
|
199
|
+
label: "Permissions:"
|
|
200
|
+
dynamicOptions: ~.rolePermissions
|
|
201
|
+
actions:
|
|
202
|
+
- what: hide
|
|
203
|
+
when: ~.userRole
|
|
204
|
+
isEmpty: true
|
|
205
|
+
- type: div
|
|
206
|
+
content:
|
|
207
|
+
- "Role: "
|
|
208
|
+
- type: strong
|
|
209
|
+
content: ~.userRole
|
|
210
|
+
- " | Permissions: "
|
|
211
|
+
- type: strong
|
|
212
|
+
content: ~.permissions
|
|
213
|
+
actions:
|
|
214
|
+
- what: hide
|
|
215
|
+
when: ~.userRole
|
|
216
|
+
isEmpty: true
|
|
217
|
+
data:
|
|
218
|
+
userRole: ""
|
|
219
|
+
permissions: ""
|
|
220
|
+
rolePermissions:
|
|
221
|
+
- label: "Select permissions"
|
|
222
|
+
value: ""
|
|
223
|
+
- label: "Read only"
|
|
224
|
+
value: "read"
|
|
225
|
+
- label: "Read/Write"
|
|
226
|
+
value: "write"
|
|
227
|
+
|
|
228
|
+
- type: RjBuildDescriber
|
|
229
|
+
title: "Empty String Handling"
|
|
230
|
+
description: "Demonstrates the difference between default behavior ('' → undefined) and allowEmptyStringAsValue: true ('' → '')"
|
|
231
|
+
toDescribe:
|
|
232
|
+
renderView:
|
|
233
|
+
- type: SelectField
|
|
234
|
+
dataLocation: ~.category
|
|
235
|
+
label: "Category (default behavior):"
|
|
236
|
+
options:
|
|
237
|
+
- label: "Select category..."
|
|
238
|
+
value: ""
|
|
239
|
+
- label: "Technology"
|
|
240
|
+
value: "tech"
|
|
241
|
+
- label: "No category"
|
|
242
|
+
value: "none"
|
|
243
|
+
- type: SelectField
|
|
244
|
+
dataLocation: ~.description
|
|
245
|
+
label: "Description (allowEmptyStringAsValue: true):"
|
|
246
|
+
allowEmptyStringAsValue: true
|
|
247
|
+
options:
|
|
248
|
+
- label: "No description"
|
|
249
|
+
value: ""
|
|
250
|
+
- label: "Brief"
|
|
251
|
+
value: "brief"
|
|
252
|
+
- label: "Detailed"
|
|
253
|
+
value: "detailed"
|
|
254
|
+
- type: div
|
|
255
|
+
attributes:
|
|
256
|
+
style:
|
|
257
|
+
marginTop: "15px"
|
|
258
|
+
padding: "10px"
|
|
259
|
+
backgroundColor: "#f8f9fa"
|
|
260
|
+
borderRadius: "5px"
|
|
261
|
+
content:
|
|
262
|
+
- type: div
|
|
263
|
+
content:
|
|
264
|
+
- type: strong
|
|
265
|
+
content: "Category behavior:"
|
|
266
|
+
- " When you select 'Select category...', the value becomes "
|
|
267
|
+
- type: code
|
|
268
|
+
content: "undefined"
|
|
269
|
+
- " (empty test: "
|
|
270
|
+
- type: span
|
|
271
|
+
content: "✓ isEmpty"
|
|
272
|
+
attributes:
|
|
273
|
+
style:
|
|
274
|
+
color: "green"
|
|
275
|
+
actions:
|
|
276
|
+
- what: hide
|
|
277
|
+
when: ~.category
|
|
278
|
+
isEmpty: "not"
|
|
279
|
+
- type: span
|
|
280
|
+
content: "✗ not empty"
|
|
281
|
+
attributes:
|
|
282
|
+
style:
|
|
283
|
+
color: "red"
|
|
284
|
+
actions:
|
|
285
|
+
- what: hide
|
|
286
|
+
when: ~.category
|
|
287
|
+
isEmpty: true
|
|
288
|
+
- ")"
|
|
289
|
+
- type: div
|
|
290
|
+
content:
|
|
291
|
+
- type: strong
|
|
292
|
+
content: "Description behavior:"
|
|
293
|
+
- " When you select 'No description', the value stays "
|
|
294
|
+
- type: code
|
|
295
|
+
content: '""'
|
|
296
|
+
- " (empty test: "
|
|
297
|
+
- type: span
|
|
298
|
+
content: "✗ not isEmpty"
|
|
299
|
+
attributes:
|
|
300
|
+
style:
|
|
301
|
+
color: "red"
|
|
302
|
+
actions:
|
|
303
|
+
- what: hide
|
|
304
|
+
when: ~.description
|
|
305
|
+
isEmpty: true
|
|
306
|
+
- type: span
|
|
307
|
+
content: "✓ has value"
|
|
308
|
+
attributes:
|
|
309
|
+
style:
|
|
310
|
+
color: "green"
|
|
311
|
+
actions:
|
|
312
|
+
- what: hide
|
|
313
|
+
when: ~.description
|
|
314
|
+
isEmpty: "not"
|
|
315
|
+
- ")"
|
|
316
|
+
data:
|
|
317
|
+
category: ""
|
|
318
|
+
description: ""
|
|
319
|
+
|
|
320
|
+
- type: Markdown
|
|
321
|
+
content: |
|
|
322
|
+
## Limitations
|
|
323
|
+
|
|
324
|
+
### Technical Limitations
|
|
325
|
+
- **Single selection only**: For multiple selection, use CheckBoxField
|
|
326
|
+
- **Value conversion**: Option values are converted to strings for HTML compatibility, then back to original types
|
|
327
|
+
- **Complex values**: Objects cannot be used as option values
|
|
328
|
+
- **No option groups**: `<optgroup>` is not supported
|
|
329
|
+
- **Simple labels only**: Template evaluation in labels is limited to simple string values
|
|
330
|
+
- **No built-in validation**: Beyond basic required field checking
|
|
331
|
+
- **No search/filtering**: Built-in search capabilities are not available
|
|
332
|
+
- **Bug with null values**: Options with `value: null` don't display as selected correctly (implementation issue)
|
|
333
|
+
|
|
334
|
+
### Input Attributes Support
|
|
335
|
+
|
|
336
|
+
The component supports custom attributes via `inputAttributes`:
|
|
337
|
+
|
|
338
|
+
```yaml
|
|
339
|
+
renderView:
|
|
340
|
+
- type: SelectField
|
|
341
|
+
dataLocation: ~.category
|
|
342
|
+
label: "Category:"
|
|
343
|
+
options:
|
|
344
|
+
- label: "Select category"
|
|
345
|
+
value: ""
|
|
346
|
+
- label: "Category A"
|
|
347
|
+
value: "a"
|
|
348
|
+
- label: "Category B"
|
|
349
|
+
value: "b"
|
|
350
|
+
inputAttributes:
|
|
351
|
+
required: true
|
|
352
|
+
style:
|
|
353
|
+
fontSize: "16px"
|
|
354
|
+
|
|
355
|
+
data:
|
|
356
|
+
category: ""
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
templates: {}
|
|
360
|
+
data: {}
|