Skip to content

Instantly share code, notes, and snippets.

@Joeldorne
Last active June 24, 2024 11:39
Show Gist options
  • Select an option

  • Save Joeldorne/b7f62a388f68d9de58e7da7c17a42226 to your computer and use it in GitHub Desktop.

Select an option

Save Joeldorne/b7f62a388f68d9de58e7da7c17a42226 to your computer and use it in GitHub Desktop.
import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import { z } from 'zod';
// Example JSON schema for form fields
const jsonSchema = {
fields: [
{
name: 'name',
type: 'text',
label: 'Name',
validation: z.string().max(15, { message: 'Name must be 15 characters or less' }).optional(),
},
{
name: 'email',
type: 'email',
label: 'Email',
validation: z.string().email({ message: 'Invalid email address format' }).optional(),
},
{
name: 'password',
type: 'password',
label: 'Password',
validation: z.string().min(6, { message: 'Password must be at least 6 characters' }).optional(),
}
]
};
const SignupForm = () => {
const initialValues = {};
const validationSchema = {};
// Dynamically build initialValues and validationSchema from jsonSchema using Zod
jsonSchema.fields.forEach(field => {
initialValues[field.name] = '';
validationSchema[field.name] = field.validation;
});
const onSubmit = (values, { setSubmitting }) => {
setTimeout(() => {
console.log(values);
setSubmitting(false);
}, 400);
};
return (
<Formik
initialValues={initialValues}
validationSchema={z.object(validationSchema)}
onSubmit={onSubmit}
>
{({ isSubmitting }) => (
<Form className="max-w-md mx-auto">
{jsonSchema.fields.map(field => (
<div key={field.name} className="mb-4">
<label htmlFor={field.name} className="block text-gray-700">{field.label}</label>
<Field
name={field.name}
type={field.type}
className={`mt-1 block w-full border border-gray-300 rounded-md ${
// Add red border if field has an error
isSubmitting && field.name in validationSchema ? 'border-red-500' : ''
}`}
/>
<ErrorMessage name={field.name}>
{msg => <div className="text-red-500 text-sm">{msg}</div>}
</ErrorMessage>
</div>
))}
<button type="submit" disabled={isSubmitting} className="bg-blue-500 text-white py-2 px-4 rounded">
Submit
</button>
</Form>
)}
</Formik>
);
};
export default SignupForm;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment