The plan is I give to this factory class an array of objects, and that gives me beck a Formik config with filled Yup validation. After then the getFrom method of my factory class generates the entire form also that can I directly rendering now with react.
But I doen't know any method to solve that for example Yup.string().required().max(2, "error") method chain built up in my class.
Plases give me some direction where can I find solutions for this problem.
// this the form describing array of objects:
const exampleFields = [
{
name: "First name",
inputType: "text",
valueType: "string",
label: "Enter your first name",
initialValue: "",
placeholder: "Enter first name here...",
stylingClasses: {
inputCotanierClasses: "w-100",
labelClasses: "text-left",
inputClassess: "border-0 border-bottom border-dark",
errorClasses: "text-danger",
},
validation: {
required: { message: "First name is required" },
min: {
value: 2,
message: "First name must be at least 2 characters",
},
max: {
value: 15,
message: "first name must be at most 15 characters",
},
},
},
{
name: "Last name",
inputType: "number",
valueType: "number",
label: "Enter your last name",
initialValue: "",
placeholder: "Enter last name here...",
validation: {
required: { message: "Last name is required" },
min: {
value: 2,
message: "Last name must be at least 2 characters",
},
max: {
value: 10,
message: "Last name must be at most 10 characters",
},
},
},
{
name: "email",
inputType: "text",
valueType: "email",
label: "Enter your email",
initialValue: "",
placeholder: "Enter yout emial here...",
validation: {
required: { message: "Email is required" },
email: true,
},
},
];
//and this is my factory class:
import React from "react";
import * as Yup from "yup";
export default class FormFactory {
constructor(fields, submit, Yup) {
this.submit = submit;
const buildUpValidation = (Yup, validation, { message, value }) => {
return Yup[validation](message, value);
};
fields.forEach((field) => {
const initialYup = Yup[field.valueType]();
const validations = Object.entries(field.validation);
validations.forEach((validation) => {
const [validationType, params] = validation;
console.log(validationType, params);
buildUpValidation(initialYup, validationType, params || true);
});
});
//this.validationSchema = Yup.object().shape({});
//console.log(this.validationSchema);
}
getConfig() {
return {
initialValues: this.initialValues,
validationSchema: this.validationSchema,
onSubmit: (values) => this.submit(values),
};
}
generateField(
formik,
{ label, id, name, key, inputType, placeholder, stylingClasses }
) {
return (
<div
key={key}
className={`input-container ${stylingClasses?.inputCotanierClasses && stylingClasses.inputCotanierClasses}`
}
>
{label && (
<label
className={
stylingClasses?.labelClasses && stylingClasses.labelClasses
}
htmlFor={id || name}
>
{label}
</label>
)}
<input
id={id || name}
className={
stylingClasses?.inputClassess && stylingClasses.inputClassess
}
name={name || id}
type={inputType || "text"}
value={formik.values[name || id]}
placeholder={placeholder}
onBlur={formik.handleBlur}
onChange={formik.handleChange}
/>
<>
{formik.touched[name || id] && formik.errors[name || id] ? (
<p
className={
stylingClasses.errorClasses && stylingClasses.errorClasses
}
>
{formik.errors[name || id]}
</p>
) : null}
</>
</div>
);
}
getForm(formik) {
return this.fields.map((field, key) =>
this.generateField(formik, { ...field, key })
);
}
}
//and the usage is the followings:
import React from "react";
import { useFormik } from "formik";
import FormFactory from "./FormFactory";
const SignUpFormikFactory = () => {
const singUpForm = new FormFactory(exampleFields, (values) =>
console.log(values)
);
// console.log(singUpForm.getConfig());
const formik = useFormik({ ...singUpForm.getConfig() });
// console.table("| formik.values", formik.values);
// console.table("| formik.errors", formik.errors);
// console.table("| formik.touched", formik.touched);
return (
<form onSubmit={formik.handleSubmit}>
<div className="form-container">
{singUpForm.getForm(formik)}
<button type="submit">Submit</button>
</div>
</form>
);
};
export default SignUpFormikFactory;
/*********************/
/* And in the app is */
/*********************/
import "./App.css";
import SignUp from "./SignUp";
import SignUpFormik from "./SignUpFormik";
import SignUpFormikFactory from "./SignUpFormikFactory";
function App() {
return (
<div className="App">
<SignUpFormikFactory />
</div>
);
}
export default App;