@iress-oss/ids-mcp-server 5.15.0 → 6.0.0-alpha.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/generated/docs/components-alert-docs.md +579 -7
- package/generated/docs/components-autocomplete-docs.md +694 -15
- package/generated/docs/components-autocomplete-recipes-docs.md +1 -1
- package/generated/docs/components-badge-docs.md +442 -59
- package/generated/docs/components-button-docs.md +1150 -70
- package/generated/docs/components-buttongroup-docs.md +441 -3
- package/generated/docs/components-card-docs.md +487 -37
- package/generated/docs/components-checkbox-docs.md +506 -5
- package/generated/docs/components-checkboxgroup-docs.md +586 -191
- package/generated/docs/components-checkboxgroup-recipes-docs.md +3 -3
- package/generated/docs/components-col-docs.md +451 -36
- package/generated/docs/components-container-docs.md +32 -0
- package/generated/docs/components-divider-docs.md +427 -27
- package/generated/docs/components-expander-docs.md +487 -108
- package/generated/docs/components-field-docs.md +1400 -68
- package/generated/docs/components-filter-docs.md +268 -55
- package/generated/docs/components-hide-docs.md +447 -10
- package/generated/docs/components-icon-docs.md +522 -259
- package/generated/docs/components-image-docs.md +493 -0
- package/generated/docs/components-inline-docs.md +1179 -44
- package/generated/docs/components-input-docs.md +544 -12
- package/generated/docs/components-input-recipes-docs.md +4 -4
- package/generated/docs/components-inputcurrency-docs.md +532 -0
- package/generated/docs/components-inputcurrency-recipes-docs.md +4 -5
- package/generated/docs/components-introduction-docs.md +450 -0
- package/generated/docs/components-label-docs.md +454 -27
- package/generated/docs/components-link-docs.md +586 -0
- package/generated/docs/components-menu-docs.md +531 -89
- package/generated/docs/components-menu-menuitem-docs.md +556 -10
- package/generated/docs/components-modal-docs.md +814 -55
- package/generated/docs/components-panel-docs.md +418 -198
- package/generated/docs/components-placeholder-docs.md +420 -1
- package/generated/docs/components-popover-docs.md +1097 -32
- package/generated/docs/components-popover-recipes-docs.md +39 -73
- package/generated/docs/components-progress-docs.md +464 -0
- package/generated/docs/components-provider-docs.md +57 -2
- package/generated/docs/components-radio-docs.md +460 -4
- package/generated/docs/components-radiogroup-docs.md +586 -116
- package/generated/docs/components-readonly-docs.md +450 -4
- package/generated/docs/components-richselect-docs.md +4660 -1257
- package/generated/docs/components-row-docs.md +2065 -588
- package/generated/docs/components-select-docs.md +489 -5
- package/generated/docs/components-skeleton-docs.md +399 -16
- package/generated/docs/components-skeleton-recipes-docs.md +7 -7
- package/generated/docs/components-skiplink-docs.md +548 -27
- package/generated/docs/components-slideout-docs.md +648 -150
- package/generated/docs/components-slider-docs.md +515 -33
- package/generated/docs/components-spinner-docs.md +393 -2
- package/generated/docs/components-stack-docs.md +732 -74
- package/generated/docs/components-table-ag-grid-docs.md +497 -127
- package/generated/docs/components-table-docs.md +1049 -27
- package/generated/docs/components-tabset-docs.md +454 -27
- package/generated/docs/components-tabset-tab-docs.md +464 -0
- package/generated/docs/components-tag-docs.md +452 -19
- package/generated/docs/components-text-docs.md +322 -131
- package/generated/docs/components-toaster-docs.md +463 -53
- package/generated/docs/components-toggle-docs.md +476 -20
- package/generated/docs/components-tooltip-docs.md +443 -7
- package/generated/docs/components-validationmessage-docs.md +933 -13
- package/generated/docs/extensions-editor-docs.md +906 -13
- package/generated/docs/extensions-editor-recipes-docs.md +51 -1
- package/generated/docs/foundations-accessibility-docs.md +1 -23
- package/generated/docs/foundations-grid-docs.md +74 -0
- package/generated/docs/foundations-introduction-docs.md +6 -4
- package/generated/docs/foundations-responsive-breakpoints-docs.md +193 -0
- package/generated/docs/foundations-tokens-colour-docs.md +564 -0
- package/generated/docs/foundations-tokens-elevation-docs.md +155 -0
- package/generated/docs/foundations-tokens-introduction-docs.md +190 -0
- package/generated/docs/foundations-tokens-radius-docs.md +71 -0
- package/generated/docs/foundations-tokens-spacing-docs.md +89 -0
- package/generated/docs/foundations-tokens-typography-docs.md +322 -0
- package/generated/docs/foundations-z-index-stacking-docs.md +31 -0
- package/generated/docs/guidelines.md +1537 -295
- package/generated/docs/introduction-docs.md +65 -21
- package/generated/docs/news-version-6-docs.md +93 -0
- package/generated/docs/patterns-form-docs.md +3902 -0
- package/generated/docs/patterns-form-recipes-docs.md +1370 -0
- package/generated/docs/patterns-introduction-docs.md +24 -0
- package/generated/docs/patterns-loading-docs.md +2940 -201
- package/generated/docs/resources-introduction-docs.md +38 -0
- package/generated/docs/resources-mcp-server-docs.md +27 -0
- package/generated/docs/styling-props-colour-docs.md +172 -0
- package/generated/docs/styling-props-elevation-docs.md +88 -0
- package/generated/docs/styling-props-radius-docs.md +86 -0
- package/generated/docs/styling-props-reference-docs.md +160 -0
- package/generated/docs/styling-props-screen-readers-docs.md +71 -0
- package/generated/docs/styling-props-sizing-docs.md +627 -0
- package/generated/docs/styling-props-spacing-docs.md +2282 -0
- package/generated/docs/styling-props-typography-docs.md +121 -0
- package/generated/docs/themes-available-themes-docs.md +29 -29
- package/generated/docs/themes-introduction-docs.md +1 -1
- package/package.json +3 -22
- package/generated/docs/components-button-recipes-docs.md +0 -76
- package/generated/docs/components-card-recipes-docs.md +0 -89
- package/generated/docs/components-combobox-docs.md +0 -1016
- package/generated/docs/components-form-docs.md +0 -2410
- package/generated/docs/components-form-recipes-docs.md +0 -886
- package/generated/docs/components-navbar-docs.md +0 -291
- package/generated/docs/components-navbar-recipes-docs.md +0 -413
- package/generated/docs/components-toaster-toast-docs.md +0 -157
- package/generated/docs/foundations-colours-docs.md +0 -257
- package/generated/docs/foundations-typography-docs.md +0 -191
- package/generated/docs/resources-changelog-docs.md +0 -6
- package/generated/docs/themes-tokens-docs.md +0 -1200
|
@@ -1,886 +0,0 @@
|
|
|
1
|
-
[](#recipes)Recipes
|
|
2
|
-
===================
|
|
3
|
-
|
|
4
|
-
[](#with-readonly-data)With readonly data
|
|
5
|
-
-----------------------------------------
|
|
6
|
-
|
|
7
|
-
You can use `IressForm` with readonly data by setting the `readonly` prop to `true` on controlled elements. This will disable those form controls, but will include the values in the form submission.
|
|
8
|
-
|
|
9
|
-
Please take note of the following when displaying read only data.
|
|
10
|
-
|
|
11
|
-
* It is best to keep readonly data in a separate section of the form, to further avoid confusion with editable fields.
|
|
12
|
-
|
|
13
|
-
User Details
|
|
14
|
-
------------
|
|
15
|
-
|
|
16
|
-
First Name
|
|
17
|
-
|
|
18
|
-
Leia
|
|
19
|
-
|
|
20
|
-
Last Name
|
|
21
|
-
|
|
22
|
-
Skywalker
|
|
23
|
-
|
|
24
|
-
* * *
|
|
25
|
-
|
|
26
|
-
Email
|
|
27
|
-
|
|
28
|
-
Submit
|
|
29
|
-
|
|
30
|
-
Hide code
|
|
31
|
-
|
|
32
|
-
\[data-radix-scroll-area-viewport\] { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; } \[data-radix-scroll-area-viewport\]::-webkit-scrollbar { display: none; } :where(\[data-radix-scroll-area-viewport\]) { display: flex; flex-direction: column; align-items: stretch; } :where(\[data-radix-scroll-area-content\]) { flex-grow: 1; }
|
|
33
|
-
|
|
34
|
-
export const WithReadonlyDataForm \= () \=> {
|
|
35
|
-
const \[values, setValues\] \= useState<FieldValues\>({
|
|
36
|
-
firstName: 'Leia',
|
|
37
|
-
lastName: 'Skywalker',
|
|
38
|
-
email: 'leia.skywalker@iress.com',
|
|
39
|
-
});
|
|
40
|
-
const \[preview, setPreview\] \= useState(false);
|
|
41
|
-
return (
|
|
42
|
-
<\>
|
|
43
|
-
<IressForm
|
|
44
|
-
onSubmit\={(data) \=> {
|
|
45
|
-
setValues(data);
|
|
46
|
-
setPreview(true);
|
|
47
|
-
}}
|
|
48
|
-
values\={values}
|
|
49
|
-
\>
|
|
50
|
-
<IressContainer\>
|
|
51
|
-
<IressText element\="h2"\>User Details</IressText\>
|
|
52
|
-
<IressStack gutter\="md"\>
|
|
53
|
-
<IressRow gutter\="md"\>
|
|
54
|
-
<IressCol\>
|
|
55
|
-
<IressFormField
|
|
56
|
-
name\="firstName"
|
|
57
|
-
label\="First Name"
|
|
58
|
-
render\={(controlledProps) \=> (
|
|
59
|
-
<IressInput {...controlledProps} readOnly />
|
|
60
|
-
)}
|
|
61
|
-
/>
|
|
62
|
-
</IressCol\>
|
|
63
|
-
<IressCol\>
|
|
64
|
-
<IressFormField
|
|
65
|
-
name\="lastName"
|
|
66
|
-
label\="Last Name"
|
|
67
|
-
render\={(controlledProps) \=> (
|
|
68
|
-
<IressInput {...controlledProps} readOnly />
|
|
69
|
-
)}
|
|
70
|
-
/>
|
|
71
|
-
</IressCol\>
|
|
72
|
-
</IressRow\>
|
|
73
|
-
<IressDivider gutter\="none" />
|
|
74
|
-
<IressRow\>
|
|
75
|
-
<IressCol\>
|
|
76
|
-
<IressFormField
|
|
77
|
-
name\="email"
|
|
78
|
-
label\="Email"
|
|
79
|
-
render\={(controlledProps) \=> (
|
|
80
|
-
<IressInput {...controlledProps} type\="email" />
|
|
81
|
-
)}
|
|
82
|
-
/>
|
|
83
|
-
</IressCol\>
|
|
84
|
-
</IressRow\>
|
|
85
|
-
<IressButton type\="submit" mode\="primary"\>
|
|
86
|
-
Submit </IressButton\>
|
|
87
|
-
</IressStack\>
|
|
88
|
-
</IressContainer\>
|
|
89
|
-
</IressForm\>
|
|
90
|
-
<IressModal show\={!!preview} onShowChange\={(show) \=> setPreview(show)}\>
|
|
91
|
-
<IressTable
|
|
92
|
-
caption\="Submitted"
|
|
93
|
-
rows\={Object.entries(values).map((entry) \=> ({
|
|
94
|
-
name: entry\[0\],
|
|
95
|
-
value: JSON.stringify(entry\[1\], null, 2),
|
|
96
|
-
}))}
|
|
97
|
-
/>
|
|
98
|
-
</IressModal\>
|
|
99
|
-
</\>
|
|
100
|
-
);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
Copy
|
|
104
|
-
|
|
105
|
-
[](#switching-between-readonly-and-edit-modes)Switching between readonly and edit modes
|
|
106
|
-
---------------------------------------------------------------------------------------
|
|
107
|
-
|
|
108
|
-
It is recommended to use a button to toggle between read-only and editable input modes.
|
|
109
|
-
|
|
110
|
-
Please take note of the following when switching between modes:
|
|
111
|
-
|
|
112
|
-
* Switching is done on a per-section basis, not on a per-field basis.
|
|
113
|
-
* When the user saves the data, it should switch back to read-only mode to avoid any confusion about whether the changes have been saved.
|
|
114
|
-
|
|
115
|
-
User Details
|
|
116
|
-
------------
|
|
117
|
-
|
|
118
|
-
First Name
|
|
119
|
-
|
|
120
|
-
Leia
|
|
121
|
-
|
|
122
|
-
Last Name
|
|
123
|
-
|
|
124
|
-
Skywalker
|
|
125
|
-
|
|
126
|
-
Email
|
|
127
|
-
|
|
128
|
-
leia.skywalker@iress.com
|
|
129
|
-
|
|
130
|
-
dependents
|
|
131
|
-
|
|
132
|
-
0
|
|
133
|
-
|
|
134
|
-
Edit
|
|
135
|
-
|
|
136
|
-
Hide code
|
|
137
|
-
|
|
138
|
-
\[data-radix-scroll-area-viewport\] { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; } \[data-radix-scroll-area-viewport\]::-webkit-scrollbar { display: none; } :where(\[data-radix-scroll-area-viewport\]) { display: flex; flex-direction: column; align-items: stretch; } :where(\[data-radix-scroll-area-content\]) { flex-grow: 1; }
|
|
139
|
-
|
|
140
|
-
export const SwitchEditReadonlyForm \= () \=> {
|
|
141
|
-
const dependentOptions \= \[
|
|
142
|
-
{ value: 0, label: '0' },
|
|
143
|
-
{ value: 1, label: '1' },
|
|
144
|
-
{ value: 2, label: '2' },
|
|
145
|
-
{ value: 3, label: '3' },
|
|
146
|
-
{ value: 4, label: '4' },
|
|
147
|
-
{ value: 5, label: '5' },
|
|
148
|
-
{ value: 6, label: '6' },
|
|
149
|
-
{ value: 7, label: '7' },
|
|
150
|
-
{ value: 8, label: '8' },
|
|
151
|
-
{ value: 9, label: '9' },
|
|
152
|
-
{ value: 10, label: '10' },
|
|
153
|
-
\];
|
|
154
|
-
const \[values, setValues\] \= useState<FieldValues\>({
|
|
155
|
-
firstName: 'Leia',
|
|
156
|
-
lastName: 'Skywalker',
|
|
157
|
-
email: 'leia.skywalker@iress.com',
|
|
158
|
-
dependents: 0,
|
|
159
|
-
});
|
|
160
|
-
const \[preview, setPreview\] \= useState(false);
|
|
161
|
-
const \[editable, setEditable\] \= useState(false);
|
|
162
|
-
return (
|
|
163
|
-
<\>
|
|
164
|
-
<IressForm
|
|
165
|
-
onSubmit\={(data) \=> {
|
|
166
|
-
setValues(data);
|
|
167
|
-
setPreview(true);
|
|
168
|
-
setEditable(false);
|
|
169
|
-
}}
|
|
170
|
-
values\={values}
|
|
171
|
-
\>
|
|
172
|
-
<IressContainer\>
|
|
173
|
-
<IressStack gutter\="md"\>
|
|
174
|
-
<IressText element\="h2"\>User Details</IressText\>
|
|
175
|
-
<IressRow gutter\="md"\>
|
|
176
|
-
<IressCol\>
|
|
177
|
-
<IressFormField
|
|
178
|
-
name\="firstName"
|
|
179
|
-
label\="First Name"
|
|
180
|
-
render\={(controlledProps) \=> (
|
|
181
|
-
<IressInput {...controlledProps} readOnly\={!editable} />
|
|
182
|
-
)}
|
|
183
|
-
/>
|
|
184
|
-
</IressCol\>
|
|
185
|
-
<IressCol\>
|
|
186
|
-
<IressFormField
|
|
187
|
-
name\="lastName"
|
|
188
|
-
label\="Last Name"
|
|
189
|
-
render\={(controlledProps) \=> (
|
|
190
|
-
<IressInput {...controlledProps} readOnly\={!editable} />
|
|
191
|
-
)}
|
|
192
|
-
/>
|
|
193
|
-
</IressCol\>
|
|
194
|
-
</IressRow\>
|
|
195
|
-
<IressRow gutter\="md"\>
|
|
196
|
-
<IressCol\>
|
|
197
|
-
<IressFormField
|
|
198
|
-
name\="email"
|
|
199
|
-
label\="Email"
|
|
200
|
-
render\={(controlledProps) \=> (
|
|
201
|
-
<IressInput
|
|
202
|
-
{...controlledProps}
|
|
203
|
-
readOnly\={!editable}
|
|
204
|
-
type\="email"
|
|
205
|
-
/>
|
|
206
|
-
)}
|
|
207
|
-
/>
|
|
208
|
-
</IressCol\>
|
|
209
|
-
<IressCol\>
|
|
210
|
-
<IressFormField
|
|
211
|
-
name\="dependents"
|
|
212
|
-
label\="dependents"
|
|
213
|
-
render\={(controlledProps) \=> (
|
|
214
|
-
<IressSelect
|
|
215
|
-
{...controlledProps}
|
|
216
|
-
readonly\={!editable}
|
|
217
|
-
onChange\={(
|
|
218
|
-
e: React.ChangeEvent<HTMLSelectElement\>,
|
|
219
|
-
value?: FormControlValue,
|
|
220
|
-
) \=> controlledProps.onChange(value)}
|
|
221
|
-
\>
|
|
222
|
-
{dependentOptions.map((option) \=> (
|
|
223
|
-
<option key\={option.value} value\={option.value}\>
|
|
224
|
-
{option.label}
|
|
225
|
-
</option\>
|
|
226
|
-
))}
|
|
227
|
-
</IressSelect\>
|
|
228
|
-
)}
|
|
229
|
-
/>
|
|
230
|
-
</IressCol\>
|
|
231
|
-
</IressRow\>
|
|
232
|
-
{editable ? (
|
|
233
|
-
<IressInline gutter\="sm"\>
|
|
234
|
-
<IressButton type\="submit" mode\="primary"\>
|
|
235
|
-
Save </IressButton\>
|
|
236
|
-
<IressButton onClick\={() \=> setEditable(false)}\>
|
|
237
|
-
Cancel </IressButton\>
|
|
238
|
-
</IressInline\>
|
|
239
|
-
) : (
|
|
240
|
-
<IressButton
|
|
241
|
-
onClick\={() \=> setEditable(true)}
|
|
242
|
-
prepend\={<IressIcon name\="pencil" />}
|
|
243
|
-
\>
|
|
244
|
-
Edit </IressButton\>
|
|
245
|
-
)}
|
|
246
|
-
</IressStack\>
|
|
247
|
-
</IressContainer\>
|
|
248
|
-
</IressForm\>
|
|
249
|
-
<IressModal show\={!!preview} onShowChange\={(show) \=> setPreview(show)}\>
|
|
250
|
-
<IressTable
|
|
251
|
-
caption\="Submitted"
|
|
252
|
-
rows\={Object.entries(values).map((entry) \=> ({
|
|
253
|
-
name: entry\[0\],
|
|
254
|
-
value: JSON.stringify(entry\[1\], null, 2),
|
|
255
|
-
}))}
|
|
256
|
-
/>
|
|
257
|
-
</IressModal\>
|
|
258
|
-
</\>
|
|
259
|
-
);
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
Copy
|
|
263
|
-
|
|
264
|
-
[](#alternative-form-validation)Alternative form validation
|
|
265
|
-
-----------------------------------------------------------
|
|
266
|
-
|
|
267
|
-
`IressForm` is always recommended for all validation, as it is the cleanest way (least code) to provide the best form user experience for your users. Please visit the [`IressForm` documentation](./?path=/docs/components-form--docs) for different validation examples.
|
|
268
|
-
|
|
269
|
-
However, if you have more complex requirements and you find `IressForm` too opinionated for your needs, you can always bring your own form validation using a native `form` element and the other IDS components such as `IressField`.
|
|
270
|
-
|
|
271
|
-
Here is an example showcasing a form using the native form constraints API to achieve validation using IDS components. There are other libraries such as: [Yup](https://github.com/jquense/yup), [Joi](https://github.com/hapijs/joi) or [Zod](https://zod.dev/)) which can improve scalability, with the downside being you will have to maintain all validation yourself.
|
|
272
|
-
|
|
273
|
-
**\*Required Name**
|
|
274
|
-
|
|
275
|
-
**\*Required Email address**
|
|
276
|
-
|
|
277
|
-
Sign up
|
|
278
|
-
|
|
279
|
-
Hide code
|
|
280
|
-
|
|
281
|
-
\[data-radix-scroll-area-viewport\] { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; } \[data-radix-scroll-area-viewport\]::-webkit-scrollbar { display: none; } :where(\[data-radix-scroll-area-viewport\]) { display: flex; flex-direction: column; align-items: stretch; } :where(\[data-radix-scroll-area-content\]) { flex-grow: 1; }
|
|
282
|
-
|
|
283
|
-
export const NativeValidationForm \= () \=> {
|
|
284
|
-
const \[formData, setFormData\] \= useState({
|
|
285
|
-
name: '',
|
|
286
|
-
email: '',
|
|
287
|
-
});
|
|
288
|
-
const \[errors, setErrors\] \= useState<Record<string, boolean\>>({
|
|
289
|
-
name: false,
|
|
290
|
-
email: false,
|
|
291
|
-
});
|
|
292
|
-
const \[isSubmitted, setIsSubmitted\] \= useState(false);
|
|
293
|
-
const hasErrors \= Object.values(errors).some((error) \=> !!error);
|
|
294
|
-
const handleInputChange \= (e: React.ChangeEvent<InputBaseElement\>) \=> {
|
|
295
|
-
setFormData({ ...formData, \[e.target.name\]: e.target.value });
|
|
296
|
-
setErrors({
|
|
297
|
-
...errors,
|
|
298
|
-
\[e.target.name\]: !e.currentTarget.reportValidity(),
|
|
299
|
-
});
|
|
300
|
-
};
|
|
301
|
-
const handleSubmit \= (e: React.FormEvent<HTMLFormElement\>) \=> {
|
|
302
|
-
e.preventDefault();
|
|
303
|
-
const form \= e.currentTarget;
|
|
304
|
-
setIsSubmitted(true);
|
|
305
|
-
if (!form.checkValidity()) {
|
|
306
|
-
const fieldData \= Object.fromEntries(new FormData(form).entries());
|
|
307
|
-
const fieldNames \= Object.keys(fieldData);
|
|
308
|
-
setErrors(
|
|
309
|
-
fieldNames.reduce(
|
|
310
|
-
(newErrors, fieldName) \=> {
|
|
311
|
-
newErrors\[fieldName\] \= !form
|
|
312
|
-
.querySelector<HTMLInputElement\>(\`\[name=${fieldName}\]\`)
|
|
313
|
-
?.checkValidity();
|
|
314
|
-
return newErrors;
|
|
315
|
-
},
|
|
316
|
-
{} as Record<string, boolean\>,
|
|
317
|
-
),
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
console.log(formData);
|
|
321
|
-
};
|
|
322
|
-
return (
|
|
323
|
-
<form onSubmit\={handleSubmit} noValidate\>
|
|
324
|
-
<IressStack gutter\="md"\>
|
|
325
|
-
{isSubmitted && hasErrors && (
|
|
326
|
-
<IressAlert status\="danger"\>
|
|
327
|
-
There's a problem with your submission. </IressAlert\>
|
|
328
|
-
)}
|
|
329
|
-
<IressField
|
|
330
|
-
label\="Name"
|
|
331
|
-
error\={
|
|
332
|
-
errors.name && (
|
|
333
|
-
<IressValidationMessage\>Name is required</IressValidationMessage\>
|
|
334
|
-
)
|
|
335
|
-
}
|
|
336
|
-
required
|
|
337
|
-
\>
|
|
338
|
-
<IressInput name\="name" onChange\={handleInputChange} required />
|
|
339
|
-
</IressField\>
|
|
340
|
-
<IressField
|
|
341
|
-
label\="Email address"
|
|
342
|
-
error\={
|
|
343
|
-
errors.email && (
|
|
344
|
-
<IressValidationMessage\>Email is required</IressValidationMessage\>
|
|
345
|
-
)
|
|
346
|
-
}
|
|
347
|
-
required
|
|
348
|
-
\>
|
|
349
|
-
<IressInput name\="email" onChange\={handleInputChange} required />
|
|
350
|
-
</IressField\>
|
|
351
|
-
<IressButton mode\="primary" type\="submit"\>
|
|
352
|
-
Sign up </IressButton\>
|
|
353
|
-
</IressStack\>
|
|
354
|
-
</form\>
|
|
355
|
-
);
|
|
356
|
-
};
|
|
357
|
-
|
|
358
|
-
Copy
|
|
359
|
-
|
|
360
|
-
[](#nested-forms)Nested forms
|
|
361
|
-
-----------------------------
|
|
362
|
-
|
|
363
|
-
Unfortunately, it is [forbidden to nest form elements as per the HTML specifications](https://developer.mozilla.org/en-US/docs/Learn/Forms/How_to_structure_a_web_form).
|
|
364
|
-
|
|
365
|
-
To achieve a similar effect, you can use multiple `IressForm` components, and trigger validation in multiple ways:
|
|
366
|
-
|
|
367
|
-
1. You can trigger specific forms using the `form` attribute of `IressButton`. The [`form` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#form) allows you to specify the form ID to submit when the button is clicked, which can be any form on the page, and will take precedence over the parent form of a button.
|
|
368
|
-
2. If you need to trigger multiple forms, you can use the [`requestSubmit` method](https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/requestSubmit) on the form element to trigger the validation of multiple forms.
|
|
369
|
-
3. If you only want to trigger validation and not trigger submission even if the validation passes, you can use the `ref` attribute of `IressForm` and trigger validation manually using `ref.current?.api.trigger()`, which is based on the [React Hook Form API](https://react-hook-form.com/docs/useform/trigger).
|
|
370
|
-
|
|
371
|
-
The example here showcases triggering validation using the `form` attribute of `IressButton` and the `requestSubmit` method on the form element.
|
|
372
|
-
|
|
373
|
-
\*Required Name
|
|
374
|
-
|
|
375
|
-
Add new dependant
|
|
376
|
-
|
|
377
|
-
\*Required Name
|
|
378
|
-
|
|
379
|
-
Save
|
|
380
|
-
|
|
381
|
-
* * *
|
|
382
|
-
|
|
383
|
-
Submit main formSubmit all forms
|
|
384
|
-
|
|
385
|
-
Hide code
|
|
386
|
-
|
|
387
|
-
\[data-radix-scroll-area-viewport\] { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; } \[data-radix-scroll-area-viewport\]::-webkit-scrollbar { display: none; } :where(\[data-radix-scroll-area-viewport\]) { display: flex; flex-direction: column; align-items: stretch; } :where(\[data-radix-scroll-area-content\]) { flex-grow: 1; }
|
|
388
|
-
|
|
389
|
-
interface FormData {
|
|
390
|
-
name: string;
|
|
391
|
-
}
|
|
392
|
-
const MainForm \= () \=> {
|
|
393
|
-
const \[details, setDetails\] \= useState<FormData | undefined\>();
|
|
394
|
-
return (
|
|
395
|
-
<\>
|
|
396
|
-
<IressForm<FormData> errorSummaryHeading="Please correct the following errors for the main form" id="mainForm" onSubmit={(data) \=> {
|
|
397
|
-
setDetails(data);
|
|
398
|
-
}}
|
|
399
|
-
> <IressFormField<FormData> name="name" label="Name" render={(controlledProps) \=> <IressInput {...controlledProps} />}
|
|
400
|
-
rules={{ required: true }}
|
|
401
|
-
/> </IressForm\>
|
|
402
|
-
<IressModal
|
|
403
|
-
show\={!!details}
|
|
404
|
-
onShowChange\={(show) \=> !show && setDetails(undefined)}
|
|
405
|
-
\>
|
|
406
|
-
{details && (
|
|
407
|
-
<IressTable
|
|
408
|
-
caption\="Submitted main form"
|
|
409
|
-
rows\={Object.entries(details).map((entry) \=> ({
|
|
410
|
-
name: entry\[0\],
|
|
411
|
-
value: JSON.stringify(entry\[1\], null, 2),
|
|
412
|
-
}))}
|
|
413
|
-
/>
|
|
414
|
-
)}
|
|
415
|
-
</IressModal\>
|
|
416
|
-
</\>
|
|
417
|
-
);
|
|
418
|
-
};
|
|
419
|
-
const SubForm \= () \=> {
|
|
420
|
-
const \[details, setDetails\] \= useState<FormData | undefined\>();
|
|
421
|
-
return (
|
|
422
|
-
<IressPanel\>
|
|
423
|
-
<IressStack gutter\="md"\>
|
|
424
|
-
<IressForm<FormData> errorSummaryHeading="Please correct the following errors found for the dependant" gutter="sm" id="subForm" onSubmit={(data) \=> {
|
|
425
|
-
setDetails(data);
|
|
426
|
-
}}
|
|
427
|
-
> <IressFieldGroup label\="Add new dependant" inline\>
|
|
428
|
-
<IressFormField
|
|
429
|
-
name\="name"
|
|
430
|
-
label\="Name"
|
|
431
|
-
render\={(controlledProps) \=> <IressInput {...controlledProps} />}
|
|
432
|
-
rules\={{ required: true }}
|
|
433
|
-
/>
|
|
434
|
-
<IressButton type\="submit"\>Save</IressButton\>
|
|
435
|
-
</IressFieldGroup\>
|
|
436
|
-
</IressForm\>
|
|
437
|
-
<IressTable
|
|
438
|
-
caption\="Dependants"
|
|
439
|
-
columns\={\[
|
|
440
|
-
{ key: 'name', label: 'Name' },
|
|
441
|
-
{ key: 'value', label: 'Value' },
|
|
442
|
-
\]}
|
|
443
|
-
rows\={Object.entries(details ?? {}).map((entry) \=> ({
|
|
444
|
-
name: entry\[0\],
|
|
445
|
-
value: JSON.stringify(entry\[1\], null, 2),
|
|
446
|
-
}))}
|
|
447
|
-
/>
|
|
448
|
-
</IressStack\>
|
|
449
|
-
</IressPanel\>
|
|
450
|
-
);
|
|
451
|
-
};
|
|
452
|
-
export const NestedFormsExample \= () \=> {
|
|
453
|
-
const submitAllForms \= () \=> {
|
|
454
|
-
document.querySelector<HTMLFormElement\>('\[id=mainForm\]')?.requestSubmit();
|
|
455
|
-
document.querySelector<HTMLFormElement\>('\[id=subForm\]')?.requestSubmit();
|
|
456
|
-
};
|
|
457
|
-
return (
|
|
458
|
-
<IressStack gutter\="md"\>
|
|
459
|
-
<MainForm />
|
|
460
|
-
<SubForm />
|
|
461
|
-
<IressDivider />
|
|
462
|
-
<IressInline gutter\="md"\>
|
|
463
|
-
<IressButton type\="submit" form\="mainForm"\>
|
|
464
|
-
Submit main form </IressButton\>
|
|
465
|
-
<IressButton onClick\={submitAllForms}\>Submit all forms</IressButton\>
|
|
466
|
-
</IressInline\>
|
|
467
|
-
</IressStack\>
|
|
468
|
-
);
|
|
469
|
-
};
|
|
470
|
-
|
|
471
|
-
Copy
|
|
472
|
-
|
|
473
|
-
[](#form-groups)Form Groups
|
|
474
|
-
---------------------------
|
|
475
|
-
|
|
476
|
-
Powered by [React Hook Form](https://react-hook-form.com/docs/usefieldarray)'s `useFieldArray`, this example allows you add/edit/delete multiple children sections within ONE form (not nested form).
|
|
477
|
-
|
|
478
|
-
Form groups
|
|
479
|
-
===========
|
|
480
|
-
|
|
481
|
-
This is one form with child sections (not nested forms). Play around to add/edit/delete child form sections:
|
|
482
|
-
|
|
483
|
-
Client
|
|
484
|
-
------
|
|
485
|
-
|
|
486
|
-
\*Required Name
|
|
487
|
-
|
|
488
|
-
\*Required Salary
|
|
489
|
-
|
|
490
|
-
\*Required Goal
|
|
491
|
-
|
|
492
|
-
Dependant 1
|
|
493
|
-
-----------
|
|
494
|
-
|
|
495
|
-
\*Required Name
|
|
496
|
-
|
|
497
|
-
\*Required Relationship
|
|
498
|
-
|
|
499
|
-
\*Required Age
|
|
500
|
-
|
|
501
|
-
Save
|
|
502
|
-
|
|
503
|
-
Add Dependant
|
|
504
|
-
|
|
505
|
-
* * *
|
|
506
|
-
|
|
507
|
-
Submit All
|
|
508
|
-
|
|
509
|
-
Hide code
|
|
510
|
-
|
|
511
|
-
\[data-radix-scroll-area-viewport\] { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; } \[data-radix-scroll-area-viewport\]::-webkit-scrollbar { display: none; } :where(\[data-radix-scroll-area-viewport\]) { display: flex; flex-direction: column; align-items: stretch; } :where(\[data-radix-scroll-area-content\]) { flex-grow: 1; }
|
|
512
|
-
|
|
513
|
-
interface Client {
|
|
514
|
-
name: string | undefined;
|
|
515
|
-
salary: number | undefined;
|
|
516
|
-
goal: string | undefined;
|
|
517
|
-
}
|
|
518
|
-
interface Dependant {
|
|
519
|
-
name: string | undefined;
|
|
520
|
-
relationship: string | undefined;
|
|
521
|
-
age: number | undefined;
|
|
522
|
-
}
|
|
523
|
-
interface FormValues {
|
|
524
|
-
client: Client;
|
|
525
|
-
dependants: Dependant\[\];
|
|
526
|
-
}
|
|
527
|
-
interface ClientProps {
|
|
528
|
-
control: Control<FormValues\> | undefined;
|
|
529
|
-
}
|
|
530
|
-
interface DependantProps {
|
|
531
|
-
index: number;
|
|
532
|
-
control: Control<FormValues\> | undefined;
|
|
533
|
-
update: (index: number, data: Dependant) \=> void;
|
|
534
|
-
remove: (index: number) \=> void;
|
|
535
|
-
getValues: UseFormGetValues<FormValues\>;
|
|
536
|
-
}
|
|
537
|
-
const defaultValues \= {
|
|
538
|
-
client: {
|
|
539
|
-
name: '',
|
|
540
|
-
salary: undefined,
|
|
541
|
-
goal: '',
|
|
542
|
-
},
|
|
543
|
-
dependants: \[
|
|
544
|
-
{
|
|
545
|
-
name: '',
|
|
546
|
-
relationship: '',
|
|
547
|
-
age: undefined,
|
|
548
|
-
},
|
|
549
|
-
\],
|
|
550
|
-
};
|
|
551
|
-
const ClientSection: React.FC<ClientProps\> \= ({ control }) \=> {
|
|
552
|
-
return (
|
|
553
|
-
<IressFieldGroup label\={<IressText element\="h2"\>Client</IressText\>}\>
|
|
554
|
-
<IressStack gutter\="md"\>
|
|
555
|
-
<IressFormField
|
|
556
|
-
name\="client.name"
|
|
557
|
-
label\="Name"
|
|
558
|
-
control\={control}
|
|
559
|
-
render\={(controlledProps) \=> <IressInput {...controlledProps} />}
|
|
560
|
-
rules\={{ required: true }}
|
|
561
|
-
/>
|
|
562
|
-
<IressFormField
|
|
563
|
-
name\="client.salary"
|
|
564
|
-
label\="Salary"
|
|
565
|
-
control\={control}
|
|
566
|
-
render\={(controlledProps) \=> <IressInput {...controlledProps} />}
|
|
567
|
-
rules\={{ required: true }}
|
|
568
|
-
/>
|
|
569
|
-
<IressFormField
|
|
570
|
-
name\="client.goal"
|
|
571
|
-
label\="Goal"
|
|
572
|
-
control\={control}
|
|
573
|
-
render\={(controlledProps) \=> <IressInput {...controlledProps} />}
|
|
574
|
-
rules\={{ required: true }}
|
|
575
|
-
/>
|
|
576
|
-
</IressStack\>
|
|
577
|
-
</IressFieldGroup\>
|
|
578
|
-
);
|
|
579
|
-
};
|
|
580
|
-
const DependantSection: React.FC<DependantProps\> \= ({
|
|
581
|
-
index,
|
|
582
|
-
update,
|
|
583
|
-
remove,
|
|
584
|
-
control,
|
|
585
|
-
getValues,
|
|
586
|
-
}: DependantProps) \=> {
|
|
587
|
-
return (
|
|
588
|
-
<IressPanel\>
|
|
589
|
-
<IressInline horizontalAlign\="right"\>
|
|
590
|
-
<IressCloseButton onClick\={() \=> remove(index)} />
|
|
591
|
-
</IressInline\>
|
|
592
|
-
<IressStack gutter\="md"\>
|
|
593
|
-
<IressFieldGroup
|
|
594
|
-
label\={<IressText element\="h2"\>Dependant {index + 1}</IressText\>}
|
|
595
|
-
\>
|
|
596
|
-
<IressStack gutter\="md"\>
|
|
597
|
-
<IressFormField
|
|
598
|
-
name\={\`dependants.${index}.name\`}
|
|
599
|
-
label\="Name"
|
|
600
|
-
control\={control}
|
|
601
|
-
render\={(controlledProps) \=> <IressInput {...controlledProps} />}
|
|
602
|
-
rules\={{ required: true }}
|
|
603
|
-
/>
|
|
604
|
-
<IressFormField
|
|
605
|
-
name\={\`dependants.${index}.relationship\`}
|
|
606
|
-
label\="Relationship"
|
|
607
|
-
control\={control}
|
|
608
|
-
render\={(controlledProps) \=> <IressInput {...controlledProps} />}
|
|
609
|
-
rules\={{ required: true }}
|
|
610
|
-
/>
|
|
611
|
-
<IressFormField
|
|
612
|
-
name\={\`dependants.${index}.age\`}
|
|
613
|
-
label\="Age"
|
|
614
|
-
control\={control}
|
|
615
|
-
render\={(controlledProps) \=> <IressInput {...controlledProps} />}
|
|
616
|
-
rules\={{ required: true }}
|
|
617
|
-
/>
|
|
618
|
-
<IressButton
|
|
619
|
-
type\="button"
|
|
620
|
-
prepend\={<IressIcon name\="check" />}
|
|
621
|
-
onClick\={() \=> {
|
|
622
|
-
const data \= getValues();
|
|
623
|
-
const value \= data?.dependants\[index\];
|
|
624
|
-
update(index, value);
|
|
625
|
-
}}
|
|
626
|
-
\>
|
|
627
|
-
Save </IressButton\>
|
|
628
|
-
</IressStack\>
|
|
629
|
-
</IressFieldGroup\>
|
|
630
|
-
</IressStack\>
|
|
631
|
-
</IressPanel\>
|
|
632
|
-
);
|
|
633
|
-
};
|
|
634
|
-
export const FormGroups \= () \=> {
|
|
635
|
-
const form \= useForm<FormValues\>({
|
|
636
|
-
defaultValues: defaultValues,
|
|
637
|
-
mode: 'onBlur',
|
|
638
|
-
});
|
|
639
|
-
const { control, getValues } \= form;
|
|
640
|
-
const { fields, append, update, remove } \= useFieldArray({
|
|
641
|
-
name: 'dependants',
|
|
642
|
-
control,
|
|
643
|
-
});
|
|
644
|
-
const onSubmit \= (data: FormValues) \=> console.log(data);
|
|
645
|
-
return (
|
|
646
|
-
<IressStack gutter\="md"\>
|
|
647
|
-
<IressText element\="h1"\>Form groups</IressText\>
|
|
648
|
-
<IressText element\="p"\>
|
|
649
|
-
This is one form with child sections (not nested forms). Play around to add/edit/delete child form sections: </IressText\>
|
|
650
|
-
<IressHookForm<FormValues> gutter="md" form={form}
|
|
651
|
-
onSubmit={onSubmit}
|
|
652
|
-
errorSummaryHeading="Please correct the following errors found for the form:" > <IressStack gutter\="md"\>
|
|
653
|
-
<ClientSection control\={control} />
|
|
654
|
-
{fields.map((field, index) \=> (
|
|
655
|
-
<DependantSection
|
|
656
|
-
key\={field.id}
|
|
657
|
-
index\={index}
|
|
658
|
-
control\={control}
|
|
659
|
-
update\={update}
|
|
660
|
-
remove\={remove}
|
|
661
|
-
getValues\={getValues}
|
|
662
|
-
/>
|
|
663
|
-
))}
|
|
664
|
-
<IressButton
|
|
665
|
-
type\="button"
|
|
666
|
-
prepend\={<IressIcon name\="plus" />}
|
|
667
|
-
onClick\={() \=> {
|
|
668
|
-
append({ name: '', relationship: '', age: undefined });
|
|
669
|
-
}}
|
|
670
|
-
\>
|
|
671
|
-
Add Dependant </IressButton\>
|
|
672
|
-
</IressStack\>
|
|
673
|
-
<IressDivider />
|
|
674
|
-
<IressButton type\="submit" mode\="primary"\>
|
|
675
|
-
Submit All </IressButton\>
|
|
676
|
-
</IressHookForm\>
|
|
677
|
-
</IressStack\>
|
|
678
|
-
);
|
|
679
|
-
};
|
|
680
|
-
|
|
681
|
-
Copy
|
|
682
|
-
|
|
683
|
-
[](#hidden-inputs)Hidden inputs
|
|
684
|
-
-------------------------------
|
|
685
|
-
|
|
686
|
-
You can use hidden inputs to store data that you do not want to display to the user, but still need to include in the form submission. This is useful for storing metadata or other information that is not editable by the user.
|
|
687
|
-
|
|
688
|
-
Warning
|
|
689
|
-
-------
|
|
690
|
-
|
|
691
|
-
This is not a recommended practice, as it can lead to security issues if sensitive data is stored in hidden inputs. It is better to use a variable to store your data, and include it in the form submission using the `onSubmit` handler.
|
|
692
|
-
|
|
693
|
-
Visible Input
|
|
694
|
-
|
|
695
|
-
Submit
|
|
696
|
-
|
|
697
|
-
Hide code
|
|
698
|
-
|
|
699
|
-
\[data-radix-scroll-area-viewport\] { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; } \[data-radix-scroll-area-viewport\]::-webkit-scrollbar { display: none; } :where(\[data-radix-scroll-area-viewport\]) { display: flex; flex-direction: column; align-items: stretch; } :where(\[data-radix-scroll-area-content\]) { flex-grow: 1; }
|
|
700
|
-
|
|
701
|
-
export const HiddenInputsForm \= () \=> {
|
|
702
|
-
const form \= IressForm.useForm();
|
|
703
|
-
const { register } \= form;
|
|
704
|
-
// This is a hidden input field that the user cannot see or interact with.
|
|
705
|
-
// This is the recommended way to handle hidden inputs in Iress forms.
|
|
706
|
-
const hiddenInputStoredInVariable \= 'hiddenValue';
|
|
707
|
-
return (
|
|
708
|
-
<IressHookForm
|
|
709
|
-
form\={form}
|
|
710
|
-
onSubmit\={(data) \=> {
|
|
711
|
-
console.log('Form submitted with data:', {
|
|
712
|
-
...data,
|
|
713
|
-
hiddenInputStoredInVariable,
|
|
714
|
-
});
|
|
715
|
-
}}
|
|
716
|
-
\>
|
|
717
|
-
<IressStack gutter\="md"\>
|
|
718
|
-
<IressFormField
|
|
719
|
-
label\="Visible Input"
|
|
720
|
-
name\="visibleInput"
|
|
721
|
-
render\={(controlledProps) \=> <IressInput {...controlledProps} />}
|
|
722
|
-
/>
|
|
723
|
-
{/\* Hidden field - NOT RECOMMENDED \*/}
|
|
724
|
-
<input
|
|
725
|
-
type\="hidden"
|
|
726
|
-
{...register('hiddenField')} // Manually register the hidden field with react-hook-form
|
|
727
|
-
value\="hiddenValue"
|
|
728
|
-
/>
|
|
729
|
-
<IressButton type\="submit"\>Submit</IressButton\>
|
|
730
|
-
</IressStack\>
|
|
731
|
-
</IressHookForm\>
|
|
732
|
-
);
|
|
733
|
-
};
|
|
734
|
-
|
|
735
|
-
Copy
|
|
736
|
-
|
|
737
|
-
[](#validation-depend-on-other-fields)Validation depend on other fields
|
|
738
|
-
-----------------------------------------------------------------------
|
|
739
|
-
|
|
740
|
-
This example shows how to validate one field based on another field's value.
|
|
741
|
-
|
|
742
|
-
The budget amount input validates against the selected budget range using the custom `validateBudgetInput` rules.
|
|
743
|
-
|
|
744
|
-
Validation depend on other fields
|
|
745
|
-
=================================
|
|
746
|
-
|
|
747
|
-
This form demonstrates how to validate a field based on the value of another field. The budget amount field is validated against the selected budget range.
|
|
748
|
-
|
|
749
|
-
\*Required Monthly investment budget
|
|
750
|
-
|
|
751
|
-
Select your budget rangeLess than $499Between $500 to $999More than $1000
|
|
752
|
-
|
|
753
|
-
\*Required Enter your budget amount ($)
|
|
754
|
-
|
|
755
|
-
AUD
|
|
756
|
-
|
|
757
|
-
Submit
|
|
758
|
-
|
|
759
|
-
* * *
|
|
760
|
-
|
|
761
|
-
Hide code
|
|
762
|
-
|
|
763
|
-
\[data-radix-scroll-area-viewport\] { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; } \[data-radix-scroll-area-viewport\]::-webkit-scrollbar { display: none; } :where(\[data-radix-scroll-area-viewport\]) { display: flex; flex-direction: column; align-items: stretch; } :where(\[data-radix-scroll-area-content\]) { flex-grow: 1; }
|
|
764
|
-
|
|
765
|
-
interface FormData {
|
|
766
|
-
primaryField: string;
|
|
767
|
-
dependentField: string;
|
|
768
|
-
}
|
|
769
|
-
const budgetOptions \= \[
|
|
770
|
-
{ value: 'less-than-499', label: 'Less than $499' },
|
|
771
|
-
{ value: 'between-500-999', label: 'Between $500 to $999' },
|
|
772
|
-
{ value: 'more-than-1000', label: 'More than $1000' },
|
|
773
|
-
\];
|
|
774
|
-
const validateBudgetInput \= (
|
|
775
|
-
value: string,
|
|
776
|
-
selectedBudget: string,
|
|
777
|
-
): string | true \=> {
|
|
778
|
-
if (!selectedBudget) return 'Select budget range first';
|
|
779
|
-
const numericValue \= parseFloat(value);
|
|
780
|
-
if (isNaN(numericValue)) return 'Enter a valid number';
|
|
781
|
-
switch (selectedBudget) {
|
|
782
|
-
case 'less-than-499':
|
|
783
|
-
return numericValue < 499 || 'Must be less than $499';
|
|
784
|
-
case 'between-500-999':
|
|
785
|
-
return (
|
|
786
|
-
(numericValue \>= 500 && numericValue <= 999) ||
|
|
787
|
-
'Must be between $500-$999'
|
|
788
|
-
);
|
|
789
|
-
case 'more-than-1000':
|
|
790
|
-
return numericValue \> 1000 || 'Must be more than $1000';
|
|
791
|
-
default:
|
|
792
|
-
return true;
|
|
793
|
-
}
|
|
794
|
-
};
|
|
795
|
-
export const ValidationDependOnOtherFields \= () \=> {
|
|
796
|
-
const \[submitted, setSubmitted\] \= useState<FormData | undefined\>(undefined);
|
|
797
|
-
const form \= IressForm.useForm<FormData\>({
|
|
798
|
-
defaultValues: {
|
|
799
|
-
primaryField: '',
|
|
800
|
-
dependentField: '',
|
|
801
|
-
},
|
|
802
|
-
});
|
|
803
|
-
const onSubmit \= (data: FormData) \=> {
|
|
804
|
-
console.log(data);
|
|
805
|
-
setSubmitted(data);
|
|
806
|
-
};
|
|
807
|
-
const onError \= (errors: Record<string, unknown\>) \=> {
|
|
808
|
-
console.log('Form validation errors:', errors);
|
|
809
|
-
};
|
|
810
|
-
return (
|
|
811
|
-
<\>
|
|
812
|
-
<IressText element\="h1"\>Validation depend on other fields</IressText\>
|
|
813
|
-
<IressText element\="p"\>
|
|
814
|
-
This form demonstrates how to validate a field based on the value of another field. The budget amount field is validated against the selected budget range. </IressText\>
|
|
815
|
-
<IressHookForm form\={form} onSubmit\={onSubmit} onError\={onError}\>
|
|
816
|
-
<IressStack gutter\="md"\>
|
|
817
|
-
<IressRow\>
|
|
818
|
-
<IressCol\>
|
|
819
|
-
<IressFormField
|
|
820
|
-
name\="primaryField"
|
|
821
|
-
label\="Monthly investment budget"
|
|
822
|
-
rules\={{
|
|
823
|
-
required: 'Budget range is required',
|
|
824
|
-
}}
|
|
825
|
-
render\={(field) \=> (
|
|
826
|
-
<IressSelect
|
|
827
|
-
{...field}
|
|
828
|
-
placeholder\="Select your budget range"
|
|
829
|
-
\>
|
|
830
|
-
{budgetOptions.map((option) \=> (
|
|
831
|
-
<option key\={option.value} value\={option.value}\>
|
|
832
|
-
{option.label}
|
|
833
|
-
</option\>
|
|
834
|
-
))}
|
|
835
|
-
</IressSelect\>
|
|
836
|
-
)}
|
|
837
|
-
/>
|
|
838
|
-
</IressCol\>
|
|
839
|
-
</IressRow\>
|
|
840
|
-
<IressRow\>
|
|
841
|
-
<IressCol\>
|
|
842
|
-
<IressFormField
|
|
843
|
-
name\="dependentField"
|
|
844
|
-
label\="Enter your budget amount ($)"
|
|
845
|
-
rules\={{
|
|
846
|
-
required: 'Budget amount is required',
|
|
847
|
-
validate: (value: string, formValues: FormData) \=>
|
|
848
|
-
validateBudgetInput(value, formValues.primaryField),
|
|
849
|
-
}}
|
|
850
|
-
render\={(field) \=> (
|
|
851
|
-
<IressInputCurrency {...field} type\="number" />
|
|
852
|
-
)}
|
|
853
|
-
/>
|
|
854
|
-
</IressCol\>
|
|
855
|
-
</IressRow\>
|
|
856
|
-
<IressButton type\="submit"\>Submit</IressButton\>
|
|
857
|
-
</IressStack\>
|
|
858
|
-
</IressHookForm\>
|
|
859
|
-
<IressDivider />
|
|
860
|
-
{submitted && (
|
|
861
|
-
<IressStack gutter\="md"\>
|
|
862
|
-
<IressText variant\="bold"\>Submitted Values:</IressText\>
|
|
863
|
-
<IressText\>
|
|
864
|
-
Budget Range:{' '}
|
|
865
|
-
{budgetOptions.find(
|
|
866
|
-
(option) \=> option.value \=== submitted.primaryField,
|
|
867
|
-
)?.label ?? submitted.primaryField}
|
|
868
|
-
</IressText\>
|
|
869
|
-
<IressText\>Budget Amount: ${submitted.dependentField}</IressText\>
|
|
870
|
-
</IressStack\>
|
|
871
|
-
)}
|
|
872
|
-
</\>
|
|
873
|
-
);
|
|
874
|
-
};
|
|
875
|
-
|
|
876
|
-
Copy
|
|
877
|
-
|
|
878
|
-
On this page
|
|
879
|
-
|
|
880
|
-
* [With readonly data](#with-readonly-data)
|
|
881
|
-
* [Switching between readonly and edit modes](#switching-between-readonly-and-edit-modes)
|
|
882
|
-
* [Alternative form validation](#alternative-form-validation)
|
|
883
|
-
* [Nested forms](#nested-forms)
|
|
884
|
-
* [Form Groups](#form-groups)
|
|
885
|
-
* [Hidden inputs](#hidden-inputs)
|
|
886
|
-
* [Validation depend on other fields](#validation-depend-on-other-fields)
|