**Today i was working on too my much forms so i was trying to make it more dynamic**
**Do you mean like this**
**My Validation schema generator**
import testFormModel from './testFormModel';
import * as yup from 'yup';
const { formField } = testFormModel;
const [firstName] = formField;
const dynamicValidationGenerator = formField => {
//dynamic required validation for required field
const validateObj = {};
formField.map(field => {
field.required &&
Object.assign(validateObj, {
[field.name]: yup
.string()
.required(`${field.errorText.requiredErrorMsg}`),
});
});
return validateObj;
};
//for manual validation + dynamic validation
export default yup.object().shape({
...dynamicValidationGenerator(formField),
[firstName.name]: yup.string().min(5),
});
**my form model**
export default {
formId: 'testForm',
formField: [
{
name: 'firstName',
label: 'First Name',
required: true,
errorText: {
requiredErrorMsg: 'Required message',
},
},
{
name: 'lastName',
label: 'Last Name',
required: true,
errorText: {
requiredErrorMsg: 'Required message',
},
},
{ name: 'email', label: 'Email' },
{ name: 'age', label: 'Age' },
{ name: 'gender', label: 'Gender' },
],
};
**Initial form field value generator**
const initialFormValueGenerator = formField => {
const initialValues = {};
formField.map(el => Object.assign(initialValues, { [el.name]: '' }));
return initialValues;
};
export default initialFormValueGenerator;
**Input field**
import React from 'react';
import { useField } from 'formik';
function InputField(props) {
const { errorText, ...rest } = props;
const [field] = useField(props);
return (
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<label>{props.label}</label>
{props?.required && <span style={{ color: 'red' }}>*</span>}
<input
type='text'
onChange={value => console.log(value)}
name={props.name}
{...field}
{...rest}
/>
</div>
);
}
export default InputField;
**Form field html **
import React from 'react';
import InputField from '../FormField/InputField';
function AddressForm(props) {
const { formField } = props;
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: 20,
padding: 20,
}}
>
{formField.map(field => {
return (
<div key={field.name}>
<InputField {...field} />
</div>
);
})}
</div>
);
}
export default AddressForm;
**App.js**
import { Formik, Form } from 'formik';
import React from 'react';
import AddressForm from './Features/Form/AddressForm';
import testFormModel from './Features/FormModel/testFormModel';
import validationSchema from './Features/FormModel/validationSchema';
import initialFormValueGenerator from './Features/Form/formInitialValues';
function App() {
const { formId, formField } = testFormModel;
const _handleSubmit = value => {
console.log('submitted', value);
};
return (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div
style={{
width: '50%',
border: '1px solid black',
display: 'flex',
flexDirection: 'column',
marginTop: 20,
padding: 20,
backgroundColor: 'orange',
}}
>
<Formik
initialValues={initialFormValueGenerator(formField)}
validationSchema={validationSchema}
onSubmit={_handleSubmit}
>
{() => (
<Form id={formId}>
<AddressForm formField={formField} />
<div>
<button type='submit'>Submit</button>
</div>
</Form>
)}
</Formik>
</div>
</div>
);
}
export default App;
field1
andfield2
known at compile time? Otherwise there would really be no point in typinguserSchema
. – Cherri