@simpleform/render 3.0.14 → 3.0.16
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 +4 -542
- package/README_CN.md +1 -1
- package/lib/index.js +1 -1
- package/lib/types.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
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
|
|
|
9
9
|
## Introduction
|
|
10
|
-
- Component
|
|
11
|
-
- Component Description(`widgetList`): We use a list to describe the
|
|
12
|
-
- Component Rendering: `Form` component handles
|
|
10
|
+
- Component registration (`components` property): We need to register form controls and non-form components before using them, in case of form controls we need to support `value` and `onChange` `props` inside the control.
|
|
11
|
+
- Component Description (`widgetList` property): We use a list to describe the UI structure, each item in the list represents a component node. Node nesting is supported.
|
|
12
|
+
- Component Rendering: `Form` component handles form values, `FormChildren` component handles form rendering, a `Form` component can support multiple `FormChildren` components for internal rendering.
|
|
13
13
|
- Component linkage: All form properties can support string expressions to describe linkage conditions (except `widgetList` property).
|
|
14
14
|
|
|
15
15
|
## install
|
|
@@ -20,541 +20,3 @@ npm install @simpleform/render --save
|
|
|
20
20
|
# 或者
|
|
21
21
|
yarn add @simpleform/render
|
|
22
22
|
```
|
|
23
|
-
## Quick Start
|
|
24
|
-
|
|
25
|
-
### 1. First register the basic components (Take antd@5.x as an example)
|
|
26
|
-
```javascript
|
|
27
|
-
// register
|
|
28
|
-
import DefaultFormRender, { FormChildren as DefaultFormChildren, FormRenderProps, FormChildrenProps } from '@simpleform/render';
|
|
29
|
-
import '@simpleform/render/lib/css/main.css';
|
|
30
|
-
import React from 'react';
|
|
31
|
-
import dayjs from 'dayjs';
|
|
32
|
-
import {
|
|
33
|
-
Input,
|
|
34
|
-
InputNumber,
|
|
35
|
-
Checkbox,
|
|
36
|
-
DatePicker,
|
|
37
|
-
Mentions,
|
|
38
|
-
Radio,
|
|
39
|
-
Rate,
|
|
40
|
-
Select,
|
|
41
|
-
Slider,
|
|
42
|
-
Switch,
|
|
43
|
-
TimePicker,
|
|
44
|
-
TreeSelect,
|
|
45
|
-
} from 'antd';
|
|
46
|
-
|
|
47
|
-
export * from '@simpleform/render';
|
|
48
|
-
|
|
49
|
-
export const widgets = {
|
|
50
|
-
"Input": Input,
|
|
51
|
-
"Input.TextArea": Input.TextArea,
|
|
52
|
-
"Input.Password": Input.Password,
|
|
53
|
-
"Input.Search": Input.Search,
|
|
54
|
-
"InputNumber": InputNumber,
|
|
55
|
-
"Checkbox": Checkbox,
|
|
56
|
-
'Checkbox.Group': Checkbox.Group,
|
|
57
|
-
"DatePicker": DatePicker,
|
|
58
|
-
"DatePicker.RangePicker": DatePicker.RangePicker,
|
|
59
|
-
"Mentions": Mentions,
|
|
60
|
-
"Mentions.Option": Mentions.Option,
|
|
61
|
-
"Radio": Radio,
|
|
62
|
-
"Radio.Group": Radio.Group,
|
|
63
|
-
"Radio.Button": Radio.Button,
|
|
64
|
-
"Rate": Rate,
|
|
65
|
-
"Select": Select,
|
|
66
|
-
"Select.Option": Select.Option,
|
|
67
|
-
"TreeSelect": TreeSelect,
|
|
68
|
-
"Slider": Slider,
|
|
69
|
-
"Switch": Switch,
|
|
70
|
-
"TimePicker": TimePicker,
|
|
71
|
-
"TimePicker.RangePicker": TimePicker.RangePicker
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export type CustomFormChildrenProps = FormChildrenProps<any>;
|
|
75
|
-
export function FormChildren(props: CustomFormChildrenProps) {
|
|
76
|
-
const { components, plugins, ...rest } = props;
|
|
77
|
-
return (
|
|
78
|
-
<DefaultFormChildren
|
|
79
|
-
options={{ props: { autoComplete: 'off' } }}
|
|
80
|
-
components={{ ...widgets, ...components }}
|
|
81
|
-
plugins={{ ...plugins, dayjs }}
|
|
82
|
-
{...rest}
|
|
83
|
-
/>
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
export type CustomFormRenderProps = FormRenderProps<any>;
|
|
87
|
-
export default function FormRender(props: CustomFormRenderProps) {
|
|
88
|
-
const { components, plugins, ...rest } = props;
|
|
89
|
-
return (
|
|
90
|
-
<DefaultFormRender
|
|
91
|
-
options={{ props: { autoComplete: 'off' } }}
|
|
92
|
-
components={{ ...widgets, ...components }}
|
|
93
|
-
plugins={{ ...plugins, dayjs }}
|
|
94
|
-
{...rest}
|
|
95
|
-
/>
|
|
96
|
-
);
|
|
97
|
-
};
|
|
98
|
-
```
|
|
99
|
-
### 2. Introduce the components that were registered in the first step.
|
|
100
|
-
```javascript
|
|
101
|
-
import { Button } from 'antd';
|
|
102
|
-
import React, { useState } from 'react';
|
|
103
|
-
import FormRender, { useSimpleForm, useSimpleFormRender } from './form-render';
|
|
104
|
-
export default function Demo(props) {
|
|
105
|
-
|
|
106
|
-
const widgetList = [
|
|
107
|
-
{
|
|
108
|
-
label: "readonly",
|
|
109
|
-
name: 'name1',
|
|
110
|
-
readOnly: true,
|
|
111
|
-
readOnlyRender: "readonly component",
|
|
112
|
-
initialValue: 1111,
|
|
113
|
-
hidden: '{{formvalues && formvalues.name6 == true}}',
|
|
114
|
-
type: 'Input',
|
|
115
|
-
props: {}
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
label: "input",
|
|
119
|
-
name: 'name2',
|
|
120
|
-
rules: [{ required: true, message: 'input empty' }],
|
|
121
|
-
initialValue: 1,
|
|
122
|
-
hidden: '{{formvalues && formvalues.name6 == true}}',
|
|
123
|
-
type: 'Input',
|
|
124
|
-
props: {}
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
label: 'list[0]',
|
|
128
|
-
name: 'list[0]',
|
|
129
|
-
rules: [{ required: true, message: 'list[0] empty' }],
|
|
130
|
-
initialValue: { label: 'option1', value: '1', key: '1' },
|
|
131
|
-
type: 'Select',
|
|
132
|
-
props: {
|
|
133
|
-
labelInValue: true,
|
|
134
|
-
style: { width: '100%' },
|
|
135
|
-
children: [
|
|
136
|
-
{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } },
|
|
137
|
-
{ type: 'Select.Option', props: { key: 2, value: '2', children: 'option2' } }
|
|
138
|
-
]
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
label: 'list[1]',
|
|
143
|
-
name: 'list[1]',
|
|
144
|
-
rules: [{ required: true, message: 'list[1] empty' }],
|
|
145
|
-
type: 'Select',
|
|
146
|
-
props: {
|
|
147
|
-
labelInValue: true,
|
|
148
|
-
style: { width: '100%' },
|
|
149
|
-
children: [
|
|
150
|
-
{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } },
|
|
151
|
-
{ type: 'Select.Option', props: { key: 2, value: '2', children: 'option2' } }
|
|
152
|
-
]
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
label: 'first',
|
|
157
|
-
name: 'name4.first',
|
|
158
|
-
rules: [{ required: true, message: 'first empty' }],
|
|
159
|
-
type: 'Select',
|
|
160
|
-
props: {
|
|
161
|
-
style: { width: '100%' },
|
|
162
|
-
children: [{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } }]
|
|
163
|
-
}
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
label: 'second',
|
|
167
|
-
name: 'name4.second',
|
|
168
|
-
rules: [{ required: true, message: 'second empty' }],
|
|
169
|
-
type: 'Select',
|
|
170
|
-
props: {
|
|
171
|
-
style: { width: '100%' },
|
|
172
|
-
children: [{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } }]
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
{
|
|
176
|
-
label: 'name5',
|
|
177
|
-
name: 'name5',
|
|
178
|
-
initialValue: { span: 12 },
|
|
179
|
-
valueSetter: "{{(value)=> (value && value['span'])}}",
|
|
180
|
-
valueGetter: "{{(value) => ({span: value})}}",
|
|
181
|
-
type: 'Select',
|
|
182
|
-
props: {
|
|
183
|
-
style: { width: '100%' },
|
|
184
|
-
children: [
|
|
185
|
-
{ type: 'Select.Option', props: { key: 1, value: 12, children: 'option1' } },
|
|
186
|
-
{ type: 'Select.Option', props: { key: 2, value: 6, children: 'option2' } },
|
|
187
|
-
{ type: 'Select.Option', props: { key: 3, value: 4, children: 'option3' } }
|
|
188
|
-
]
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
label: 'checkbox',
|
|
193
|
-
name: 'name6',
|
|
194
|
-
valueProp: 'checked',
|
|
195
|
-
initialValue: true,
|
|
196
|
-
rules: [{ required: true, message: 'checkbox empty' }],
|
|
197
|
-
type: 'Checkbox',
|
|
198
|
-
props: {
|
|
199
|
-
style: { width: '100%' },
|
|
200
|
-
children: 'option'
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
]
|
|
204
|
-
|
|
205
|
-
const form = useSimpleForm();
|
|
206
|
-
// const formrender = useSimpleFormRender();
|
|
207
|
-
|
|
208
|
-
const onSubmit = async (e) => {
|
|
209
|
-
e?.preventDefault?.();
|
|
210
|
-
const result = await form.validate();
|
|
211
|
-
console.log(result, 'result');
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
return (
|
|
215
|
-
<div>
|
|
216
|
-
<FormRender
|
|
217
|
-
form={form}
|
|
218
|
-
// formrender={formrender}
|
|
219
|
-
widgetList={widgetList}
|
|
220
|
-
/>
|
|
221
|
-
<div style={{ marginLeft: '120px' }}>
|
|
222
|
-
<Button onClick={onSubmit}>submit</Button>
|
|
223
|
-
</div>
|
|
224
|
-
</div>
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
|
-
```
|
|
228
|
-
### 3. Multi-module rendering
|
|
229
|
-
The form engine also supports rendering by multiple `FormChildren` components, which then unify the processing of form values by the `Form` component.
|
|
230
|
-
- `useSimpleForm`: Creates a managed instance of a form value.
|
|
231
|
-
- `useSimpleFormRender`: creates an instance that renders the form.
|
|
232
|
-
```javascript
|
|
233
|
-
import React, { useState } from 'react';
|
|
234
|
-
import { FormChildren, Form, useSimpleForm } from './form-render';
|
|
235
|
-
import { Button } from 'antd';
|
|
236
|
-
export default function Demo(props) {
|
|
237
|
-
|
|
238
|
-
const widgetList1 = [{
|
|
239
|
-
label: "part1input",
|
|
240
|
-
name: 'part1',
|
|
241
|
-
rules: [{ required: true, message: 'part1 empty' }],
|
|
242
|
-
initialValue: 1,
|
|
243
|
-
type: 'Input',
|
|
244
|
-
props: {}
|
|
245
|
-
}]
|
|
246
|
-
|
|
247
|
-
const widgetList2 = [{
|
|
248
|
-
label: "part2input",
|
|
249
|
-
name: 'part2',
|
|
250
|
-
rules: [{ required: true, message: 'part2 empty' }],
|
|
251
|
-
initialValue: 1,
|
|
252
|
-
type: 'Input',
|
|
253
|
-
props: {}
|
|
254
|
-
}]
|
|
255
|
-
|
|
256
|
-
const form = useSimpleForm();
|
|
257
|
-
// const formrender1 = useSimpleFormRender()
|
|
258
|
-
// const formrender2 = useSimpleFormRender()
|
|
259
|
-
|
|
260
|
-
const onSubmit = async (e) => {
|
|
261
|
-
e?.preventDefault?.();
|
|
262
|
-
const result = await form.validate();
|
|
263
|
-
console.log(result, 'result');
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
return (
|
|
267
|
-
<div style={{ padding: '0 8px' }}>
|
|
268
|
-
<Form form={form}>
|
|
269
|
-
<div>
|
|
270
|
-
<p>part1</p>
|
|
271
|
-
<FormChildren
|
|
272
|
-
// formrender={formrender1}
|
|
273
|
-
widgetList={widgetList1}
|
|
274
|
-
/>
|
|
275
|
-
</div>
|
|
276
|
-
<div>
|
|
277
|
-
<p>part2</p>
|
|
278
|
-
<FormChildren
|
|
279
|
-
// formrender={formrender2}
|
|
280
|
-
widgetList={widgetList2}
|
|
281
|
-
/>
|
|
282
|
-
</div>
|
|
283
|
-
</Form>
|
|
284
|
-
<div style={{ marginLeft: '120px' }}>
|
|
285
|
-
<Button onClick={onSubmit}>submit</Button>
|
|
286
|
-
</div>
|
|
287
|
-
</div>
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
```
|
|
291
|
-
### 4. List Demo
|
|
292
|
-
Support for array rendering
|
|
293
|
-
```javascript
|
|
294
|
-
import React, { useEffect, useState } from 'react';
|
|
295
|
-
import FormRender, { CustomFormRenderProps, useSimpleForm } from './form-render';
|
|
296
|
-
import { Button } from 'antd';
|
|
297
|
-
|
|
298
|
-
const OptionList = React.forwardRef<HTMLElement, any>((props, ref) => {
|
|
299
|
-
|
|
300
|
-
const {
|
|
301
|
-
value,
|
|
302
|
-
onChange,
|
|
303
|
-
...rest
|
|
304
|
-
} = props;
|
|
305
|
-
|
|
306
|
-
const intialValue = [{ label: '', value: '' }];
|
|
307
|
-
const [dataSource, setDataSource] = useState<Array<any>>([]);
|
|
308
|
-
const form = useSimpleForm();
|
|
309
|
-
|
|
310
|
-
useEffect(() => {
|
|
311
|
-
const options = value || [...intialValue];
|
|
312
|
-
setDataSource(options);
|
|
313
|
-
form.setFieldsValue(options);
|
|
314
|
-
}, [value]);
|
|
315
|
-
|
|
316
|
-
const widgetList = dataSource.map((item, index) => ({
|
|
317
|
-
type: 'row',
|
|
318
|
-
props: {
|
|
319
|
-
gutter: 12,
|
|
320
|
-
align: 'middle'
|
|
321
|
-
},
|
|
322
|
-
widgetList: [
|
|
323
|
-
{
|
|
324
|
-
name: `[${index}]label`,
|
|
325
|
-
compact: true,
|
|
326
|
-
outside: { type: 'col', props: { span: 9 } },
|
|
327
|
-
rules: [{ required: true }],
|
|
328
|
-
type: 'Input',
|
|
329
|
-
props: {
|
|
330
|
-
placeholder: 'label',
|
|
331
|
-
style: { width: '100%' }
|
|
332
|
-
}
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
name: `[${index}]value`,
|
|
336
|
-
compact: true,
|
|
337
|
-
outside: { type: 'col', props: { span: 9 } },
|
|
338
|
-
rules: [{ required: true }],
|
|
339
|
-
type: 'Input',
|
|
340
|
-
props: {
|
|
341
|
-
placeholder: 'value',
|
|
342
|
-
style: { width: '100%' }
|
|
343
|
-
}
|
|
344
|
-
},
|
|
345
|
-
{
|
|
346
|
-
outside: { type: 'col', props: { span: 6 } },
|
|
347
|
-
typeRender: <Button type="link" onClick={() => deleteItem(index)}>delete</Button>
|
|
348
|
-
},
|
|
349
|
-
]
|
|
350
|
-
}));
|
|
351
|
-
|
|
352
|
-
const deleteItem = (index: number) => {
|
|
353
|
-
const oldData = [...dataSource];
|
|
354
|
-
if (!oldData) return;
|
|
355
|
-
const newData = [...oldData];
|
|
356
|
-
newData.splice(index, 1);
|
|
357
|
-
setDataSource(newData);
|
|
358
|
-
form.setFieldsValue(newData);
|
|
359
|
-
onChange && onChange(newData);
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
const addItem = async () => {
|
|
363
|
-
const { error } = await form.validate();
|
|
364
|
-
if (error) {
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
const newData = dataSource.concat(intialValue);
|
|
368
|
-
form.setFieldsValue(newData);
|
|
369
|
-
setDataSource(newData);
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
const onFieldsChange: CustomFormRenderProps['onFieldsChange'] = (_, values) => {
|
|
373
|
-
setDataSource(values);
|
|
374
|
-
onChange && onChange(values);
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
return (
|
|
378
|
-
<div>
|
|
379
|
-
<FormRender
|
|
380
|
-
form={form}
|
|
381
|
-
widgetList={widgetList}
|
|
382
|
-
onFieldsChange={onFieldsChange}
|
|
383
|
-
/>
|
|
384
|
-
<Button type="link" onClick={addItem}>
|
|
385
|
-
add
|
|
386
|
-
</Button>
|
|
387
|
-
</div>
|
|
388
|
-
);
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
export default OptionList;
|
|
392
|
-
```
|
|
393
|
-
## API
|
|
394
|
-
|
|
395
|
-
### Form`s props
|
|
396
|
-
Sourced from [@simpleform/form](../form);
|
|
397
|
-
|
|
398
|
-
### FormChildren's props
|
|
399
|
-
- `widgetList`: `WidgetItem[]` Renders the form's DSL form json data
|
|
400
|
-
- `components`: registers all components in the form.
|
|
401
|
-
- `plugins`: foreign libraries to be introduced in the form.
|
|
402
|
-
- `options`: `GenerateFormNodeProps | ((field: GenerateFormNodeProps) => any)` Parameter information passed to the form node components. The priority is lower than the form node's own parameters
|
|
403
|
-
- `renderList`: Provides a function to customize the rendered list.
|
|
404
|
-
- `renderItem`: provides a function to customize the rendering of the node.
|
|
405
|
-
- `onRenderChange`: `(newValue: WidgetList) => void;` `onRenderChange` change callback function.
|
|
406
|
-
- `formrender`: The form class responsible for rendering. Created by `useSimpleFormRender()`, optional.
|
|
407
|
-
- `form`: Class responsible for the value of the form. Created via `useSimpleForm()`, optional.
|
|
408
|
-
- `uneval`: does not execute string expressions in the form.
|
|
409
|
-
|
|
410
|
-
### SimpleFormRender's Methods
|
|
411
|
-
- `updateItemByPath`: `(data?: any, path?: string) => void` Get the corresponding node based on `path`.
|
|
412
|
-
- `setItemByPath`: `(data?: any, path?: string) => void` Sets the corresponding node according to `path`.
|
|
413
|
-
- `delItemByPath`: `(path?: string) => void` Removes the node corresponding to the path `path`.
|
|
414
|
-
- `insertItemByIndex`: `(data: WidgetItem | WidgetItem[], index?: number, parent?: string) => void` Adds a node based on the serial number and the path of the parent node.
|
|
415
|
-
- `getItemByPath`: `(path: string) => void` Get the node corresponding to the path `path`.
|
|
416
|
-
- `moveItemByPath`: `(from: { parent?: string, index: number }, to: { parent?: string, index?: number })` Swap options in the tree from one position to another
|
|
417
|
-
- `setWidgetList`: `(data?: WidgetList) => void` Sets the `widgetList` attribute of the form.
|
|
418
|
-
|
|
419
|
-
### Hooks
|
|
420
|
-
- `useSimpleFormRender()`: create `new SimpleFormRender()`.
|
|
421
|
-
- `useSimpleForm(defaultValues)`: create `new SimpleForm()`
|
|
422
|
-
|
|
423
|
-
## Other
|
|
424
|
-
|
|
425
|
-
### widgetList structure description
|
|
426
|
-
Each item in the `widgetList` list is a rendering node, rendered from `type` and `props`. divided into a form control node and nonform node.
|
|
427
|
-
- Form control nodes.
|
|
428
|
-
Nodes with the `name` attribute are form control nodes and carry the form field component (`Form.Item`) by default, for example:
|
|
429
|
-
```javascript
|
|
430
|
-
const widgetList = [{
|
|
431
|
-
label: "part2input",
|
|
432
|
-
name: 'part2',
|
|
433
|
-
rules: [{ required: true, message: 'part2 empty' }],
|
|
434
|
-
initialValue: 1,
|
|
435
|
-
type: 'Input',
|
|
436
|
-
props: {}
|
|
437
|
-
}]
|
|
438
|
-
```
|
|
439
|
-
- nonform node.
|
|
440
|
-
Nodes without the `name` attribute. Example:
|
|
441
|
-
```javascript
|
|
442
|
-
const widgetList = [{
|
|
443
|
-
type: 'CustomCard',
|
|
444
|
-
props: {}
|
|
445
|
-
}]
|
|
446
|
-
```
|
|
447
|
-
- Form Node's types
|
|
448
|
-
```javascript
|
|
449
|
-
export type GenerateWidgetItem<T extends Record<string, any> = {}> = FormItemProps & T & {
|
|
450
|
-
inside?: CustomUnionType; // The inner layer of the node
|
|
451
|
-
outside?: CustomUnionType; // The outside layer of the node
|
|
452
|
-
readOnly?: boolean; // read-only mode
|
|
453
|
-
readOnlyRender?: CustomUnionType; // Read-only mode rendering
|
|
454
|
-
typeRender?: CustomUnionType; // Registering components for custom rendering
|
|
455
|
-
hidden?: boolean;
|
|
456
|
-
type?: string; // Register the component
|
|
457
|
-
props?: Record<string, any> & { children?: any | Array<CustomWidget> }; // Register the component's props
|
|
458
|
-
widgetList?: WidgetList; // children of the component(will override props.children)
|
|
459
|
-
}
|
|
460
|
-
```
|
|
461
|
-
### parameter injection
|
|
462
|
-
- The properties of the form node are set globally:
|
|
463
|
-
Set the global properties of the form node via 'options'
|
|
464
|
-
```javascript
|
|
465
|
-
|
|
466
|
-
...
|
|
467
|
-
|
|
468
|
-
<FormRender
|
|
469
|
-
options={{
|
|
470
|
-
layout: 'vertical',
|
|
471
|
-
props: { disabled: true }
|
|
472
|
-
}}
|
|
473
|
-
/>
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
- Parameters received by the registration component of the form:
|
|
477
|
-
The registration component in the form receives a context parameter
|
|
478
|
-
```javascript
|
|
479
|
-
export interface GenerateParams<T = {}> {
|
|
480
|
-
path?: string;
|
|
481
|
-
widgetItem?: GenerateWidgetItem<T>;
|
|
482
|
-
formrender?: SimpleFormRender;
|
|
483
|
-
form?: SimpleForm;
|
|
484
|
-
};
|
|
485
|
-
```
|
|
486
|
-
### Rules for the name field of form controls
|
|
487
|
-
The `name` field can indicate the location path of a field in an array or object.
|
|
488
|
-
|
|
489
|
-
Example:
|
|
490
|
-
- `a[0]` denotes the first option below the array a
|
|
491
|
-
- `a.b` indicates the b attribute of the a object
|
|
492
|
-
- `a[0].b` denotes the b attribute of the first option below array a
|
|
493
|
-
|
|
494
|
-
### String Expression Usage
|
|
495
|
-
Property fields in a form node can support string expressions for linkage, except for `widgetList`.
|
|
496
|
-
1. Quick use: computational expressions wrapping target attribute values in `{{` and `}}`
|
|
497
|
-
```javascript
|
|
498
|
-
|
|
499
|
-
...
|
|
500
|
-
|
|
501
|
-
const widgetList = [
|
|
502
|
-
{
|
|
503
|
-
label: 'name1',
|
|
504
|
-
name: 'name1',
|
|
505
|
-
valueProp: 'checked',
|
|
506
|
-
initialValue: true,
|
|
507
|
-
type: 'Checkbox',
|
|
508
|
-
props: {
|
|
509
|
-
children: 'option'
|
|
510
|
-
}
|
|
511
|
-
},
|
|
512
|
-
{
|
|
513
|
-
label: "name2",
|
|
514
|
-
name: 'name2',
|
|
515
|
-
rules: '{{[{ required: formvalues && formvalues.name1 === true, message: "name2 empty" }]}}',
|
|
516
|
-
initialValue: 1,
|
|
517
|
-
type: 'Input',
|
|
518
|
-
props: {}
|
|
519
|
-
}
|
|
520
|
-
]
|
|
521
|
-
|
|
522
|
-
// OR
|
|
523
|
-
|
|
524
|
-
const widgetList = [
|
|
525
|
-
{
|
|
526
|
-
label: 'name1',
|
|
527
|
-
name: 'name1',
|
|
528
|
-
valueProp: 'checked',
|
|
529
|
-
initialValue: true,
|
|
530
|
-
type: 'Checkbox',
|
|
531
|
-
props: {
|
|
532
|
-
children: 'option'
|
|
533
|
-
}
|
|
534
|
-
},
|
|
535
|
-
{
|
|
536
|
-
label: "name2",
|
|
537
|
-
name: 'name2',
|
|
538
|
-
hidden: '{{formvalues && formvalues.name1 === true}}',
|
|
539
|
-
initialValue: 1,
|
|
540
|
-
type: 'Input',
|
|
541
|
-
props: {}
|
|
542
|
-
},
|
|
543
|
-
]
|
|
544
|
-
```
|
|
545
|
-
2. Rules for the use of string expressions
|
|
546
|
-
- A string has and can have only one pair of `{{` and `}}`.
|
|
547
|
-
- In addition to the three built-in variables (`form` (i.e., `useSimpleForm()`), `formrender` (i.e., `useSimpleFormRender()`), `formvalues`)), you can introduce an external variable via `plugins` and then reference the variable name directly in the string expression. in a string expression.
|
|
548
|
-
```javascript
|
|
549
|
-
import dayjs from 'dayjs';
|
|
550
|
-
import FormRender from "./form-render";
|
|
551
|
-
|
|
552
|
-
const widgetList = [{
|
|
553
|
-
label: "name3",
|
|
554
|
-
initialValue: "{{dayjs().format('YYYY-MM-DD')}}",
|
|
555
|
-
type: 'Input',
|
|
556
|
-
props: {}
|
|
557
|
-
}]
|
|
558
|
-
|
|
559
|
-
<FormRender widgetList={widgetList} plugins={{ dayjs }} />
|
|
560
|
-
```
|
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
|
|