17
A React Material UI Library to Build Any Form With Only JSON Config
Suppose we want to create a form to collect shipping address. Here's how we can replicate the form below with just JSON config and the open-source library I built @jeremyling/react-material-ui-form-builder
.
const fields = [
{
title: "Shipping Address",
component: "display-text",
titleProps: {
style: {
fontSize: 20,
marginTop: 16,
fontWeight: "bold",
userSelect: "none",
fontVariant: "small-caps",
marginBottom: 8,
},
},
},
{
col: {
xs: 6,
},
label: "First Name",
props: {
required: true,
},
attribute: "firstName",
component: "text-field",
validations: {
label: "First Name",
required: "Required",
},
validationType: "string",
},
{
col: {
xs: 6,
},
label: "Last Name",
props: {
required: true,
},
attribute: "lastName",
component: "text-field",
validations: {
label: "Last Name",
required: "Required",
},
validationType: "string",
},
{
label: "Address Line 1",
props: {
required: true,
},
attribute: "address1",
component: "text-field",
validations: {
label: "Address 1",
required: "Required",
},
validationType: "string",
},
{
label: "Address Line 2",
attribute: "address2",
component: "text-field",
validations: {
label: "Address 2",
},
validationType: "string",
},
{
col: {
xs: 6,
},
label: "City",
attribute: "city",
component: "text-field",
validations: {
label: "City",
},
validationType: "string",
},
{
col: {
xs: 6,
},
label: "State",
attribute: "state",
component: "text-field",
validations: {
label: "State",
},
validationType: "string",
},
{
col: {
xs: 6,
},
label: "Postcode",
props: {
required: true,
},
attribute: "postcode",
component: "text-field",
validations: {
label: "Postcode",
required: "Required",
},
validationType: "string",
},
{
col: {
xs: 6,
},
label: "Country",
props: {
required: true,
},
attribute: "country",
component: "text-field",
validations: {
label: "Country",
required: "Required",
},
validationType: "string",
},
{
options: [
{
label: "Same as Billing",
value: true,
},
],
optionConfig: {
key: "label",
label: "label",
value: "value",
},
attribute: "sameAsBilling",
component: "checkbox-group",
},
];
import React, { useRef, useState } from "react";
import { FormBuilder } from "@jeremyling/react-material-ui-form-builder";
import { Button } from "@mui/material";
import { get, isEmpty } from "lodash";
async function validate(refs, form) {
var errors = {};
for (const [attribute, ref] of Object.entries(refs.current)) {
if (ref.validate) {
const error = await ref.validate(get(form, attribute));
if (error.length) {
errors[attribute] = error;
}
}
}
if (!isEmpty(errors)) {
console.log(errors);
return false;
}
return true;
}
export default function ShippingAddress() {
const [form, setForm] = useState({});
const refs = useRef({});
const updateForm = (updates) => {
const copy = { ...form };
for (const [key, value] of Object.entries(updates)) {
copy[key] = value;
}
setForm(copy);
};
const handleNext = async (event) => {
event.preventDefault();
const ok = await validate(refs, form);
if (!ok) {
return;
}
console.log(form);
};
return (
<>
<FormBuilder
fields={fields}
form={form}
updateForm={updateForm}
refs={refs}
/>
<Button
type="submit"
variant="contained"
color="primary"
sx={{ mt: 1 }}
onClick={handleNext}
>
Next
</Button>
</>
);
}
Here, we only use a few components from the library, display-text
, text-field
and checkbox-group
. There are many more you can use. You can view the documentation here. Just note, in general, all input components would have these core field props.
{
...
title: "State", // Display text above the input
label: "State", // Input label
attribute: "state", // Attribute of the form to set/control
component: "text-field", // Type of component
col: {
// Breakpoints and corresponding width (1 - 12)
xs: 6,
sm: 6,
...
},
validations: {
// Any validations accepted by yup
required: true,
length: 10,
min: 5,
max: 20,
matches: ['/[a-z]/i', 'Can only contain letters'],
email: true,
url: true,
uuid: true,
},
}
I actually created the form above with 3 clicks and a few renames on FormBlob. Try it out and make building forms a breeze. If you're a developer, contact us and I'll turn on a feature for you to export the forms you build into your own project. Alternatively, you can even build and deploy a hosted form entirely on FormBlob and embed the form in your own domain. If you use this method, you don’t have to use React in your app and it still works out of the box!
If data privacy is a concern, you can define webhooks to call on each submission to pass the form data to your own backend. If you choose, FormBlob does not store any data on our servers beyond the form structure.
17