1.4.5 • Published 4 years ago
react-form-from-json v1.4.5
react-form-from-json
Create dynamic forms from json config file
Install
npm i react-form-from-json
or
yarn add react-form-from-json
Dev
In root run with concurrently (which is installed globally npm i -g concurrently
)
concurrently "yarn start" "cd example && yarn start" "cd example && json-server --watch example-json.json --port 3100"
Usage
Form properties
handler
-> Each field has handler prop, which defines what to do with input (see example apphandleInput
)fields
-> An array of fields, which will be rendered in the applicationdisplayUnder
-> Whether or not should fields be rendered next to the labels, iftrue
field will be rendere under the label (seeRendered
section),true
by default
Example code with axios request (response json shown below)
import React, { FormEvent, useEffect, useState } from 'react'
import { Form } from 'react-form-from-json'
import get from 'axios'
const App = () => {
const [payload, setPayload] = useState({})
const [form, setForm] = useState({
name: '',
fields: []
})
const handleInput = (key: string, value: any) => {
setPayload((prevPayload) => ({ ...prevPayload, [key]: value }))
}
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
//Submit Action
}
useEffect(() => {
get('http://localhost:3100/form', {
method: 'GET'
}).then((res: any) => {
setForm(res.data)
})
}, [])
return (
<div>
<form
method='post'
id='generated-form'
onSubmit={(e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
handleSubmit(e)
}}
>
<legend>{form.name}</legend>
<Form fields={form.fields} handler={handleInput} displayUnder={true} />
<button type='submit'>Submit</button>
</form>
</div>
)
}
export default App
Form works with following fields formats
JSON (with currently working input types)
Full example json is in example\example-json.json
{
...some other properties,
"form": {
"name": "Some Dummy Form",
"fields": [
{
"name": "Dummy email",
"subtype": "email",
"type": "string"
},
{
"name": "Dummy number",
"subtype": "number",
"type": "string"
},
{
"name": "Dummy password",
"subtype": "password",
"type": "string"
},
{
"name": "Dummy search",
"subtype": "search",
"type": "string"
},
{
"name": "Dummy tel",
"subtype": "tel",
"type": "string"
},
{
"name": "Dummy text",
"subtype": "text",
"type": "string"
},
{
"name": "Dummy url",
"subtype": "url",
"type": "string"
},
{
"name": "Dummy checkbox",
"subtype": "checkbox",
"type": "boolean",
"className": "some dummy class"
},
{
"name": "Dummy select",
"type": "select",
"values": [
{
"key": "key-1",
"value": "Value 1"
},
{
"key": "key-2",
"value": "Value 2"
},
{
"key": "key-3",
"value": "Value 3"
},
{
"key": "key-4",
"value": "Value 4"
}
]
},
{
"name": "Dummy textarea",
"type": "textarea",
"rows": 4,
"cols": 20
},
{
"name": "Dummy textarea no cols, no rows",
"type": "textarea"
},
{
"name": "Dummy range",
"type": "range",
"min": 0,
"max": 10
},
{
"name": "Dummy radio",
"type": "radio",
"values": [
{
"key": "rad1",
"value": "Value 1"
},
{
"key": "rad2",
"value": "Value 2"
}
]
},
{
"name": "Dummy file",
"type": "file"
},
{
"name": "Dummy date",
"type": "date",
"subtype": "date",
"min": "2020-10-05",
"max": "2020-11-01",
"format": "dd. MM. yyyy",
"className": "some dummy class"
},
{
"name": "Dummy color",
"type": "string",
"subtype": "color"
}
]
}
}
CSS (index.css of App)
.field-text div {
width: 1000px;
}
.field-text input {
height: 1.5vh;
}
.field-text label {
color: green;
}
.field-area div {
width: 1000px;
}
.field-area input {
height: 1.5vh;
}
.field-area label {
color: violet;
}
.field-select div {
width: 1000px;
}
.field-select select {
height: 1.5vh;
}
.field-select option {
height: 1.5vh;
}
.field-select label {
color: brown;
}
.field-range div {
width: 1000px;
}
.field-range input {
height: 1.5vh;
}
.field-range label {
color: blanchedalmond;
}
.field-radio div {
width: 100px;
}
.field-radio input {
height: 1.5vh;
}
.field-radio p {
color: tomato;
}
.field-radio label {
color: aquamarine;
}
.field-file div {
width: 1000px;
}
.field-file input {
height: 1.5vh;
}
.field-file label {
color: yellowgreen;
}
.field-date div {
width: 1000px;
}
.field-date input {
height: 1.5vh;
}
.field-date label {
color: red;
}
.field-checkbox div {
width: 1000px;
}
.field-checkbox input {
height: 1.5vh;
}
.field-checkbox label {
color: bisque;
}
Added custom class names for each field
You can add the class name into the json
{
"name": "Dummy checkbox",
"subtype": "checkbox",
"type": "boolean",
"className": "some dummy class"
}
or just expand field array before passing it down as props
Rendered
When displayUnder
prop is true
Roadmap
Arrays- JSON
- Change state of field
- Fill payload
- Form submit action
- ClassNames
- Default ClassNames
- Custom ClassNames for each field
- Global ClassNames
- Styles from file as prop
- Default values
- Input types
- Date inputs
- Date
- Formats
- Min - Max
- Exclude dates
- Include dates
- Filter dates
- Higligh dates
- Date
- Selectors
- Select
- Checkbox
- Color
- File
- Radio
- Range
- Min - Max
- Datalist
- Text inputs
- Text
- URL
- Tel
- Number
- Password
- TextArea
Search
- MISC
HiddenResetSubmit
- Date inputs
- Validators - regex from json parameter
{
"name": "Email field",
"subtype": "email",
"type": "string",
"validator": "/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i"
},
License
MIT © johnathan-codes