@simpleform/render 3.0.7 → 3.0.9
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.md +84 -45
- package/README_CN.md +81 -43
- package/lib/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
English | [中文说明](./README_CN.md)
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@simpleform/render)
|
|
6
6
|
|
|
7
7
|
> A lightweight dynamic forms engine that makes it easy to dynamically render forms.
|
|
8
8
|
|
|
@@ -307,65 +307,103 @@ export default function Demo(props) {
|
|
|
307
307
|
### 4. List Demo
|
|
308
308
|
Support for array rendering
|
|
309
309
|
```javascript
|
|
310
|
-
import React, { useState } from 'react';
|
|
311
|
-
import FormRender, { useSimpleForm } from './form-render';
|
|
310
|
+
import React, { useEffect, useState } from 'react';
|
|
311
|
+
import FormRender, { CustomFormRenderProps, useSimpleForm } from './form-render';
|
|
312
312
|
import { Button } from 'antd';
|
|
313
|
-
|
|
313
|
+
|
|
314
|
+
const OptionList = React.forwardRef<HTMLElement, any>((props, ref) => {
|
|
315
|
+
|
|
316
|
+
const {
|
|
317
|
+
value,
|
|
318
|
+
onChange,
|
|
319
|
+
...rest
|
|
320
|
+
} = props;
|
|
321
|
+
|
|
322
|
+
const intialValue = [{ label: '', value: '' }];
|
|
323
|
+
const [dataSource, setDataSource] = useState<Array<any>>([]);
|
|
314
324
|
const form = useSimpleForm();
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
+
|
|
326
|
+
useEffect(() => {
|
|
327
|
+
const options = value || [...intialValue];
|
|
328
|
+
setDataSource(options);
|
|
329
|
+
form.setFieldsValue(options);
|
|
330
|
+
}, [value]);
|
|
331
|
+
|
|
332
|
+
const widgetList = dataSource.map((item, index) => ({
|
|
333
|
+
type: 'row',
|
|
334
|
+
props: {
|
|
335
|
+
gutter: 12,
|
|
336
|
+
align: 'middle',
|
|
337
|
+
className: classes.item
|
|
338
|
+
},
|
|
339
|
+
widgetList: [
|
|
325
340
|
{
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
341
|
+
name: `[${index}]label`,
|
|
342
|
+
compact: true,
|
|
343
|
+
outside: { type: 'col', props: { span: 9 } },
|
|
344
|
+
rules: [{ required: true }],
|
|
330
345
|
type: 'Input',
|
|
331
|
-
props: {
|
|
346
|
+
props: {
|
|
347
|
+
placeholder: 'label',
|
|
348
|
+
style: { width: '100%' }
|
|
349
|
+
}
|
|
332
350
|
},
|
|
333
351
|
{
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
352
|
+
name: `[${index}]value`,
|
|
353
|
+
compact: true,
|
|
354
|
+
outside: { type: 'col', props: { span: 9 } },
|
|
355
|
+
rules: [{ required: true }],
|
|
338
356
|
type: 'Input',
|
|
339
|
-
props: {
|
|
357
|
+
props: {
|
|
358
|
+
placeholder: 'value',
|
|
359
|
+
style: { width: '100%' }
|
|
360
|
+
}
|
|
340
361
|
},
|
|
341
362
|
{
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
rules: [{ required: true, message: 'list[3] empty' }],
|
|
345
|
-
initialValue: 4,
|
|
346
|
-
type: 'Input',
|
|
347
|
-
props: {}
|
|
363
|
+
outside: { type: 'col', props: { span: 6 } },
|
|
364
|
+
typeRender: <Button type="link" onClick={() => deleteItem(index)}>delete</Button>
|
|
348
365
|
},
|
|
349
|
-
]
|
|
366
|
+
]
|
|
367
|
+
}));
|
|
368
|
+
|
|
369
|
+
const deleteItem = (index: number) => {
|
|
370
|
+
const oldData = [...dataSource];
|
|
371
|
+
if (!oldData) return;
|
|
372
|
+
const newData = [...oldData];
|
|
373
|
+
newData.splice(index, 1);
|
|
374
|
+
setDataSource(newData);
|
|
375
|
+
onChange && onChange(newData);
|
|
376
|
+
};
|
|
350
377
|
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
378
|
+
const addItem = () => {
|
|
379
|
+
const { error } = await form.validate();
|
|
380
|
+
if (error) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const newDataSource = dataSource.concat(intialValue);
|
|
384
|
+
setDataSource(newDataSource);
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const onFieldsChange: CustomFormRenderProps['onFieldsChange'] = ({ value }, values) => {
|
|
388
|
+
setDataSource(values);
|
|
389
|
+
onChange && onChange(values);
|
|
355
390
|
};
|
|
356
391
|
|
|
357
392
|
return (
|
|
358
|
-
<div
|
|
393
|
+
<div>
|
|
359
394
|
<FormRender
|
|
360
395
|
form={form}
|
|
361
396
|
widgetList={widgetList}
|
|
397
|
+
onFieldsChange={onFieldsChange}
|
|
362
398
|
/>
|
|
363
|
-
<
|
|
364
|
-
|
|
365
|
-
</
|
|
399
|
+
<Button type="link" onClick={addItem}>
|
|
400
|
+
add
|
|
401
|
+
</Button>
|
|
366
402
|
</div>
|
|
367
403
|
);
|
|
368
|
-
}
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
export default OptionList;
|
|
369
407
|
```
|
|
370
408
|
## API
|
|
371
409
|
|
|
@@ -460,12 +498,13 @@ export interface GenerateParams<T = {}> {
|
|
|
460
498
|
form?: SimpleForm;
|
|
461
499
|
};
|
|
462
500
|
```
|
|
463
|
-
###
|
|
464
|
-
|
|
501
|
+
### Rules for the name field of form controls
|
|
502
|
+
The `name` field can indicate the location path of a field in an array or object.
|
|
503
|
+
|
|
465
504
|
Example:
|
|
466
|
-
- `a[0]` denotes the first option below the array
|
|
467
|
-
- `a.b`
|
|
468
|
-
- `a[0].b`
|
|
505
|
+
- `a[0]` denotes the first option below the array a
|
|
506
|
+
- `a.b` indicates the b attribute of the a object
|
|
507
|
+
- `a[0].b` denotes the b attribute of the first option below array a
|
|
469
508
|
|
|
470
509
|
### String Expression Usage
|
|
471
510
|
Property fields in a form node can support string expressions for linkage, except for `widgetList`.
|
package/README_CN.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[English](./README.md) | 中文说明
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@simpleform/render)
|
|
6
6
|
|
|
7
7
|
> 轻量级动态表单引擎,实现动态渲染表单很简单.
|
|
8
8
|
|
|
@@ -308,67 +308,105 @@ export default function Demo(props) {
|
|
|
308
308
|
}
|
|
309
309
|
```
|
|
310
310
|
### 4. 数组数据
|
|
311
|
-
|
|
311
|
+
复杂的列表渲染增删改功能demo
|
|
312
312
|
```javascript
|
|
313
|
-
import React, { useState } from 'react';
|
|
314
|
-
import FormRender, { useSimpleForm } from './form-render';
|
|
313
|
+
import React, { useEffect, useState } from 'react';
|
|
314
|
+
import FormRender, { CustomFormRenderProps, useSimpleForm } from './form-render';
|
|
315
315
|
import { Button } from 'antd';
|
|
316
|
-
|
|
316
|
+
|
|
317
|
+
const OptionList = React.forwardRef<HTMLElement, any>((props, ref) => {
|
|
318
|
+
|
|
319
|
+
const {
|
|
320
|
+
value,
|
|
321
|
+
onChange,
|
|
322
|
+
...rest
|
|
323
|
+
} = props;
|
|
324
|
+
|
|
325
|
+
const intialValue = [{ label: '', value: '' }];
|
|
326
|
+
const [dataSource, setDataSource] = useState<Array<any>>([]);
|
|
317
327
|
const form = useSimpleForm();
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
+
|
|
329
|
+
useEffect(() => {
|
|
330
|
+
const options = value || [...intialValue];
|
|
331
|
+
setDataSource(options);
|
|
332
|
+
form.setFieldsValue(options);
|
|
333
|
+
}, [value]);
|
|
334
|
+
|
|
335
|
+
const widgetList = dataSource.map((item, index) => ({
|
|
336
|
+
type: 'row',
|
|
337
|
+
props: {
|
|
338
|
+
gutter: 12,
|
|
339
|
+
align: 'middle',
|
|
340
|
+
className: classes.item
|
|
341
|
+
},
|
|
342
|
+
widgetList: [
|
|
328
343
|
{
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
344
|
+
name: `[${index}]label`,
|
|
345
|
+
compact: true,
|
|
346
|
+
outside: { type: 'col', props: { span: 9 } },
|
|
347
|
+
rules: [{ required: true }],
|
|
333
348
|
type: 'Input',
|
|
334
|
-
props: {
|
|
349
|
+
props: {
|
|
350
|
+
placeholder: 'label',
|
|
351
|
+
style: { width: '100%' }
|
|
352
|
+
}
|
|
335
353
|
},
|
|
336
354
|
{
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
355
|
+
name: `[${index}]value`,
|
|
356
|
+
compact: true,
|
|
357
|
+
outside: { type: 'col', props: { span: 9 } },
|
|
358
|
+
rules: [{ required: true }],
|
|
341
359
|
type: 'Input',
|
|
342
|
-
props: {
|
|
360
|
+
props: {
|
|
361
|
+
placeholder: 'value',
|
|
362
|
+
style: { width: '100%' }
|
|
363
|
+
}
|
|
343
364
|
},
|
|
344
365
|
{
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
rules: [{ required: true, message: 'list[3] empty' }],
|
|
348
|
-
initialValue: 4,
|
|
349
|
-
type: 'Input',
|
|
350
|
-
props: {}
|
|
366
|
+
outside: { type: 'col', props: { span: 6 } },
|
|
367
|
+
typeRender: <Button type="link" onClick={() => deleteItem(index)}>delete</Button>
|
|
351
368
|
},
|
|
352
|
-
]
|
|
369
|
+
]
|
|
370
|
+
}));
|
|
371
|
+
|
|
372
|
+
const deleteItem = (index: number) => {
|
|
373
|
+
const oldData = [...dataSource];
|
|
374
|
+
if (!oldData) return;
|
|
375
|
+
const newData = [...oldData];
|
|
376
|
+
newData.splice(index, 1);
|
|
377
|
+
setDataSource(newData);
|
|
378
|
+
onChange && onChange(newData);
|
|
379
|
+
};
|
|
353
380
|
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
381
|
+
const addItem = () => {
|
|
382
|
+
const { error } = await form.validate();
|
|
383
|
+
if (error) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
const newDataSource = dataSource.concat(intialValue);
|
|
387
|
+
setDataSource(newDataSource);
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
const onFieldsChange: CustomFormRenderProps['onFieldsChange'] = ({ value }, values) => {
|
|
391
|
+
setDataSource(values);
|
|
392
|
+
onChange && onChange(values);
|
|
358
393
|
};
|
|
359
394
|
|
|
360
395
|
return (
|
|
361
|
-
<div
|
|
396
|
+
<div>
|
|
362
397
|
<FormRender
|
|
363
398
|
form={form}
|
|
364
399
|
widgetList={widgetList}
|
|
400
|
+
onFieldsChange={onFieldsChange}
|
|
365
401
|
/>
|
|
366
|
-
<
|
|
367
|
-
|
|
368
|
-
</
|
|
402
|
+
<Button type="link" onClick={addItem}>
|
|
403
|
+
add
|
|
404
|
+
</Button>
|
|
369
405
|
</div>
|
|
370
406
|
);
|
|
371
|
-
}
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
export default OptionList;
|
|
372
410
|
```
|
|
373
411
|
|
|
374
412
|
## API
|
|
@@ -465,8 +503,8 @@ export interface GenerateParams<T = {}> {
|
|
|
465
503
|
form?: SimpleForm;
|
|
466
504
|
};
|
|
467
505
|
```
|
|
468
|
-
###
|
|
469
|
-
|
|
506
|
+
### 表单控件name字段的规则
|
|
507
|
+
`name`字段可表示数组或对象中某个属性字段的位置路径
|
|
470
508
|
|
|
471
509
|
举例:
|
|
472
510
|
- `a[0]`表示数组a下面的第一个选项
|