├── .babelrc ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── debug.log ├── examples └── src │ ├── App.js │ ├── _appStyle.js │ ├── data │ └── formData.js │ ├── index.html │ └── index.js ├── package.json ├── src ├── components │ ├── CheckboxField.js │ ├── RadioButtonField.js │ ├── SelectField.js │ ├── TextAreaField.js │ ├── TextField.js │ ├── UploadField.js │ ├── _fieldStyles.js │ └── index.js ├── constants.js ├── index.js └── utils │ └── yupSchemaCreator.js ├── webpack.config.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "node": "current" 8 | } 9 | } 10 | ], 11 | "@babel/preset-react" 12 | ], 13 | "plugins": ["@babel/plugin-proposal-class-properties"] 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | build 4 | coverage -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | build 3 | coverage 4 | examples 5 | .babelrc 6 | .gitignore 7 | enzyme.setup.js 8 | jest.config.json 9 | webpack.config.js -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | MIT License 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ridoansaleh/dynamic-form-json/blob/master/LICENSE) [![dynamic-form-json version](https://img.shields.io/badge/dynamic--form--json-v1.0.9-green)](https://www.npmjs.com/package/dynamic-form-json) [![npm version](https://img.shields.io/badge/npm-v6.14.8-green)](https://www.npmjs.com/package/dynamic-form-json) 2 | 3 | # Dynamic Form Json 4 | 5 | `dynamic-form-json` is a tiny library to generate a Form in React automatically based on certain array of object that passed as a props. This library use regular css created from scratch, so user can customize it in the future. On top of it, i use [Formik](https://github.com/jaredpalmer/formik) and [Yup](https://github.com/jquense/yup) for form's skeleton and validations. Credit goes to [vijayranghar](https://github.com/vijayranghar) for the inspiration how to create dynamic validation on Yup from this [link](https://github.com/jquense/yup/issues/559). 6 | 7 | ## Installation 8 | 9 | `npm install dynamic-form-json` or `yarn add dynamic-form-json` 10 | 11 | ## Peer Dependencies 12 | 13 | Remember you also need to install the [peer dependencies](https://yarnpkg.com/lang/en/docs/dependency-types/#toc-peerdependencies) of this package. They are `formik`, `yup`, and `styled-components`. 14 | 15 | ## How to Use 16 | 17 | Incase you are curious to try this library, you can implement it as the source code below. 18 | 19 | index.js 20 | 21 | ```js 22 | import React from "react"; 23 | import ReactDOM from "react-dom"; 24 | import App from "./App"; 25 | 26 | ReactDOM.render(, document.getElementById("root")); 27 | ``` 28 | 29 | App.js 30 | 31 | ```js 32 | import DynamicForm from 'dynamic-form-json'; 33 | import { formData } from './data/formData'; 34 | 35 | function App() { 36 | const handleSubmission = val => { 37 | console.log('Values : 'val) 38 | } 39 | return ( 40 |
41 |

My Amazing Form

42 | 43 |
44 | ) 45 | } 46 | 47 | export default App; 48 | ``` 49 | 50 | formData.js 51 | 52 | ```js 53 | export const formData = [ 54 | { 55 | id: "name", 56 | label: "Full name", 57 | placeholder: "Enter full name", 58 | type: "text", 59 | validationType: "string", 60 | value: "", 61 | validations: [ 62 | { 63 | type: "required", 64 | params: ["name is required"], 65 | }, 66 | { 67 | type: "min", 68 | params: [5, "name cannot be less than 5 characters"], 69 | }, 70 | { 71 | type: "max", 72 | params: [10, "name cannot be more than 10 characters"], 73 | }, 74 | ], 75 | }, 76 | ]; 77 | ``` 78 | 79 | ## Supported Fields 80 | 81 | Currently this library supports form input types such as: 82 | 83 | - [x] text 84 | 85 | - [x] select 86 | 87 | - [x] textarea 88 | 89 | - [x] radio 90 | 91 | - [x] checkbox 92 | 93 | - [x] upload 94 | 95 | ## API 96 | 97 | ### DynamicFormJSON - `DynamicForm(fields: Array[Object], cbSubmit: Func)` 98 | 99 | This library could be imported by any name you like because we export it by `default` approach. It also accepts two parameters which are named fields and cbSubmit. All params are required. 100 | 101 | ``` 102 | import DynamicForm from "dynamic-form-json"; 103 | ``` 104 | 105 | `fields` is a property that accepts array of object to create the inputs element inside a Form. The last one is `cbSumbit`, which will handle the submission for you. It accepts a callback function. 106 | 107 | ### TextField 108 | 109 | These are the properties you can pass to an Object in formData array to create TextField component. Not all of them are required. The properties required are id, and type. 110 | 111 | | Name | Description | PropType | Required | Default Props | 112 | | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------- | :------- | :---------------------------------------------------------------------------------- | 113 | | id | This id will be put as the name of the field / input element | string | true | `""` / empty string | 114 | | label | The label of the field | string | false | Id (uppercase the first letter of id props). Example: `id="email" => label="Email"` | 115 | | placeholder | The placeholder of the field | string | false | `""` | 116 | | type | The type of the field | string <= enum["text", "password", "number", "email"] | true | `""` | 117 | | value | The default value of the field | string | false | `""` | 118 | | validationType | The validation type of the field. This is related to the type of data you'll enter in your field. If the data you will input to the field is number, you should make this as number. | string | false | `"string"` | 119 | | validations | Validation rule for this field. This is similar to yup API because we used yup under the hood. | array | false | `"[]"` | 120 | 121 | ### SelectField 122 | 123 | These are the properties you can pass to an Object in formData array to create SelectField component. 124 | 125 | | Name | Description | PropType | Required | Default Props | 126 | | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------- | :------- | :-------------------------------------------------------------------------------- | 127 | | id | This id will be put as the name of the field / input element | string | true | `""` / empty string | 128 | | label | The label of the field | string | false | Id (uppercase the first letter of id props). Example: `id="city" => label="City"` | 129 | | placeholder | The placeholder of the field | string | false | `"Please select"` | 130 | | type | The type of the field | string <= "select" | true | `""` | 131 | | value | The default value of the field | string | false | `""` | 132 | | options | The option list of the field / dropdown | array | false | `[]` | 133 | | validationType | The validation type of the field. This is related to the type of data you'll enter in your field. If the data you will input to the field is number, you should make this as number. | string | false | `"string"` | 134 | | validations | Validation rule for this field. This is similar to yup API because we used yup under the hood. | array | false | `"[]"` | 135 | 136 | ### TextArea 137 | 138 | These are the properties you can pass to an Object in formData array to create TextArea component. 139 | 140 | | Name | Description | PropType | Required | Default Props | 141 | | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :----------------- | :-------------------------------------------------------------------------------------- | 142 | | id | This id will be put as the name of the field / input element | string | true | `""` / empty string | 143 | | label | The label of the field | string | false | Id (uppercase the first letter of id props). Example: `id="address" => label="Address"` | 144 | | placeholder | The placeholder of the field | string | false | `""` | 145 | | type | The type of the field | string | true <= "textarea" | `""` | 146 | | value | The default value of the field | string | false | `""` | 147 | | validationType | The validation type of the field. This is related to the type of data you'll enter in your field. If the data you will input to the field is number, you should make this as number. | string | false | `"string"` | 148 | | validations | Validation rule for this field. This is similar to yup API because we used yup under the hood. | array | false | `"[]"` | 149 | 150 | ### Radio 151 | 152 | These are the properties you can pass to an Object in formData array to create Radio component. 153 | 154 | | Name | Description | PropType | Required | Default Props | 155 | | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :-------------- | :------------------------------------------------------------------------------------ | 156 | | id | This id will be put as the name of the field / input element | string | true | `""` / empty string | 157 | | label | The label of the field | string | false | Id (uppercase the first letter of id props). Example: `id="gender" => label="Gender"` | 158 | | placeholder | The placeholder of the field | string | false | `""` | 159 | | type | The type of the field | string | true <= "radio" | `""` | 160 | | value | The default value of the field | string | false | `""` | 161 | | options | The option list of the radio field | array | false | `[]` | 162 | | validationType | The validation type of the field. This is related to the type of data you'll enter in your field. If the data you will input to the field is number, you should make this as number. | string | false | `"string"` | 163 | | validations | Validation rule for this field. This is similar to yup API because we used yup under the hood. | array | false | `"[]"` | 164 | 165 | ### Checkbox 166 | 167 | These are the properties you can pass to an Object in formData array to create Checkbox component. 168 | 169 | | Name | Description | PropType | Required | Default Props | 170 | | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :----------------- | :-------------------------------------------------------------------------------------- | 171 | | id | This id will be put as the name of the field / input element | string | true | `""` / empty string | 172 | | label | The label of the field | string | false | Id (uppercase the first letter of id props). Example: `id="hobbies" => label="Hobbies"` | 173 | | placeholder | The placeholder of the field | string | false | `""` | 174 | | type | The type of the field | string | true <= "checkbox" | `""` | 175 | | value | The default value of the field | string | false | `""` | 176 | | options | The option list of the checkbox field | array | false | `[]` | 177 | | validationType | The validation type of the field. This is related to the type of data you'll enter in your field. If the data you will input to the field is number, you should make this as number. | string | false | `"string"` | 178 | | validations | Validation rule for this field. This is similar to yup API because we used yup under the hood. | array | false | `"[]"` | 179 | 180 | ### UploadField 181 | 182 | These are the properties you can pass to an Object in formData array to create UploadField component. 183 | 184 | | Name | Description | PropType | Required | Default Props | 185 | | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------- | :------- | :---------------------------------------------------------------------------------- | 186 | | id | This id will be put as the name of the field / input element | string | true | `""` / empty string | 187 | | label | The label of the field | string | false | Id (uppercase the first letter of id props). Example: `id="photo" => label="Photo"` | 188 | | placeholder | The placeholder of the field | string | false | `""` | 189 | | type | The type of the field | string <= "upload" | true | `""` | 190 | | value | The default value of the field | string | false | `""` | 191 | | validationType | The validation type of the field. This is related to the type of data you'll enter in your field. If the data you will input to the field is number, you should make this as number. | string | false | `"string"` | 192 | | validations | Validation rule for this field. This is similar to yup API because we used yup under the hood. | array | false | `"[]"` | 193 | 194 | ## Info 195 | 196 | This package is still on development. Not ready yet to use in production. 197 | -------------------------------------------------------------------------------- /debug.log: -------------------------------------------------------------------------------- 1 | [1022/071004.602:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) 2 | -------------------------------------------------------------------------------- /examples/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import DynamicForm from "../../src"; 3 | import { 4 | Container, 5 | Title, 6 | Wrapper, 7 | JsonWrapper, 8 | FormWrapper, 9 | Textarea, 10 | ErrMessage, 11 | Author, 12 | } from "./_appStyle"; 13 | import { formData } from "./data/formData"; 14 | 15 | function App() { 16 | const [jsonData, setJsonData] = useState(formData); 17 | const [validJsonData, setValidJsonData] = useState(formData); 18 | const [errData, setErrData] = useState(false); 19 | 20 | const isJSON = (str) => { 21 | try { 22 | JSON.parse(str); 23 | } catch (e) { 24 | return false; 25 | } 26 | return true; 27 | }; 28 | 29 | const handleInputChange = (e) => { 30 | if (!isJSON(e.target.value)) { 31 | setJsonData(e.target.value); 32 | setErrData(true); 33 | } else { 34 | let value = JSON.parse(e.target.value); 35 | setJsonData(value); 36 | setValidJsonData(value); 37 | setErrData(false); 38 | } 39 | }; 40 | 41 | const handleSubmission = (val) => { 42 | alert(JSON.stringify(val, null, 4)); 43 | }; 44 | 45 | return ( 46 | 47 | Dynamic Form Json Demo 48 | 49 | 50 |

JSON Data

51 |