1
- import { AnyListener , ChildForm , ErrorMap , FormInput , FormSelect , FormTextArea , useForm } from "typed-react-form" ;
1
+ import { AnyListener , ArrayForm , ChildForm , ErrorMap , FormInput , FormSelect , FormTextArea , useForm } from "typed-react-form" ;
2
2
import tv , { SchemaType } from "typed-object-validator" ;
3
3
import React from "react" ;
4
4
import { VisualRender } from "./VisualRender" ;
@@ -14,7 +14,14 @@ const FormDataSchema = tv.object({
14
14
object : tv . object ( {
15
15
childText : tv . string ( ) ,
16
16
childNumber : tv . number ( )
17
- } )
17
+ } ) ,
18
+ array : tv . array ( tv . string ( ) ) ,
19
+ objectArray : tv . array (
20
+ tv . object ( {
21
+ text : tv . string ( ) ,
22
+ boolean : tv . boolean ( )
23
+ } )
24
+ )
18
25
} ) ;
19
26
type FormData = SchemaType < typeof FormDataSchema > ;
20
27
@@ -25,7 +32,19 @@ function validate(data: FormData) {
25
32
export function ExampleForm ( ) {
26
33
// Initial values as first argument
27
34
const form = useForm (
28
- { longText : "" , text : "" , number : 123 , enum : "option1" , boolean : false , object : { childText : "" , childNumber : 0 } } as FormData ,
35
+ {
36
+ longText : "" ,
37
+ text : "" ,
38
+ number : 123 ,
39
+ enum : "option1" ,
40
+ boolean : false ,
41
+ object : { childText : "" , childNumber : 0 } ,
42
+ array : [ "Item 1" , "Item 2" ] ,
43
+ objectArray : [
44
+ { boolean : true , text : "Item 1" } ,
45
+ { boolean : false , text : "Item 2" }
46
+ ]
47
+ } as FormData ,
29
48
validate
30
49
) ;
31
50
@@ -118,10 +137,12 @@ export function ExampleForm() {
118
137
< FormInput form = { form } type = "checkbox" name = "text" setUndefinedOnUncheck value = "" />
119
138
< FormInput form = { form } name = "text" hideWhenNull />
120
139
</ div >
121
- < pre > { `
140
+ < pre >
141
+ { `
122
142
<FormInput form={form} type="checkbox" name="text" setUndefinedOnUncheck value="" />
123
143
<FormInput form={form} name="text" hideWhenNull />
124
- ` } </ pre >
144
+ ` }
145
+ </ pre >
125
146
126
147
{ /* Object field */ }
127
148
< label > Object field</ label >
@@ -139,7 +160,8 @@ export function ExampleForm() {
139
160
) }
140
161
/>
141
162
</ div >
142
- < pre > { `
163
+ < pre >
164
+ { `
143
165
<ChildForm
144
166
form={form}
145
167
name="parentObjectFieldName"
@@ -149,19 +171,198 @@ export function ExampleForm() {
149
171
</div>
150
172
)}
151
173
/>
152
- ` } </ pre >
174
+ ` }
175
+ </ pre >
153
176
154
177
{ /* Set object field to undefined on uncheck */ }
155
178
< label > Toggle object</ label >
156
179
< FormInput form = { form } type = "checkbox" name = "object" setUndefinedOnUncheck value = { { childNumber : 0 , childText : "" } } />
157
- < pre > { `
180
+ < pre >
181
+ { `
158
182
<FormInput
159
183
form={form}
160
184
type="checkbox"
161
185
name="fieldName"
162
186
setUndefinedOnUncheck
163
187
value={{ childDefaultFieldValue: "" }}
164
- /> ` } </ pre >
188
+ /> ` }
189
+ </ pre >
190
+
191
+ { /* Simple string array */ }
192
+ < label > String array</ label >
193
+ < ArrayForm
194
+ form = { form }
195
+ name = "array"
196
+ render = { ( { form } ) => (
197
+ < ul >
198
+ { form . values . map ( ( _ , i ) => (
199
+ < li key = { i } >
200
+ < FormInput form = { form } name = { i } />
201
+ </ li >
202
+ ) ) }
203
+ </ ul >
204
+ ) }
205
+ />
206
+ < pre >
207
+ { `
208
+ <ArrayForm
209
+ form={form}
210
+ name="array"
211
+ render={({ form }) => (
212
+ <ul>
213
+ {form.values.map((_, i) => (
214
+ <li key={i}>
215
+ <FormInput form={form} name={i} />
216
+ </li>
217
+ ))}
218
+ </ul>
219
+ )}
220
+ />` }
221
+ </ pre >
222
+
223
+ { /* Dynamic string array */ }
224
+ < label > Dynamic string array</ label >
225
+ < ArrayForm
226
+ form = { form }
227
+ name = "array"
228
+ render = { ( { form, append, remove } ) => (
229
+ < ul >
230
+ { form . values . map ( ( _ , i ) => (
231
+ < li key = { i } >
232
+ < FormInput form = { form } name = { i } />
233
+ < button onClick = { ( ) => remove ( i ) } > Remove</ button >
234
+ </ li >
235
+ ) ) }
236
+ < button type = "button" onClick = { ( ) => append ( "" ) } >
237
+ Add
238
+ </ button >
239
+ </ ul >
240
+ ) }
241
+ />
242
+ < pre >
243
+ { `
244
+ <ArrayForm
245
+ form={form}
246
+ name="arrayFieldName"
247
+ render={({ form, append, remove }) => (
248
+ <div>
249
+ <ul>
250
+ {form.values.map((_, i) => (
251
+ <li key={i}>
252
+ <FormInput form={form} name={i} />
253
+ <button onClick={() => remove(i)}>Remove</button>
254
+ </li>
255
+ ))}
256
+ </ul>
257
+ <button type="button" onClick={() => append("")}>
258
+ Add
259
+ </button>
260
+ </div>
261
+ )}
262
+ /> ` }
263
+ </ pre >
264
+
265
+ { /* Object array */ }
266
+ < label > Object array</ label >
267
+ < ArrayForm
268
+ form = { form }
269
+ name = "objectArray"
270
+ render = { ( { form } ) => (
271
+ < ul >
272
+ { form . values . map ( ( _ , i ) => (
273
+ < ChildForm
274
+ form = { form }
275
+ name = { i }
276
+ render = { ( form ) => (
277
+ < div >
278
+ < FormInput form = { form } name = "text" />
279
+ < FormInput form = { form } name = "boolean" type = "checkbox" />
280
+ </ div >
281
+ ) }
282
+ />
283
+ ) ) }
284
+ </ ul >
285
+ ) }
286
+ />
287
+ < pre >
288
+ { `
289
+ <ArrayForm
290
+ form={form}
291
+ name="objectArrayField"
292
+ render={({ form }) => (
293
+ <ul>
294
+ {form.values.map((_, i) => (
295
+ <ChildForm
296
+ form={form}
297
+ name={i}
298
+ render={(form) => (
299
+ <div>
300
+ <FormInput form={form} name="objectFieldName" />
301
+ </div>
302
+ )}
303
+ />
304
+ ))}
305
+ </ul>
306
+ )}
307
+ /> ` }
308
+ </ pre >
309
+
310
+ { /* Dynamic object array */ }
311
+ < label > Dynamic object array</ label >
312
+ < ArrayForm
313
+ form = { form }
314
+ name = "objectArray"
315
+ render = { ( { form, append, remove } ) => (
316
+ < ul >
317
+ { form . values . map ( ( _ , i ) => (
318
+ < ChildForm
319
+ form = { form }
320
+ name = { i }
321
+ render = { ( form ) => (
322
+ < div >
323
+ < FormInput form = { form } name = "text" />
324
+ < FormInput form = { form } name = "boolean" type = "checkbox" />
325
+ < button type = "button" onClick = { ( ) => remove ( i ) } >
326
+ Remove
327
+ </ button >
328
+ </ div >
329
+ ) }
330
+ />
331
+ ) ) }
332
+ < button type = "button" onClick = { ( ) => append ( { text : "" , boolean : false } ) } >
333
+ Add item
334
+ </ button >
335
+ </ ul >
336
+ ) }
337
+ />
338
+ < pre >
339
+ { `
340
+ <ArrayForm
341
+ form={form}
342
+ name="objectArrayField"
343
+ render={({ form, append, remove }) => (
344
+ <ul>
345
+ {form.values.map((_, i) => (
346
+ <ChildForm
347
+ form={form}
348
+ name={i}
349
+ render={(form) => (
350
+ <div>
351
+ <FormInput form={form} name="objectFieldName" />
352
+ <button type="button" onClick={() => remove(i)}>
353
+ Remove
354
+ </button>
355
+ </div>
356
+ )}
357
+ />
358
+ ))}
359
+ <button type="button" onClick={() => append({ objectFieldName: "default value" })}>
360
+ Add item
361
+ </button>
362
+ </ul>
363
+ )}
364
+ />` }
365
+ </ pre >
165
366
</ form >
166
367
) ;
167
368
}
0 commit comments