@ea-lab/reactive-json-docs 2.3.0 → 2.5.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 +1 -1
- package/public/rjbuild/docs/core/element/form/AutocompleteField.md +169 -0
- package/public/rjbuild/docs/core/element/form/AutocompleteField.yaml +225 -0
- package/public/rjbuild/docs/core/element/html/Join.md +108 -0
- package/public/rjbuild/docs/core/element/html/Join.yaml +113 -0
- package/public/rjbuild/docs/core/element/special/Switch.md +102 -0
- package/public/rjbuild/docs/core/element/special/Switch.yaml +98 -1
- package/public/rjbuild/docs/core/reaction/fetchData.md +36 -0
- package/public/rjbuild/docs/core/reaction/fetchData.yaml +12 -0
- package/public/rjbuild/docs/core/reaction/submitData.md +2 -0
- package/public/rjbuild/docs/core/reaction/submitData.yaml +12 -0
package/package.json
CHANGED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# AutocompleteField
|
|
2
|
+
|
|
3
|
+
The `AutocompleteField` component provides a search-as-you-type input that fetches suggestions from a remote API as the user types. It supports single and multiple value selection, and customizable dropdown and selected-item templates.
|
|
4
|
+
|
|
5
|
+
## Basic Syntax
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
- type: AutocompleteField
|
|
9
|
+
dataLocation: ~~.selectedId
|
|
10
|
+
placeholder: "Search…"
|
|
11
|
+
src:
|
|
12
|
+
- "/api/items"
|
|
13
|
+
- param: "search"
|
|
14
|
+
value: "<reactive-json:autocomplete-field:input>"
|
|
15
|
+
- param: "limit"
|
|
16
|
+
value: "10"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Properties
|
|
20
|
+
|
|
21
|
+
- `dataLocation` (string, required): Path where the selected value (or array of values in multiple mode) is stored in the data context.
|
|
22
|
+
- `src` (array, required): URL segments used to build the API endpoint, using the same format as `additionalDataSource.src`. The special token `<reactive-json:autocomplete-field:input>` is replaced by the current search text at request time.
|
|
23
|
+
- `placeholder` (string, optional): Placeholder text for the search input.
|
|
24
|
+
- `minChars` (number, optional): Minimum number of characters required before a search is triggered. Defaults to `2`.
|
|
25
|
+
- `debounce` (number, optional): Delay in milliseconds between the last keystroke and the API request. Defaults to `300`.
|
|
26
|
+
- `multiple` (boolean, optional): Enable multiple selection mode. Selected values are stored as an array. Defaults to `false`.
|
|
27
|
+
- `maxItems` (number, optional): Maximum number of items that can be selected in multiple mode. No limit by default.
|
|
28
|
+
- `clearOnSelect` (boolean, optional): Clear the search input and close the dropdown after an item is selected. Defaults to `true`.
|
|
29
|
+
- `itemTemplate` (rjbuild, optional): Template used to render each item in the dropdown. Has access to item data via `~.` (e.g., `~.label`, `~.value`). Defaults to a `div` displaying `~.label`.
|
|
30
|
+
- `selectedTemplate` (rjbuild, optional): Template used to render the selected item (single mode) or each tag (multiple mode). Has access to item data via `~.`. Defaults to a `span` displaying `~.label`.
|
|
31
|
+
- `defaultFieldValue` (any, optional): Default value used when no data is present at `dataLocation`.
|
|
32
|
+
- `attributes` (object, optional): Attributes applied to the root container `div`. Also receives the CSS class `rj-autocomplete` automatically.
|
|
33
|
+
- `actions` (array, optional): Actions to execute based on component state.
|
|
34
|
+
|
|
35
|
+
## Backend Response Format
|
|
36
|
+
|
|
37
|
+
The endpoint must return a JSON array of objects. Each object must have at minimum a `value` and a `label` key:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
[
|
|
41
|
+
{ "value": 42, "label": "First result" },
|
|
42
|
+
{ "value": 7, "label": "Second result" }
|
|
43
|
+
]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Additional keys can be included and are available in `itemTemplate` / `selectedTemplate` via `~.fieldName`.
|
|
47
|
+
|
|
48
|
+
## The Input Token
|
|
49
|
+
|
|
50
|
+
The string `<reactive-json:autocomplete-field:input>` is a special token that can be placed anywhere in the `src` segments (as a `value`, `param`, or URL segment). It is replaced at request time with the current text in the search field.
|
|
51
|
+
|
|
52
|
+
```yaml
|
|
53
|
+
src:
|
|
54
|
+
- "/api/search"
|
|
55
|
+
- param: "q"
|
|
56
|
+
value: "<reactive-json:autocomplete-field:input>"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## CSS Classes
|
|
60
|
+
|
|
61
|
+
The component uses the following CSS classes for styling:
|
|
62
|
+
|
|
63
|
+
- `.rj-autocomplete` — root container
|
|
64
|
+
- `.rj-autocomplete__input` — the search text input
|
|
65
|
+
- `.rj-autocomplete__dropdown` — the suggestions dropdown
|
|
66
|
+
- `.rj-autocomplete__item` — each suggestion item
|
|
67
|
+
- `.rj-autocomplete__item.is-selected` — a suggestion that is already selected (multiple mode)
|
|
68
|
+
- `.rj-autocomplete__selected` — the selected-item area (single mode)
|
|
69
|
+
- `.rj-autocomplete__clear` — the clear button (single mode)
|
|
70
|
+
- `.rj-autocomplete__tag` — a selected tag (multiple mode)
|
|
71
|
+
- `.rj-autocomplete__tag-remove` — the remove button on a tag
|
|
72
|
+
- `.rj-autocomplete__loading` — the loading indicator
|
|
73
|
+
|
|
74
|
+
## Examples
|
|
75
|
+
|
|
76
|
+
### Single value selection
|
|
77
|
+
|
|
78
|
+
Stores a single selected value. Shows a clear button once an item is selected.
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
renderView:
|
|
82
|
+
- type: AutocompleteField
|
|
83
|
+
dataLocation: ~~.selectedId
|
|
84
|
+
placeholder: "Search…"
|
|
85
|
+
src:
|
|
86
|
+
- "/api/items"
|
|
87
|
+
- param: "search"
|
|
88
|
+
value: "<reactive-json:autocomplete-field:input>"
|
|
89
|
+
- param: "limit"
|
|
90
|
+
value: "10"
|
|
91
|
+
|
|
92
|
+
data:
|
|
93
|
+
selectedId: null
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Multiple selection with a limit
|
|
97
|
+
|
|
98
|
+
Stores up to 3 values as an array. Each selected item is displayed as a removable tag.
|
|
99
|
+
|
|
100
|
+
```yaml
|
|
101
|
+
renderView:
|
|
102
|
+
- type: AutocompleteField
|
|
103
|
+
dataLocation: ~~.selectedIds
|
|
104
|
+
multiple: true
|
|
105
|
+
maxItems: 3
|
|
106
|
+
placeholder: "Add items (max 3)…"
|
|
107
|
+
src:
|
|
108
|
+
- "/api/items"
|
|
109
|
+
- param: "search"
|
|
110
|
+
value: "<reactive-json:autocomplete-field:input>"
|
|
111
|
+
- param: "limit"
|
|
112
|
+
value: "10"
|
|
113
|
+
- type: p
|
|
114
|
+
content:
|
|
115
|
+
- "Selected IDs: "
|
|
116
|
+
- type: Join
|
|
117
|
+
content: ~~.selectedIds
|
|
118
|
+
|
|
119
|
+
data:
|
|
120
|
+
selectedIds: []
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Custom templates
|
|
124
|
+
|
|
125
|
+
Use `itemTemplate` and `selectedTemplate` to render richer content. Both templates have access to all fields returned by the backend via `~.`.
|
|
126
|
+
|
|
127
|
+
```yaml
|
|
128
|
+
- type: AutocompleteField
|
|
129
|
+
dataLocation: ~~.selectedItem
|
|
130
|
+
placeholder: "Search…"
|
|
131
|
+
src:
|
|
132
|
+
- "/api/items"
|
|
133
|
+
- param: "search"
|
|
134
|
+
value: "<reactive-json:autocomplete-field:input>"
|
|
135
|
+
itemTemplate:
|
|
136
|
+
type: div
|
|
137
|
+
content:
|
|
138
|
+
- type: strong
|
|
139
|
+
content: ~.label
|
|
140
|
+
- " (#"
|
|
141
|
+
- ~.value
|
|
142
|
+
- ")"
|
|
143
|
+
selectedTemplate:
|
|
144
|
+
type: span
|
|
145
|
+
content:
|
|
146
|
+
- ~.label
|
|
147
|
+
- " ✓"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Keep search text after selection
|
|
151
|
+
|
|
152
|
+
Set `clearOnSelect: false` to keep the typed text and dropdown open after selecting an item (useful in multiple mode when selecting several items quickly).
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
- type: AutocompleteField
|
|
156
|
+
dataLocation: ~~.selectedIds
|
|
157
|
+
multiple: true
|
|
158
|
+
clearOnSelect: false
|
|
159
|
+
placeholder: "Search…"
|
|
160
|
+
src: [...]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Limitations
|
|
164
|
+
|
|
165
|
+
- Requires an external API endpoint; no built-in static options support.
|
|
166
|
+
- The dropdown only renders while the user is actively typing (results are not re-fetched on re-open without re-typing).
|
|
167
|
+
- In multiple mode, selected items' display data is kept in local React state and may be lost on page reload unless persisted separately.
|
|
168
|
+
- Styling must be provided via external CSS targeting the `.rj-autocomplete*` classes, or via `attributes.style`.
|
|
169
|
+
- No built-in keyboard navigation for the dropdown.
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
renderView:
|
|
2
|
+
- type: Markdown
|
|
3
|
+
content: |
|
|
4
|
+
# AutocompleteField
|
|
5
|
+
|
|
6
|
+
The `AutocompleteField` component provides a search-as-you-type input that fetches suggestions from a remote API as the user types. It supports single and multiple value selection, and customizable dropdown and selected-item templates.
|
|
7
|
+
|
|
8
|
+
- type: Markdown
|
|
9
|
+
content: |
|
|
10
|
+
## Basic Syntax
|
|
11
|
+
|
|
12
|
+
```yaml
|
|
13
|
+
- type: AutocompleteField
|
|
14
|
+
dataLocation: ~~.selectedId
|
|
15
|
+
placeholder: "Search…"
|
|
16
|
+
src:
|
|
17
|
+
- "/api/items"
|
|
18
|
+
- param: "search"
|
|
19
|
+
value: "<reactive-json:autocomplete-field:input>"
|
|
20
|
+
- param: "limit"
|
|
21
|
+
value: "10"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Properties
|
|
25
|
+
|
|
26
|
+
- type: DefinitionList
|
|
27
|
+
content:
|
|
28
|
+
- term:
|
|
29
|
+
code: dataLocation
|
|
30
|
+
after: "(string, required)"
|
|
31
|
+
details: "Path where the selected value (or array of values in multiple mode) is stored in the data context."
|
|
32
|
+
- term:
|
|
33
|
+
code: src
|
|
34
|
+
after: "(array, required)"
|
|
35
|
+
details:
|
|
36
|
+
type: Markdown
|
|
37
|
+
content: "URL segments used to build the API endpoint. The special token `<reactive-json:autocomplete-field:input>` is replaced by the current search text at request time."
|
|
38
|
+
- term:
|
|
39
|
+
code: placeholder
|
|
40
|
+
after: "(string, optional)"
|
|
41
|
+
details: "Placeholder text for the search input."
|
|
42
|
+
- term:
|
|
43
|
+
code: minChars
|
|
44
|
+
after: "(number, optional, default: 2)"
|
|
45
|
+
details: "Minimum number of characters required before a search is triggered."
|
|
46
|
+
- term:
|
|
47
|
+
code: debounce
|
|
48
|
+
after: "(number, optional, default: 300)"
|
|
49
|
+
details: "Delay in milliseconds between the last keystroke and the API request."
|
|
50
|
+
- term:
|
|
51
|
+
code: multiple
|
|
52
|
+
after: "(boolean, optional, default: false)"
|
|
53
|
+
details: "Enable multiple selection mode. Selected values are stored as an array."
|
|
54
|
+
- term:
|
|
55
|
+
code: maxItems
|
|
56
|
+
after: "(number, optional)"
|
|
57
|
+
details: "Maximum number of items selectable in multiple mode. No limit by default."
|
|
58
|
+
- term:
|
|
59
|
+
code: clearOnSelect
|
|
60
|
+
after: "(boolean, optional, default: true)"
|
|
61
|
+
details: "Clear the search input and close the dropdown after an item is selected."
|
|
62
|
+
- term:
|
|
63
|
+
code: itemTemplate
|
|
64
|
+
after: "(rjbuild, optional)"
|
|
65
|
+
details:
|
|
66
|
+
type: Markdown
|
|
67
|
+
content: "Template rendered for each item in the dropdown. Has access to item data via `~.` (e.g., `~.label`, `~.value`). Defaults to a `div` displaying `~.label`."
|
|
68
|
+
- term:
|
|
69
|
+
code: selectedTemplate
|
|
70
|
+
after: "(rjbuild, optional)"
|
|
71
|
+
details:
|
|
72
|
+
type: Markdown
|
|
73
|
+
content: "Template rendered for the selected item (single mode) or each tag (multiple mode). Has access to item data via `~.`. Defaults to a `span` displaying `~.label`."
|
|
74
|
+
- term:
|
|
75
|
+
code: defaultFieldValue
|
|
76
|
+
after: "(any, optional)"
|
|
77
|
+
details: "Default value used when no data is present at dataLocation."
|
|
78
|
+
- term:
|
|
79
|
+
code: attributes
|
|
80
|
+
after: "(object, optional)"
|
|
81
|
+
details:
|
|
82
|
+
type: Markdown
|
|
83
|
+
content: "Attributes applied to the root container `div`. Also receives the CSS class `rj-autocomplete` automatically."
|
|
84
|
+
- term:
|
|
85
|
+
code: actions
|
|
86
|
+
after: "(array, optional)"
|
|
87
|
+
details: "Actions to execute based on component state."
|
|
88
|
+
|
|
89
|
+
- type: Markdown
|
|
90
|
+
content: |
|
|
91
|
+
## Backend Response Format
|
|
92
|
+
|
|
93
|
+
The endpoint must return a JSON array of objects. Each object must have at minimum a `value` and a `label` key:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
[
|
|
97
|
+
{ "value": 42, "label": "First result" },
|
|
98
|
+
{ "value": 7, "label": "Second result" }
|
|
99
|
+
]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Additional keys can be included and are available in `itemTemplate` / `selectedTemplate` via `~.fieldName`.
|
|
103
|
+
|
|
104
|
+
- type: Markdown
|
|
105
|
+
content: |
|
|
106
|
+
## The Input Token
|
|
107
|
+
|
|
108
|
+
The string `<reactive-json:autocomplete-field:input>` is a special token that can be placed anywhere in the `src` segments. It is replaced at request time with the current text in the search field.
|
|
109
|
+
|
|
110
|
+
```yaml
|
|
111
|
+
src:
|
|
112
|
+
- "/api/search"
|
|
113
|
+
- param: "q"
|
|
114
|
+
value: "<reactive-json:autocomplete-field:input>"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- type: Markdown
|
|
118
|
+
content: |
|
|
119
|
+
## CSS Classes
|
|
120
|
+
|
|
121
|
+
The component uses the following CSS classes for styling:
|
|
122
|
+
|
|
123
|
+
| Class | Element |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `.rj-autocomplete` | Root container |
|
|
126
|
+
| `.rj-autocomplete__input` | The search text input |
|
|
127
|
+
| `.rj-autocomplete__dropdown` | The suggestions dropdown |
|
|
128
|
+
| `.rj-autocomplete__item` | Each suggestion item |
|
|
129
|
+
| `.rj-autocomplete__item.is-selected` | A suggestion already selected (multiple mode) |
|
|
130
|
+
| `.rj-autocomplete__selected` | The selected-item area (single mode) |
|
|
131
|
+
| `.rj-autocomplete__clear` | The clear button (single mode) |
|
|
132
|
+
| `.rj-autocomplete__tag` | A selected tag (multiple mode) |
|
|
133
|
+
| `.rj-autocomplete__tag-remove` | The remove button on a tag |
|
|
134
|
+
| `.rj-autocomplete__loading` | The loading indicator |
|
|
135
|
+
|
|
136
|
+
- type: Markdown
|
|
137
|
+
content: |
|
|
138
|
+
## Examples
|
|
139
|
+
|
|
140
|
+
> **Note**: The following examples require a live API endpoint. They show the YAML configuration without a live demo.
|
|
141
|
+
|
|
142
|
+
### Single value selection
|
|
143
|
+
|
|
144
|
+
Stores a single selected value. Shows a clear button once an item is selected.
|
|
145
|
+
|
|
146
|
+
```yaml
|
|
147
|
+
renderView:
|
|
148
|
+
- type: AutocompleteField
|
|
149
|
+
dataLocation: ~~.selectedId
|
|
150
|
+
placeholder: "Search…"
|
|
151
|
+
src:
|
|
152
|
+
- "/api/items"
|
|
153
|
+
- param: "search"
|
|
154
|
+
value: "<reactive-json:autocomplete-field:input>"
|
|
155
|
+
- param: "limit"
|
|
156
|
+
value: "10"
|
|
157
|
+
|
|
158
|
+
data:
|
|
159
|
+
selectedId: null
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Multiple selection with a limit
|
|
163
|
+
|
|
164
|
+
Stores up to 3 values as an array. Each selected item is displayed as a removable tag.
|
|
165
|
+
|
|
166
|
+
```yaml
|
|
167
|
+
renderView:
|
|
168
|
+
- type: AutocompleteField
|
|
169
|
+
dataLocation: ~~.selectedIds
|
|
170
|
+
multiple: true
|
|
171
|
+
maxItems: 3
|
|
172
|
+
placeholder: "Add items (max 3)…"
|
|
173
|
+
src:
|
|
174
|
+
- "/api/items"
|
|
175
|
+
- param: "search"
|
|
176
|
+
value: "<reactive-json:autocomplete-field:input>"
|
|
177
|
+
- param: "limit"
|
|
178
|
+
value: "10"
|
|
179
|
+
- type: p
|
|
180
|
+
content:
|
|
181
|
+
- "Selected IDs: "
|
|
182
|
+
- type: Join
|
|
183
|
+
content: ~~.selectedIds
|
|
184
|
+
|
|
185
|
+
data:
|
|
186
|
+
selectedIds: []
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Custom templates
|
|
190
|
+
|
|
191
|
+
Use `itemTemplate` and `selectedTemplate` to render richer content. Both templates have access to all fields returned by the backend via `~.`.
|
|
192
|
+
|
|
193
|
+
```yaml
|
|
194
|
+
- type: AutocompleteField
|
|
195
|
+
dataLocation: ~~.selectedItem
|
|
196
|
+
placeholder: "Search…"
|
|
197
|
+
src:
|
|
198
|
+
- "/api/items"
|
|
199
|
+
- param: "search"
|
|
200
|
+
value: "<reactive-json:autocomplete-field:input>"
|
|
201
|
+
itemTemplate:
|
|
202
|
+
type: div
|
|
203
|
+
content:
|
|
204
|
+
- type: strong
|
|
205
|
+
content: ~.label
|
|
206
|
+
- " (#"
|
|
207
|
+
- ~.value
|
|
208
|
+
- ")"
|
|
209
|
+
selectedTemplate:
|
|
210
|
+
type: span
|
|
211
|
+
content:
|
|
212
|
+
- ~.label
|
|
213
|
+
- " ✓"
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Limitations
|
|
217
|
+
|
|
218
|
+
- Requires an external API endpoint; no built-in static options support.
|
|
219
|
+
- The dropdown only renders while the user is actively typing (results are not re-fetched on re-open without re-typing).
|
|
220
|
+
- In multiple mode, selected items' display data is kept in local React state and may be lost on page reload unless persisted separately.
|
|
221
|
+
- Styling must be provided via external CSS targeting the `.rj-autocomplete*` classes, or via `attributes.style`.
|
|
222
|
+
- No built-in keyboard navigation for the dropdown.
|
|
223
|
+
|
|
224
|
+
templates: {}
|
|
225
|
+
data: {}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Join
|
|
2
|
+
|
|
3
|
+
The `Join` component concatenates an array of values into a single string, with a configurable separator. It is useful for displaying lists of scalar values (IDs, labels, tags, etc.) inline.
|
|
4
|
+
|
|
5
|
+
## Basic Syntax
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
- type: Join
|
|
9
|
+
content: ~~.myArray
|
|
10
|
+
separator: ", "
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Properties
|
|
14
|
+
|
|
15
|
+
- `content` (array, required): The array to join. Supports template references such as `~~.myArray` or `~.items`. Non-array values are coerced to string and displayed as-is.
|
|
16
|
+
- `separator` (string, optional): The string used between each element. Defaults to `", "`.
|
|
17
|
+
- `attributes` (object, optional): Additional attributes for the root element.
|
|
18
|
+
- `actions` (array, optional): Actions to execute based on component state.
|
|
19
|
+
|
|
20
|
+
## Examples
|
|
21
|
+
|
|
22
|
+
### Basic join with default separator
|
|
23
|
+
|
|
24
|
+
```yaml
|
|
25
|
+
renderView:
|
|
26
|
+
- type: Join
|
|
27
|
+
content: ~~.tags
|
|
28
|
+
|
|
29
|
+
data:
|
|
30
|
+
tags:
|
|
31
|
+
- "react"
|
|
32
|
+
- "yaml"
|
|
33
|
+
- "json"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Renders: `react, yaml, json`
|
|
37
|
+
|
|
38
|
+
### Custom separator
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
renderView:
|
|
42
|
+
- type: Join
|
|
43
|
+
content: ~~.ids
|
|
44
|
+
separator: " | "
|
|
45
|
+
|
|
46
|
+
data:
|
|
47
|
+
ids:
|
|
48
|
+
- 1
|
|
49
|
+
- 2
|
|
50
|
+
- 3
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Renders: `1 | 2 | 3`
|
|
54
|
+
|
|
55
|
+
### Used inside a sentence
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
renderView:
|
|
59
|
+
- type: p
|
|
60
|
+
content:
|
|
61
|
+
- "Selected items: "
|
|
62
|
+
- type: Join
|
|
63
|
+
content: ~~.selectedIds
|
|
64
|
+
separator: ", "
|
|
65
|
+
|
|
66
|
+
data:
|
|
67
|
+
selectedIds:
|
|
68
|
+
- 42
|
|
69
|
+
- 7
|
|
70
|
+
- 15
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### With template-scoped data
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
renderView:
|
|
77
|
+
- type: Switch
|
|
78
|
+
content: ~~.users
|
|
79
|
+
singleOption:
|
|
80
|
+
load: userRow
|
|
81
|
+
|
|
82
|
+
templates:
|
|
83
|
+
userRow:
|
|
84
|
+
type: div
|
|
85
|
+
content:
|
|
86
|
+
- "Roles: "
|
|
87
|
+
- type: Join
|
|
88
|
+
content: ~.roles
|
|
89
|
+
separator: " / "
|
|
90
|
+
|
|
91
|
+
data:
|
|
92
|
+
users:
|
|
93
|
+
- name: "Alice"
|
|
94
|
+
roles: ["admin", "editor"]
|
|
95
|
+
- name: "Bob"
|
|
96
|
+
roles: ["viewer"]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Notes
|
|
100
|
+
|
|
101
|
+
- If `content` evaluates to a non-array value, it is rendered as a plain string (no separator applied).
|
|
102
|
+
- Null or undefined `content` renders nothing.
|
|
103
|
+
- Array elements are joined using JavaScript's native `.join()`, so objects will render as `[object Object]`. Use this component with arrays of primitives (strings, numbers).
|
|
104
|
+
|
|
105
|
+
## Limitations
|
|
106
|
+
|
|
107
|
+
- No support for rendering rich content (HTML, components) between items — use `Switch` with a template for that.
|
|
108
|
+
- No per-item formatting; all elements are joined as plain strings.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
renderView:
|
|
2
|
+
- type: Markdown
|
|
3
|
+
content: |
|
|
4
|
+
# Join
|
|
5
|
+
|
|
6
|
+
The `Join` component concatenates an array of values into a single string, with a configurable separator. It is useful for displaying lists of scalar values (IDs, labels, tags, etc.) inline.
|
|
7
|
+
|
|
8
|
+
- type: Markdown
|
|
9
|
+
content: |
|
|
10
|
+
## Basic Syntax
|
|
11
|
+
|
|
12
|
+
```yaml
|
|
13
|
+
- type: Join
|
|
14
|
+
content: ~~.myArray
|
|
15
|
+
separator: ", "
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Properties
|
|
19
|
+
|
|
20
|
+
- type: DefinitionList
|
|
21
|
+
content:
|
|
22
|
+
- term:
|
|
23
|
+
code: content
|
|
24
|
+
after: "(array, required)"
|
|
25
|
+
details: "The array to join. Supports template references such as ~~.myArray or ~.items. Non-array values are coerced to string and displayed as-is."
|
|
26
|
+
- term:
|
|
27
|
+
code: separator
|
|
28
|
+
after: '(string, optional, default: ", ")'
|
|
29
|
+
details: "The string used between each element."
|
|
30
|
+
- term:
|
|
31
|
+
code: attributes
|
|
32
|
+
after: "(object, optional)"
|
|
33
|
+
details: "Additional attributes for the root element."
|
|
34
|
+
- term:
|
|
35
|
+
code: actions
|
|
36
|
+
after: "(array, optional)"
|
|
37
|
+
details: "Actions to execute based on component state."
|
|
38
|
+
|
|
39
|
+
- type: RjBuildDescriber
|
|
40
|
+
title: "Basic join with default separator"
|
|
41
|
+
description: "Join an array of strings with the default comma-space separator."
|
|
42
|
+
toDescribe:
|
|
43
|
+
renderView:
|
|
44
|
+
- type: p
|
|
45
|
+
content:
|
|
46
|
+
- "Tags: "
|
|
47
|
+
- type: Join
|
|
48
|
+
content: ~~.tags
|
|
49
|
+
data:
|
|
50
|
+
tags:
|
|
51
|
+
- "react"
|
|
52
|
+
- "yaml"
|
|
53
|
+
- "json"
|
|
54
|
+
|
|
55
|
+
- type: RjBuildDescriber
|
|
56
|
+
title: "Custom separator"
|
|
57
|
+
description: "Use a pipe separator to display a list of IDs."
|
|
58
|
+
toDescribe:
|
|
59
|
+
renderView:
|
|
60
|
+
- type: p
|
|
61
|
+
content:
|
|
62
|
+
- "IDs: "
|
|
63
|
+
- type: Join
|
|
64
|
+
content: ~~.ids
|
|
65
|
+
separator: " | "
|
|
66
|
+
- type: div
|
|
67
|
+
attributes:
|
|
68
|
+
class: "mt-5 p-2.5 rounded border border-gray-300 dark:border-gray-600"
|
|
69
|
+
content:
|
|
70
|
+
- type: strong
|
|
71
|
+
content: "Raw array: "
|
|
72
|
+
- type: Code
|
|
73
|
+
content: ~~.ids
|
|
74
|
+
data:
|
|
75
|
+
ids:
|
|
76
|
+
- 42
|
|
77
|
+
- 7
|
|
78
|
+
- 15
|
|
79
|
+
|
|
80
|
+
- type: RjBuildDescriber
|
|
81
|
+
title: "Inside a sentence"
|
|
82
|
+
description: "Embed a Join inside a paragraph to display selected values inline."
|
|
83
|
+
toDescribe:
|
|
84
|
+
renderView:
|
|
85
|
+
- type: p
|
|
86
|
+
content:
|
|
87
|
+
- "Selected items: "
|
|
88
|
+
- type: strong
|
|
89
|
+
content:
|
|
90
|
+
type: Join
|
|
91
|
+
content: ~~.selectedIds
|
|
92
|
+
separator: ", "
|
|
93
|
+
data:
|
|
94
|
+
selectedIds:
|
|
95
|
+
- 42
|
|
96
|
+
- 7
|
|
97
|
+
- 15
|
|
98
|
+
|
|
99
|
+
- type: Markdown
|
|
100
|
+
content: |
|
|
101
|
+
## Notes
|
|
102
|
+
|
|
103
|
+
- If `content` evaluates to a non-array value, it is rendered as a plain string (no separator applied).
|
|
104
|
+
- Null or undefined `content` renders nothing.
|
|
105
|
+
- Array elements are joined using JavaScript's native `.join()`, so objects will render as `[object Object]`. Use this component with arrays of primitives (strings, numbers).
|
|
106
|
+
|
|
107
|
+
## Limitations
|
|
108
|
+
|
|
109
|
+
- No support for rendering rich content (HTML, components) between items — use `Switch` with a template for that.
|
|
110
|
+
- No per-item formatting; all elements are joined as plain strings.
|
|
111
|
+
|
|
112
|
+
templates: {}
|
|
113
|
+
data: {}
|
|
@@ -257,4 +257,106 @@ data:
|
|
|
257
257
|
- name: "string2"
|
|
258
258
|
- name: "string3"
|
|
259
259
|
```
|
|
260
|
+
|
|
261
|
+
## Caveats — common pitfalls that fail silently
|
|
262
|
+
|
|
263
|
+
These two patterns *look* correct, type-check, throw no error, and produce
|
|
264
|
+
empty output. They're easy to miss and have cost real debugging time.
|
|
265
|
+
|
|
266
|
+
### Caveat 1 — `content` must be a template reference, not an inline array
|
|
267
|
+
|
|
268
|
+
Switch iterates whatever you put in `content`, but the per-item template
|
|
269
|
+
context (i.e. what `~.field` resolves against) is fetched from the **reactive
|
|
270
|
+
data store** at the iterated path. An inline array literal in `content` is
|
|
271
|
+
never written to the store, so each iteration's `templateData` ends up
|
|
272
|
+
`undefined` and every `~.field` resolves to nothing.
|
|
273
|
+
|
|
274
|
+
```yaml
|
|
275
|
+
# ❌ Silent failure — items render but ~.label is undefined
|
|
276
|
+
renderView:
|
|
277
|
+
- type: Switch
|
|
278
|
+
content:
|
|
279
|
+
- {label: "Home"}
|
|
280
|
+
- {label: "About"}
|
|
281
|
+
singleOption:
|
|
282
|
+
load: navLink
|
|
283
|
+
|
|
284
|
+
templates:
|
|
285
|
+
navLink:
|
|
286
|
+
type: a
|
|
287
|
+
content: ~.label
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
```yaml
|
|
291
|
+
# ✅ Works — content points into the store
|
|
292
|
+
data:
|
|
293
|
+
navItems:
|
|
294
|
+
- {label: "Home"}
|
|
295
|
+
- {label: "About"}
|
|
296
|
+
|
|
297
|
+
renderView:
|
|
298
|
+
- type: Switch
|
|
299
|
+
content: ~~.navItems
|
|
300
|
+
singleOption:
|
|
301
|
+
load: navLink
|
|
302
|
+
|
|
303
|
+
templates:
|
|
304
|
+
navLink:
|
|
305
|
+
type: a
|
|
306
|
+
content: ~.label
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Rule of thumb:** `Switch.content` is always a path reference (`~~.foo` for
|
|
310
|
+
global, `~.foo` for local), never a literal. If your iteration data is
|
|
311
|
+
"constant" from a page-data perspective, that's fine — just put it in the
|
|
312
|
+
YAML's `data:` section. It will still be reachable via `~~.foo`.
|
|
313
|
+
|
|
314
|
+
### Caveat 2 — `singleOption` must use `load:`, not an inline template
|
|
315
|
+
|
|
316
|
+
The per-item `TemplateContext` that makes `~.field` resolve against the
|
|
317
|
+
current item is set up by the `load` branch of the `View` engine. Writing
|
|
318
|
+
`singleOption` as an inline `{type: ..., content: ...}` skips that setup —
|
|
319
|
+
the iteration happens, but `~.field` inside the inline template resolves
|
|
320
|
+
against the **outer** context (whatever was active where the Switch sits),
|
|
321
|
+
not the per-item context.
|
|
322
|
+
|
|
323
|
+
```yaml
|
|
324
|
+
# ❌ ~.name resolves against the outer context, not each user
|
|
325
|
+
renderView:
|
|
326
|
+
- type: Switch
|
|
327
|
+
content: ~~.users
|
|
328
|
+
singleOption:
|
|
329
|
+
type: div
|
|
330
|
+
content: ~.name
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
```yaml
|
|
334
|
+
# ✅ Per-item context is correctly pushed
|
|
335
|
+
renderView:
|
|
336
|
+
- type: Switch
|
|
337
|
+
content: ~~.users
|
|
338
|
+
singleOption:
|
|
339
|
+
load: userCard
|
|
340
|
+
|
|
341
|
+
templates:
|
|
342
|
+
userCard:
|
|
343
|
+
type: div
|
|
344
|
+
content: ~.name
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**Rule of thumb:** treat `singleOption` and `options.<key>` as
|
|
348
|
+
`{load: <templateName>}` only. If you find yourself writing an inline
|
|
349
|
+
template there, factor it into `templates:` and reference it.
|
|
350
|
+
|
|
351
|
+
### Debugging checklist when an iteration renders empty
|
|
352
|
+
|
|
353
|
+
1. Is `Switch.content` a `~~.path` (not an inline literal)?
|
|
354
|
+
2. Does that path exist in the store? (Defaults in `data:` are merged in
|
|
355
|
+
unless the parent mounts with a `dataOverride` that omits the field.)
|
|
356
|
+
3. Is `singleOption` / `options.<key>` a `{load: <name>}`?
|
|
357
|
+
4. Is each item in the data an object (not a primitive)? Switch silently
|
|
358
|
+
skips non-object entries.
|
|
359
|
+
5. Is the `usePagination` hook available? Switch returns `null` if not —
|
|
360
|
+
normally guaranteed by `ReactiveJsonRoot` auto-merging
|
|
361
|
+
`coreComponentsPlugin`, but worth checking on a stripped-down root.
|
|
260
362
|
|
|
@@ -118,12 +118,109 @@ renderView:
|
|
|
118
118
|
|
|
119
119
|
# ✅ This will work:
|
|
120
120
|
data:
|
|
121
|
-
items:
|
|
121
|
+
items:
|
|
122
122
|
- name: "string1"
|
|
123
123
|
- name: "string2"
|
|
124
124
|
- name: "string3"
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
+
## Caveats — common pitfalls that fail silently
|
|
128
|
+
|
|
129
|
+
Two patterns *look* correct, throw no error, and produce empty output.
|
|
130
|
+
They've cost real debugging time.
|
|
131
|
+
|
|
132
|
+
### Caveat 1 — `content` must be a template reference, not an inline array
|
|
133
|
+
|
|
134
|
+
Switch iterates whatever you put in `content`, but the per-item
|
|
135
|
+
template context is fetched from the **reactive data store** at the
|
|
136
|
+
iterated path. An inline array literal in `content` is never written
|
|
137
|
+
to the store, so each iteration's `templateData` ends up `undefined`
|
|
138
|
+
and every `~.field` resolves to nothing.
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
# ❌ Silent failure — items render but ~.label is undefined
|
|
142
|
+
renderView:
|
|
143
|
+
- type: Switch
|
|
144
|
+
content:
|
|
145
|
+
- {label: "Home"}
|
|
146
|
+
- {label: "About"}
|
|
147
|
+
singleOption:
|
|
148
|
+
load: navLink
|
|
149
|
+
templates:
|
|
150
|
+
navLink:
|
|
151
|
+
type: a
|
|
152
|
+
content: ~.label
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```yaml
|
|
156
|
+
# ✅ Works — content points into the store
|
|
157
|
+
data:
|
|
158
|
+
navItems:
|
|
159
|
+
- {label: "Home"}
|
|
160
|
+
- {label: "About"}
|
|
161
|
+
renderView:
|
|
162
|
+
- type: Switch
|
|
163
|
+
content: ~~.navItems
|
|
164
|
+
singleOption:
|
|
165
|
+
load: navLink
|
|
166
|
+
templates:
|
|
167
|
+
navLink:
|
|
168
|
+
type: a
|
|
169
|
+
content: ~.label
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**Rule of thumb:** `Switch.content` is always a path reference
|
|
173
|
+
(`~~.foo` for global, `~.foo` for local), never a literal. Constant
|
|
174
|
+
iteration data belongs in the YAML's `data:` section.
|
|
175
|
+
|
|
176
|
+
### Caveat 2 — `singleOption` must use `load:`, not an inline template
|
|
177
|
+
|
|
178
|
+
The per-item TemplateContext that makes `~.field` resolve against the
|
|
179
|
+
current item is set up by the `load` branch of the View engine.
|
|
180
|
+
Writing `singleOption` as an inline `{type: ..., content: ...}` skips
|
|
181
|
+
that setup — the iteration happens, but `~.field` resolves against
|
|
182
|
+
the **outer** context, not the per-item context.
|
|
183
|
+
|
|
184
|
+
```yaml
|
|
185
|
+
# ❌ ~.name resolves against the outer context
|
|
186
|
+
renderView:
|
|
187
|
+
- type: Switch
|
|
188
|
+
content: ~~.users
|
|
189
|
+
singleOption:
|
|
190
|
+
type: div
|
|
191
|
+
content: ~.name
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
```yaml
|
|
195
|
+
# ✅ Per-item context is correctly pushed
|
|
196
|
+
renderView:
|
|
197
|
+
- type: Switch
|
|
198
|
+
content: ~~.users
|
|
199
|
+
singleOption:
|
|
200
|
+
load: userCard
|
|
201
|
+
templates:
|
|
202
|
+
userCard:
|
|
203
|
+
type: div
|
|
204
|
+
content: ~.name
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**Rule of thumb:** treat `singleOption` and `options.<key>` as
|
|
208
|
+
`{load: <templateName>}` only. Factor inline templates into
|
|
209
|
+
`templates:`.
|
|
210
|
+
|
|
211
|
+
### Debugging checklist when an iteration renders empty
|
|
212
|
+
|
|
213
|
+
1. Is `Switch.content` a `~~.path` (not an inline literal)?
|
|
214
|
+
2. Does that path exist in the store? (Defaults in `data:` are merged
|
|
215
|
+
in unless the parent mounts with a `dataOverride` that omits the
|
|
216
|
+
field.)
|
|
217
|
+
3. Is `singleOption` / `options.<key>` a `{load: <name>}`?
|
|
218
|
+
4. Is each item in the data an object (not a primitive)? Switch
|
|
219
|
+
silently skips non-object entries.
|
|
220
|
+
5. Is the `usePagination` hook available? Switch returns `null` if
|
|
221
|
+
not — normally guaranteed by `ReactiveJsonRoot` auto-merging
|
|
222
|
+
`coreComponentsPlugin`.
|
|
223
|
+
|
|
127
224
|
- type: RjBuildDescriber
|
|
128
225
|
title: "Simple usage with `singleOption` (no pagination)"
|
|
129
226
|
description: |
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
## Properties
|
|
11
11
|
- `httpMethod` (string, optional): The HTTP method to use (default: "get"). Supports: get, post, put, patch, delete, etc.
|
|
12
12
|
- `refreshAppOnResponse` (boolean, optional): If true (default), the response will update the application. If false, the response is ignored (webhook mode).
|
|
13
|
+
- `allowConcurrent` (boolean, optional): When true, allows concurrent requests (bypasses the global lock). Default: false. Implicitly true when `requestKey` is set.
|
|
14
|
+
- `requestKey` (string, optional): Identifier used to group requests that should cancel each other. When set, firing a new request with the same key aborts the previous one client-side (via AbortController). Different keys are independent. Bypasses the global lock automatically. See [Concurrency control](#concurrency-control--requestkey) below.
|
|
13
15
|
- `updateOnlyData` (boolean, optional): When true and `refreshAppOnResponse` is true, only updates the data section instead of replacing the entire RjBuild. Preserves templates and renderView. Default: false.
|
|
14
16
|
- `updateDataAtLocation` (string, optional): When `updateOnlyData` is true, specifies where to place the response data using template path syntax (e.g., "~~.userProfile", "~.config.settings"). If not specified, replaces the entire data object.
|
|
15
17
|
- `url` (string, required): The URL to call (must be a static string, dynamic URLs are not supported)
|
|
@@ -54,6 +56,40 @@ The response event provides access to the complete server response through `<rea
|
|
|
54
56
|
|
|
55
57
|
> **⚠️ Important:** When using `updateOnlyData: true`, the server response must contain **data only**, not a complete RjBuild structure. The response should be the raw data object, not wrapped in `{data: {...}, renderView: [...], templates: {...}}`.
|
|
56
58
|
|
|
59
|
+
## Concurrency control — `requestKey`
|
|
60
|
+
|
|
61
|
+
By default, `fetchData` and `submitData` share a **global lock** at the document level: only one HTTP request can be active across the whole app at any time. A second call fired while the first is in flight is **silently dropped**. This is safe for most cases but bites when a user clicks rapidly through buckets in a filter UI, or hits two save buttons quickly — the second request's siblings (e.g. `setData` updating local UI state) still run, but the request itself never goes out, leaving UI and data out of sync.
|
|
62
|
+
|
|
63
|
+
`requestKey` opts the call into per-key cancel-on-new semantics. The library keeps a registry of in-flight requests keyed by `requestKey` and, on each new call:
|
|
64
|
+
|
|
65
|
+
1. Aborts the previous request with the same key (via `AbortController` on the underlying axios call).
|
|
66
|
+
2. Replaces the registry entry with the new request.
|
|
67
|
+
3. Lets the new request proceed.
|
|
68
|
+
|
|
69
|
+
Aborted requests are silently swallowed: their `.catch` doesn't log an error, and their `.finally` skips the `response` event dispatch. The successor will fire its own `response` event normally.
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
# Rapid clicks on bucket A then B share `facet-refresh` — A's request
|
|
73
|
+
# is aborted as soon as B is fired, so only B's response lands in the
|
|
74
|
+
# store. Without requestKey, B would silently no-op (global lock held
|
|
75
|
+
# by A) and the UI would diverge from the data.
|
|
76
|
+
actions:
|
|
77
|
+
- what: setData
|
|
78
|
+
on: click
|
|
79
|
+
path: ~~.selectedFilter
|
|
80
|
+
value: ~.key
|
|
81
|
+
- what: fetchData
|
|
82
|
+
on: click
|
|
83
|
+
requestKey: facet-refresh
|
|
84
|
+
url: ~~.endpoint
|
|
85
|
+
updateOnlyData: true
|
|
86
|
+
updateDataAtLocation: ~~.result
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Different keys are independent: edit modals on multiple rows can each have their own `requestKey: 'save-row-42'` etc. and save simultaneously without interfering.
|
|
90
|
+
|
|
91
|
+
`requestKey` implies `allowConcurrent: true` — the global lock is bypassed automatically when a key is provided, since per-key cancel-on-new already guarantees single-flight within the key.
|
|
92
|
+
|
|
57
93
|
## Examples
|
|
58
94
|
|
|
59
95
|
### Data Loading with GET (Default)
|
|
@@ -26,6 +26,18 @@ renderView:
|
|
|
26
26
|
details:
|
|
27
27
|
type: Markdown
|
|
28
28
|
content: "If true (default), the response will update the application. If false, the response is ignored (webhook mode)"
|
|
29
|
+
- term:
|
|
30
|
+
code: allowConcurrent
|
|
31
|
+
after: "(boolean, optional)"
|
|
32
|
+
details:
|
|
33
|
+
type: Markdown
|
|
34
|
+
content: "When true, allows concurrent requests (bypasses the global lock). Default: false. Implicitly true when `requestKey` is set."
|
|
35
|
+
- term:
|
|
36
|
+
code: requestKey
|
|
37
|
+
after: "(string, optional)"
|
|
38
|
+
details:
|
|
39
|
+
type: Markdown
|
|
40
|
+
content: "Identifier used to group requests that should cancel each other. When set, firing a new request with the same key aborts the previous one client-side (via AbortController). Different keys are independent. Bypasses the global lock automatically."
|
|
29
41
|
- term:
|
|
30
42
|
code: updateDataAtLocation
|
|
31
43
|
after: "(string, optional)"
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
- `httpMethod` (string, optional): The HTTP method to use (default: "post")
|
|
12
12
|
- `data` (object, optional): The data to send. If not specified, data is sent in an object with the structure `{ data: globalDataContext.templateData }`. If `__state` exists in the context, it is automatically added.
|
|
13
13
|
- `refreshAppOnResponse` (boolean, optional): If true (default), reloads the application with the server response. If false, the response is ignored and **no change is made to the application's state or display** (just like `fetchData`).
|
|
14
|
+
- `allowConcurrent` (boolean, optional): When true, allows concurrent requests (bypasses the global lock). Default: false. Implicitly true when `requestKey` is set.
|
|
15
|
+
- `requestKey` (string, optional): Identifier used to group requests that should cancel each other. When set, firing a new submission with the same key aborts the previous one client-side (via AbortController). Different keys are independent. Bypasses the global lock automatically. See the [Concurrency control section in `fetchData`](fetchData.md#concurrency-control--requestkey) — the semantics are identical.
|
|
14
16
|
- `submitSilently` (boolean, optional): If true, doesn't apply visual disabling styles during submission
|
|
15
17
|
- `updateOnlyData` (boolean, optional): When true and `refreshAppOnResponse` is true, only updates the data section instead of replacing the entire RjBuild. Preserves templates and renderView. Default: false.
|
|
16
18
|
- `updateDataAtLocation` (string, optional): When `updateOnlyData` is true, specifies where to place the response data using template path syntax (e.g., "~~.userProfile", "~.config.settings"). If not specified, replaces the entire data object.
|
|
@@ -35,6 +35,18 @@ renderView:
|
|
|
35
35
|
details:
|
|
36
36
|
type: Markdown
|
|
37
37
|
content: "If true (default), reloads the application with the server response. If false, the response is ignored and **no change is made to the application's state or display** (just like `fetchData`)"
|
|
38
|
+
- term:
|
|
39
|
+
code: allowConcurrent
|
|
40
|
+
after: "(boolean, optional)"
|
|
41
|
+
details:
|
|
42
|
+
type: Markdown
|
|
43
|
+
content: "When true, allows concurrent requests (bypasses the global lock). Default: false. Implicitly true when `requestKey` is set."
|
|
44
|
+
- term:
|
|
45
|
+
code: requestKey
|
|
46
|
+
after: "(string, optional)"
|
|
47
|
+
details:
|
|
48
|
+
type: Markdown
|
|
49
|
+
content: "Identifier used to group requests that should cancel each other. When set, firing a new submission with the same key aborts the previous one client-side (via AbortController). Different keys are independent. Bypasses the global lock automatically. See [Concurrency control in `fetchData`](fetchData) — same semantics."
|
|
38
50
|
- term:
|
|
39
51
|
code: submitSilently
|
|
40
52
|
after: "(boolean, optional)"
|