This component will generate a form template you can use to generate form fields with an object:

Source: /g/xampp8/htdocs/laravel/StudentTodo/StudentTodoV2

Usage:

To add a single field in the exisiting form useState Object. The example below calls the first property object.

{generateField(form['myselect'], 'myselect')} // calls form.myselect

 

To call dyanmically to a new field that is not in the useState object and a new field:

                                        {generateField({
                                            type: "text",
                                            title: "Top Min",
                                            name: "topMin",
                                            value: "1",
                                            maxLength:"3",
                                             size:"2",
                                            className: "form-control"
                                        }, 'topMin')}

 

Math.jsx file:

import { useState } from "react";
function Math() {
    const handleSubmit = (e) => {
        e.preventDefault();
       // console.log(`LINE 73 e=`, e);
        //console.log(`LINE 73 form=`, form);
        const postData = {};
        for (let [fieldName, field] of Object.entries(form)){
            //console.log(`LINE 73a fieldName=`, fieldName);
            postData[field.name] = field.value;
        }
        console.log(`LINE 73b postData=`, postData);
        // SEND VIA AXIOS
    }
    const [form, setForm] = useState(
        {
            myselect: { type: "select", title: "My Select", name: "select", dataValues: [{ '+': 'Addition' }, { '-': 'Substraction' }, { '*': 'Multiplication' }, { '/': 'Dvision' }], value: '+' },
            mytextarea: { type: "textarea", title: "Textarea Box", name: "name", value: "This is the text area default value" },
            myradio: { type: "radio", title: "Radios", name: "radio", dataValues: ['one', 'two', 'three'], value: "" },
            mycheckbox: { type: "checkbox", title: "CheckBoxes", name: "checkbox", checked: false, value: "agree" },
            mytext: { type: "text", title: "Your Name", name: "name", value: "John", className: "form-control" },
            myemail: { type: "email", title: "Email", name: "email", value: "[email protected]", className: "form-control" },
            mypassword: { type: "password", title: "Password", name: "password", value: "pass124", className: "form-control" }, //onChange: 'handleAction'
            mysubmit: { type: "submit", title: "Submit", name: "submit", value: "Submit", className: "btn btn-primary" }, //onChange: 'handleAction'
        }
    );
    const updateRadio = (fieldName, index, value) => {
        const new_form = { ...form }; // copy the array
        if (new_form[fieldName].type == 'radio') {
            new_form[fieldName]['dataValues'][index] = value;
            new_form[fieldName]['value'] = value;
        } else if (new_form[fieldName].type == 'checkbox') {
            new_form[fieldName]['checked'] = !new_form[fieldName]['checked']; // toggle checkbox
        } else if (new_form[fieldName].type == 'select') {
        } else {
            // input:text,password...
            new_form[fieldName]['value'] = value;
        }
        setForm(new_form); // return a new data object
    }
    const generateField = (field, fieldName) => {
        switch (field.type) {
            case 'textarea':
                return <textarea
                    defaultValue={form[fieldName].value}
                    className="form-control"
                    // rows={4}
                    // cols={40}
                    name={form[fieldName].name}
                    onChange={(e) => setForm(
                        {
                            ...form, [fieldName]: {
                                ...form[fieldName],
                                value: e.target.value
                            }
                        })}
                ></textarea>
                break;
            case 'checkbox':
                return (<div className="form-check">
                    <input
                        className="form-check-input"
                        type="checkbox"
                        id={`${fieldName}`}
                        name={form[fieldName].name}
                        value={form[fieldName].value}
                        onChange={(e) => updateRadio(fieldName, '', e.target.value)}
                    />
                    <label className="form-check-label" htmlFor={`${fieldName}`}>
                        {form[fieldName].value} | {form[fieldName].checked}
                    </label>
                </div>
                )
                break;
            case 'radio':
                return (
                    <>
                        {form[fieldName].dataValues.map((value, index) => {
                            return (
                                <div className={`form-${field.type}`} key={index}>
                                    <input
                                        type={field.type}
                                        id={`${fieldName}`}
                                        className="form-check-input"
                                        name={form[fieldName].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={form[fieldName].name}
                        id={`${field.name}`}
                        className="form-select"
                        aria-label="Default select example"
                        onChange={(e) => updateRadio(fieldName, '', e.target.value)}
                        defaultValue={form[fieldName].value}
                    >
                        {form[fieldName].dataValues.map((value, index) => <option
                            key={index}
                            value={Object.keys(value)[0]}
                        >{value[Object.keys(value)[0]]}</option>)}
                    </select>
                )
                break;
            default: return <input
                {...form[fieldName]}
                onChange={(e) => updateRadio(fieldName, '', e.target.value)}
            />
                break;
        }
    }
    return (
        <>
            <div className="container">
                <div className="row">
                    <form onSubmit={handleSubmit}>
                        {Object.entries(form).map(([fieldName, field], index) => {
                            return (
                                <div className="mb-3" key={index}>
                                    {/* <pre>{JSON.stringify(field, null, 2)}</pre> */}
                                    <label htmlFor={fieldName} className="form-label">{field.title}</label>
                                    {generateField(field, fieldName)}
                                    {field.description && <div className="form-text">{field.description}</div>}
                                </div>
                            )
                        })}
                    </form>
                </div>
            </div>
        </>
    )
}
export default Math