Skip to content

Commit 5083502

Browse files
author
bietkul
committed
2 parents acc14e5 + 273a52a commit 5083502

File tree

1 file changed

+302
-0
lines changed

1 file changed

+302
-0
lines changed

docs/api/FormGenerator.md

Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,303 @@
11

2+
# FormGenerator
3+
A react component which generates a tree of control objects & render the UI by keeping the same order in which the controls have been defined in `fieldConfig`.
4+
5+
## How it works
6+
- It creates a new instance of [FormGroup](FormGroup.md) ( if `controls` property is an object ) or
7+
[FormArray](FormArray.md) ( if `controls` property is an array ) if the `control` property is not supplied.
8+
- It renders the form UI according to the control-component mapping by keeping the same order in which they have been
9+
defined in `fieldConfig`.
10+
- You can define a parent control by passing the `parent` property.
11+
- If a `control` prop is defined then it just returns the same.
12+
13+
14+
## Props
15+
```ts
16+
onMount: (form: FormGroup|FormArray) => void
17+
```
18+
A function callback called when a form has been rendered, the basic use case is to save the form instance for further uses.
19+
##
20+
```ts
21+
onUnmount: () => void
22+
```
23+
A function callback called when a form has been unmounted.
24+
##
25+
```ts
26+
fieldConfig: {[key: string]: any}
27+
```
28+
Field config has a set of properties which are required for the form configuration.
29+
30+
### Properties of `fieldConfig`
31+
```ts
32+
controls: Array<{[key: string]: any}> | {[key: string]: any};
33+
```
34+
FormGenerator creates a [FormGroup](FormGroup.md) if the `controls` property is an object.
35+
36+
For example the following config will create a [FormGroup](FormGroup.md) with two form controls named `username` & `password` respectively.
37+
```ts
38+
const fieldConfig = {
39+
controls: {
40+
username: {
41+
...
42+
},
43+
password: {
44+
....
45+
}
46+
}
47+
}
48+
```
49+
50+
FormGenerator creates a [FormArray](FormArray.md) if the `controls` property is an array.
51+
52+
For example the following config will create a [FormArray](FormArray.md) with two form controls at index `0` & `1` respectively.
53+
54+
```ts
55+
const fieldConfig = {
56+
controls: [
57+
{
58+
... // item1
59+
},
60+
{
61+
... // item2
62+
}
63+
]
64+
}
65+
```
66+
67+
#### Nested Controls
68+
You can also define the nested controls in the same way.
69+
70+
Example: Nested controls in `FormGroup`
71+
```ts
72+
const fieldConfig = {
73+
controls: {
74+
address: {
75+
controls: {
76+
city: {
77+
...
78+
},
79+
country: {
80+
...
81+
}
82+
}
83+
}
84+
}
85+
}
86+
```
87+
The above example will create a structure like that:
88+
```ts
89+
{
90+
address: {
91+
city: "",
92+
country: ""
93+
}
94+
}
95+
```
96+
97+
Example: Nested controls in `FormArray`
98+
99+
```ts
100+
const fieldConfig = {
101+
controls: [
102+
{
103+
// item1
104+
controls: {
105+
itemName: {
106+
....
107+
},
108+
itemPrice: {
109+
...
110+
}
111+
}
112+
},
113+
{
114+
// item2
115+
}
116+
]
117+
}
118+
```
119+
The above example will create a structure like that:
120+
```ts
121+
[
122+
{
123+
itemName: "",
124+
itemPrice: ""
125+
},
126+
"" // item2
127+
]
128+
```
129+
##
130+
```ts
131+
formState: any|{ value: any, disabled: boolean }
132+
```
133+
You can use this property to define the initial state of the control.
134+
### Note:
135+
Only works with [FormControl](FormControl.md)
136+
137+
##
138+
```ts
139+
meta: {[key: string]: any};
140+
```
141+
You can pass an object of custom inputs to customize your component.
142+
143+
##
144+
```ts
145+
render: (control: FormArray|FormControl|FormGroup) => React.ReactElement<any>|React.ReactElement<any>[];
146+
```
147+
A render function prop which returns a react component which needs to be re-render whenever the control state changes.
148+
149+
### Note:
150+
Only works with [FormControl](FormControl.md)
151+
152+
For example:
153+
```ts
154+
const fieldConfig = {
155+
controls: {
156+
username: {
157+
render: TextInput // some react component to render an input,
158+
meta: {
159+
label: "Username"
160+
}
161+
},
162+
password: {
163+
render: TextInput,
164+
meta: {
165+
label: "Password",
166+
type: "password"
167+
}
168+
}
169+
}
170+
}
171+
```
172+
##
173+
174+
```ts
175+
index: number
176+
```
177+
To define at which index the controls has to be inserted if the parent control is an instance of [FormArray](FormArray.md).
178+
179+
### Note:
180+
Only works if the parent is [FormArray](FormArray.md).
181+
182+
##
183+
```ts
184+
options: AbstractControlOptions;
185+
```
186+
You can pass the [AbstractControlOptions](AbstractControlOptions.md) as `options` props.
187+
188+
For example:
189+
```ts
190+
const fieldConfig = {
191+
controls: {
192+
username: {
193+
render: TextInput // some react component to render an input,
194+
meta: {
195+
label: "Username"
196+
}
197+
options: {
198+
validators: Validators.required,
199+
updateOn: 'blur'
200+
}
201+
},
202+
password: {
203+
render: TextInput,
204+
meta: {
205+
label: "Password",
206+
type: "password"
207+
},
208+
options: {
209+
validators: Validators.required,
210+
}
211+
}
212+
}
213+
}
214+
```
215+
216+
217+
##
218+
```ts
219+
control: AbstractControl;
220+
```
221+
An instance of [AbstractControl](AbstractControl.md) control.
222+
223+
##
224+
```ts
225+
parent: AbstractControl;
226+
```
227+
An instance of [FormGroup](FormGroup.md) or [FormArray](FormArray.md) class as a parent control.
228+
229+
## Inject a component
230+
FormGenerator generates the UI in the same order in which the controls have been defined in the `formConfig`, so sometime you may need to add a component in between the controls.
231+
FormGenerator provides this facility by defining a `$field_` property to determine that the control is not need to be added so it just renders the component.
232+
233+
If the parent is `FormGroup` then you can inject a component by defining the control name starts with`$field_`.
234+
235+
For Example:
236+
```ts
237+
const fieldConfig = {
238+
controls: {
239+
$field_0: {
240+
render: () => <span>Username:</span>
241+
},
242+
username: {
243+
render: TextInput,
244+
},
245+
$field_1: {
246+
render: () => <span>Password:</span>
247+
},
248+
password: {
249+
render: TextInput,
250+
meta: {
251+
label: "Password",
252+
type: "password"
253+
}
254+
}
255+
}
256+
}
257+
```
258+
If the parent is `FormArray` then you can inject a component by defining the control's index starts with`$field_`.
259+
260+
```ts
261+
const fieldConfig = {
262+
controls: [
263+
{
264+
index: "$field_0"
265+
render: () => <span>Item1:</span>
266+
},
267+
{
268+
render: TextInput
269+
},
270+
{
271+
index: "$field_1"
272+
render: () => <span>Item2:</span>
273+
},
274+
{
275+
render: TextInput
276+
}
277+
]
278+
}
279+
```
280+
You can also access the root control object by using the `$field_` control & subscribe the component for the form state changes by just defining the `isStatic` property as `false`.
281+
282+
For example:
283+
284+
```ts
285+
const fieldConfig = {
286+
controls: {
287+
username: {
288+
render: TextInput,
289+
},
290+
password: {
291+
render: TextInput,
292+
meta: {
293+
label: "Password",
294+
type: "password"
295+
}
296+
},
297+
$field_0: {
298+
isStatic: false,
299+
render: ({ invalid }) => <button disabled={invalid}>Submit</button>
300+
},
301+
}
302+
}
303+
```

0 commit comments

Comments
 (0)