|
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