This is version 4 for form fields for react MDB:

Source: /g/xampp8/htdocs/laravel/StudentTodo/StudentTodoV4/React-Laravel-MDB-API-SSL-AuthenticationV3

It in git also:

1. Use Context

use context for the fields constant

 import { useStateContext } from "../../../context/ContextProvider.jsx";
....
const {formValue, setFormValue } = useStateContext();
const [isLoading, setIsLoading] = useState(false); // used for showing skeleton in the form when submitted
const [errorMessageObj, setErrorMessageArr] = useState(null); // used for showing backend errors

 

2. Context provider:

export const ContextProvider = ({ children }) => {
const [formValue, setFormValue] = useState([]);
...
    return (
...
            notification,
            setNotification,
)

 

3. UseEffect to initialize the context values:

    useEffect(() => {
        setFormValue(this_formValue);
        // reload DOM only when submit changes
    }, [isLoading])

 

4. The useState const

Set a temporary holder for the context variable

    const this_formValue = [
        { divider: "Create Your Account" },
        // name row
        {

            name: {
                postMessage: "",
                required: true,
                value: '',
                errorMsg: 'Please enter your name.',
                type: 'text',
                label: 'Your Name',
            },
 
        },
        {
            email: {
                value: '',
                errorMsg: 'Please enter a valid email',
                type: 'email',
                label: 'Email',
                required: true,
                preMessage: "Email address",

            }
        },
        {
            password: {
                value: '',
                errorMsg: 'Please enter a valid password',
                type: 'password',
                label: 'Password',
                preMessage: "Secret Password",
            }
        },
        {
            password_confirmation: {
                value: '',
                errorMsg: 'Please enter a valid password',
                type: 'password',
                label: 'Repeat Password',
            }
        },
        {
            submit: {
                value: 'Create Account',
                type: 'submit',
                color: "primary",
                className: "",
                block: true,
                size: 'lg',
                isLoading: isLoading
            }
        },
        { // you can use section to add non fields after a field
            section: {
                type: 'section',
                content:
                    <div className='text-center'><Link to="/login">Already a member? Sign In!</Link></div>
            }
        }
    ];

 

5. JSX Usage

    return (
        <section className="vh-100" style={{ backgroundColor: "#508bfc" }}>
            <div className="container py-5 v-100">
                <div className="row d-flex justify-content-center align-items-center h-100">
                    <div className="col-12 col-md-8 col-lg-6 col-xl-5">
                        <div className="card shadow-2-strong" style={{ borderRadius: "1rem" }}>
                            <div className="card-body ">
                                <MDBValidation className='row g-3 ' onSubmit={e => OnsubmitForm(e)} id='myform'>
                                    {errorMessageObj && !isLoading &&
                                        <MDBContainer className="">
                                            <ol className='w-100 alert alert-danger'>
                                                {Object.entries(errorMessageObj).map(([field, value], index) =>
                                                    <li key={index} className='text-danger'>{field}: {value}</li>
                                                )}
                                            </ol>
                                        </MDBContainer>
                                    }
                                    {
                                        formValue && formValue.map((group, index) => {
                                            return (
                                                <div key={index}>
                                                    {
                                                        typeof group.divider != "undefined" ?
                                                            <h4 className="my-3  text-center" style={{ borderBottom: '1px solid #000', lineHeight: '0.1em', margin: '10px 0 20x' }}><span style={{ background: "#FFF", padding: "0 10px" }}>{group.divider}</span></h4>
                                                            :
                                                            <MDBRow className="mt-3" >
                                                                {Object.entries(group).map(([fieldname, field], index2) => {
                                                                    return (
                                                                        <MDBCol key={index2} size={`sm-${12 / Object.entries(group).length}`}>
                                                                            <MDBValidationItem feedback={field.errorMsg} invalid className='col-md-12' >
                                                                                {GenerateField(field, fieldname, index, group, formValue, setFormValue, isLoading)}
                                                                            </MDBValidationItem>
                                                                        </MDBCol>
                                                                    )
                                                                })}
                                                            </MDBRow>
                                                    }
                                                </div>
                                            )
                                        })}
                                </MDBValidation>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    );

 

6. The GenerateFields component:

import { React, useState, useEffect } from 'react';
import { useStateContext } from "../../context/ContextProvider";
import { MDBBtn, MDBCheckbox, MDBCol, MDBInput, MDBSpinner } from 'mdb-react-ui-kit';
import Skeleton from 'react-loading-skeleton'
import 'react-loading-skeleton/dist/skeleton.css'
export const GenerateField = (field, fieldName, index, group, formValue, setFormValue, isLoading) => {
    //console.log(`LINE 8 field=`, field);
    switch (field.type) {
        case 'section':
            return field.content;
            break;
        case 'textarea':
            return <textarea
                defaultValue={field.value}
                className="form-control"
                // rows={4}
                // cols={40}
                name={field.name}
                onChange={(e) => setForm(
                    {
                        ...form, [fieldName]: {
                            ...field[fieldName],
                            value: e.target.value
                        }
                    })}
            ></textarea>
            break;
        case 'checkbox':
            console.log(`LINE 39 field=`, field);
            return (
                <MDBCheckbox
                    name={fieldName}
                    value={field.value}
                    id={fieldName}
                    label={field.label}
                    onChange={(e) => { updateFieldValue(e, formValue, setFormValue) }}
                />
            )
            break;
        case 'radio':
            return (
                <>
                    {field.dataValues.map((value, index) => {
                        return (
                            <div className={`form-${field.type}`} key={index}>
                                <input
                                    type={field.type}
                                    id={`${fieldName}`}
                                    className="form-check-input"
                                    name={field.name}
                                    value={value}
                                    onChange={(e) => updateRadio(fieldName, index, e.target.value)}
                                />
                                <label className="form-check-label" htmlFor={`${fieldName}`}>
                                    {value} | {index}
                                </label>
                            </div>
                        )
                    })}
                </>
            )
        case 'select':
            return (
                <select
                    name={field.name}
                    id={`${field.name}`}
                    className="form-select"
                    aria-label="Default select example"
                    onChange={(e) => updateRadio(fieldName, '', e.target.value)}