|
1 | | -/* eslint react/prop-types: "off" */ |
| 1 | +/* eslint-disable react/prop-types */ |
2 | 2 | import React, { Fragment, useState } from 'react'; |
3 | | -import FormRender, { componentTypes, useFormApi, useFieldApi } from '@data-driven-forms/react-form-renderer'; |
| 3 | +import FormRender, { componentTypes, useFormApi, useFieldApi, FieldArray } from '@data-driven-forms/react-form-renderer'; |
4 | 4 |
|
5 | | -// eslint-disable-next-line no-unused-vars |
6 | 5 | const wrapperStyles = { |
7 | 6 | padding: 16, |
8 | 7 | borderRadius: 4, |
9 | | - fontFamily: 'Roboto', |
| 8 | + fontFamily: 'Roboto' |
10 | 9 | }; |
11 | 10 |
|
12 | | -const getBackgroundColor = variant => ({ |
13 | | - primary: 'RebeccaPurple', |
14 | | - add: 'LimeGreen', |
15 | | - remove: '#FF4136', |
16 | | -}[variant] || '#888'); |
| 11 | +const getBackgroundColor = (variant) => |
| 12 | + ({ |
| 13 | + primary: 'RebeccaPurple', |
| 14 | + add: 'LimeGreen', |
| 15 | + remove: '#FF4136' |
| 16 | + }[variant] || '#888'); |
17 | 17 |
|
18 | | -const getButtonStyle = variant => ({ |
| 18 | +const getButtonStyle = (variant) => ({ |
19 | 19 | color: 'White', |
20 | 20 | backgroundColor: getBackgroundColor(variant), |
21 | 21 | padding: '8px 16px', |
22 | 22 | borderRadius: 4, |
23 | 23 | cursor: 'pointer', |
24 | 24 | border: 'none', |
25 | | - marginRight: 4, |
| 25 | + marginRight: 4 |
26 | 26 | }); |
27 | 27 |
|
28 | | -const Button = ({ children, label, variant, ...props }) => <button style={ getButtonStyle(variant) } { ...props }>{ label }</button>; |
| 28 | +const Button = ({ children, label, variant, ...props }) => ( |
| 29 | + <button style={getButtonStyle(variant)} {...props}> |
| 30 | + {label} |
| 31 | + </button> |
| 32 | +); |
29 | 33 |
|
30 | 34 | const TextField = (props) => { |
31 | | - const {input, meta: { touched, error }, label, isRequired, ...rest} = useFieldApi(props) |
| 35 | + const { |
| 36 | + input, |
| 37 | + meta: { touched, error }, |
| 38 | + label, |
| 39 | + isRequired, |
| 40 | + ...rest |
| 41 | + } = useFieldApi(props); |
32 | 42 | return ( |
33 | | - <div className={ `ddorg__demo-formGroup ${isRequired ? 'required' : ''} ${error ? 'error' : ''}` }> |
34 | | - <label htmlFor={ input.name }>{ label }</label> |
35 | | - <br /> |
36 | | - <input id={ input.name } { ...input } { ...rest } /> |
37 | | - { touched && error && <p className="error-text">{ error }</p> } |
38 | | - <br /> |
39 | | - </div> |
40 | | -)}; |
41 | | - |
42 | | -const ArrayItem = ({ |
43 | | - fields, |
44 | | - fieldIndex, |
45 | | - name, |
46 | | - remove, |
47 | | -}) => { |
| 43 | + <div className={`ddorg__demo-formGroup ${isRequired ? 'required' : ''} ${error ? 'error' : ''}`}> |
| 44 | + <label htmlFor={input.name}>{label}</label> |
| 45 | + <br /> |
| 46 | + <input id={input.name} {...input} {...rest} /> |
| 47 | + {touched && error && <p className="error-text">{error}</p>} |
| 48 | + <br /> |
| 49 | + </div> |
| 50 | + ); |
| 51 | +}; |
| 52 | + |
| 53 | +const ArrayItem = ({ fields, fieldIndex, name, remove }) => { |
48 | 54 | const { renderForm } = useFormApi(); |
49 | 55 | const editedFields = fields.map((field) => ({ ...field, name: `${name}.${field.name}` })); |
50 | 56 |
|
51 | 57 | return ( |
52 | 58 | <React.Fragment> |
53 | | - { renderForm(editedFields) } |
| 59 | + {renderForm(editedFields)} |
54 | 60 | <br /> |
55 | | - <Button |
56 | | - onClick={ () => remove(fieldIndex) } |
57 | | - label="Remove" |
58 | | - type="button" |
59 | | - variant="remove" |
60 | | - /> |
| 61 | + <Button onClick={() => remove(fieldIndex)} label="Remove" type="button" variant="remove" /> |
61 | 62 | <br /> |
62 | 63 | <br /> |
63 | 64 | <br /> |
64 | 65 | </React.Fragment> |
65 | 66 | ); |
66 | 67 | }; |
67 | 68 |
|
68 | | -const FieldArray = ({ |
69 | | - fieldKey, |
70 | | - arrayValidator, |
71 | | - title, |
72 | | - description, |
73 | | - fields, |
74 | | - itemDefault, |
75 | | - meta, |
76 | | - FieldArrayProvider, |
77 | | - ...rest |
78 | | -}) => { |
| 69 | +const FieldArrayCustom = (props) => { |
| 70 | + const { fieldKey, arrayValidator, title, description, fields, itemDefault, meta, ...rest } = useFieldApi(props); |
79 | 71 | const { dirty, submitFailed, error } = meta; |
80 | 72 | const isError = (dirty || submitFailed) && error && typeof error === 'string'; |
81 | 73 |
|
82 | 74 | return ( |
83 | | - <FieldArrayProvider key={ fieldKey } name={ rest.input.name } validate={ arrayValidator }> |
84 | | - { (cosi) => ( |
| 75 | + <FieldArray key={fieldKey} name={rest.input.name} validate={arrayValidator}> |
| 76 | + {(cosi) => ( |
85 | 77 | <Fragment> |
86 | | - { title && <h3>{ title }</h3> } |
87 | | - { description && <p>{ description }</p> } |
88 | | - { cosi.fields.map((name, index) => ( |
| 78 | + {title && <h3>{title}</h3>} |
| 79 | + {description && <p>{description}</p>} |
| 80 | + {cosi.fields.map((name, index) => ( |
89 | 81 | <ArrayItem |
90 | | - key={ `${name || fieldKey}-${index}` } |
91 | | - fields={ fields } |
92 | | - name={ name } |
93 | | - fieldKey={ fieldKey } |
94 | | - fieldIndex={ index } |
95 | | - remove={ cosi.fields.remove } |
96 | | - />)) } |
97 | | - { isError && error } |
| 82 | + key={`${name || fieldKey}-${index}`} |
| 83 | + fields={fields} |
| 84 | + name={name} |
| 85 | + fieldKey={fieldKey} |
| 86 | + fieldIndex={index} |
| 87 | + remove={cosi.fields.remove} |
| 88 | + /> |
| 89 | + ))} |
| 90 | + {isError && error} |
98 | 91 | <br /> |
99 | | - <Button |
100 | | - type="button" |
101 | | - variant="add" |
102 | | - onClick={ () => cosi.fields.push(itemDefault) } |
103 | | - label="Add +"/> |
| 92 | + <Button type="button" variant="add" onClick={() => cosi.fields.push(itemDefault)} label="Add +" /> |
104 | 93 | <br /> |
105 | 94 | <br /> |
106 | 95 | </Fragment> |
107 | | - ) } |
108 | | - </FieldArrayProvider>); |
| 96 | + )} |
| 97 | + </FieldArray> |
| 98 | + ); |
109 | 99 | }; |
110 | 100 |
|
111 | 101 | const componentMapper = { |
112 | 102 | [componentTypes.TEXT_FIELD]: TextField, |
113 | | - [componentTypes.FIELD_ARRAY]: FieldArray, |
| 103 | + [componentTypes.FIELD_ARRAY]: FieldArrayCustom |
| 104 | +}; |
| 105 | + |
| 106 | +const FormTemplate = ({ formFields }) => { |
| 107 | + const { handleSubmit, valid } = useFormApi(); |
| 108 | + |
| 109 | + return ( |
| 110 | + <form onSubmit={handleSubmit} style={wrapperStyles}> |
| 111 | + {formFields} |
| 112 | + <Button type="submit" label="Submit" variant="primary" disabled={!valid} /> |
| 113 | + </form> |
| 114 | + ); |
114 | 115 | }; |
115 | 116 |
|
116 | 117 | const FieldArrayProvider = () => { |
117 | | - const [ values, setValues ] = useState(undefined); |
| 118 | + const [values, setValues] = useState(undefined); |
118 | 119 |
|
119 | 120 | const schema = { |
120 | | - fields: [{ |
121 | | - component: componentTypes.FIELD_ARRAY, |
122 | | - name: 'nice_people', |
123 | | - fieldKey: 'field_array', |
124 | | - title: 'Nice people', |
125 | | - description: 'This allow you to add nice people to the list dynamically', |
126 | | - itemDefault: { name: 'enter a name', lastName: 'enter a last name' }, |
127 | | - fields: [{ |
128 | | - component: componentTypes.TEXT_FIELD, |
129 | | - name: 'name', |
130 | | - label: 'Name', |
131 | | - }, { |
132 | | - component: componentTypes.TEXT_FIELD, |
133 | | - name: 'lastName', |
134 | | - label: 'Last Name', |
135 | | - }], |
136 | | - }], |
| 121 | + fields: [ |
| 122 | + { |
| 123 | + component: componentTypes.FIELD_ARRAY, |
| 124 | + name: 'nice_people', |
| 125 | + fieldKey: 'field_array', |
| 126 | + title: 'Nice people', |
| 127 | + description: 'This allow you to add nice people to the list dynamically', |
| 128 | + itemDefault: { name: 'enter a name', lastName: 'enter a last name' }, |
| 129 | + fields: [ |
| 130 | + { |
| 131 | + component: componentTypes.TEXT_FIELD, |
| 132 | + name: 'name', |
| 133 | + label: 'Name' |
| 134 | + }, |
| 135 | + { |
| 136 | + component: componentTypes.TEXT_FIELD, |
| 137 | + name: 'lastName', |
| 138 | + label: 'Last Name' |
| 139 | + } |
| 140 | + ] |
| 141 | + } |
| 142 | + ] |
137 | 143 | }; |
138 | 144 |
|
139 | 145 | const onSubmit = (values) => console.log(values); |
140 | 146 |
|
141 | 147 | return ( |
142 | 148 | <React.Fragment> |
143 | 149 | <FormRender |
144 | | - componentMapper={ componentMapper } |
145 | | - FormTemplate={ () => null } |
146 | | - schema={ schema } |
147 | | - onSubmit={ onSubmit } |
148 | | - onStateUpdate={ ({ values }) => setValues(values) } |
| 150 | + componentMapper={componentMapper} |
| 151 | + FormTemplate={FormTemplate} |
| 152 | + schema={schema} |
| 153 | + onSubmit={onSubmit} |
| 154 | + debug={({ values }) => setValues(values)} |
149 | 155 | /> |
150 | 156 | <div style={{ marginTop: 16 }}> |
151 | 157 | <h3>Form values</h3> |
152 | | - <pre> |
153 | | - { JSON.stringify(values, null, 2) } |
154 | | - </pre> |
| 158 | + <pre>{JSON.stringify(values, null, 2)}</pre> |
155 | 159 | </div> |
156 | 160 | </React.Fragment> |
157 | 161 | ); |
|
0 commit comments