diff --git a/README.md b/README.md index 53d1318..982b742 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ JSON React Form is library that convert JSON schema into React component forms. - checkbox - radio - currency +- file - submit button ## How To Use @@ -108,6 +109,18 @@ We use react-select for rendering input type select and its options. By default - **options**: array > The options is array of object that consists at least `label` and `value`. Label will be displayed in options, while value is the one that will be returned later. +### File --> `return FileList` + +- **type**: file +- **required**: true | false +- **disabled**: true | false +- **multiple**: true | false +- **accept**: string + > Specifies supported formats for the file upload field. + > example: `.png, .jpg`. +- **label**: string + > Label of the file upload field. It will be replaced when a file selected. + ### Submit The key you provided to the model will become text inside this submit button. @@ -170,6 +183,13 @@ export default { } ], }, + "Upload": { + "type": "file", + "required": true, + "multiple": true, + "accept": ".png,.jpg", + "label": "Choose an image file" + }, "Save": { // button submit "type": "submit", } diff --git a/dist/json-reactform.cjs.dev.js b/dist/json-reactform.cjs.dev.js index b1393bd..ae0721c 100644 --- a/dist/json-reactform.cjs.dev.js +++ b/dist/json-reactform.cjs.dev.js @@ -178,6 +178,14 @@ var index = (function (_ref2) { setState(_extends({}, state, {}, changedObject)); }; + var onChangeFile = function onChangeFile(key, _ref3, model) { + var files = _ref3.target.files; + var changedObject = {}; + var selectedFiles = !model.multiple ? files[0] : files; + changedObject[key] = selectedFiles; + setState(_extends({}, state, {}, changedObject)); + }; + Object.keys(model).forEach(function (key) { if (model[key].type === 'date') { formItems.push(React.createElement(reactstrap.FormGroup, { @@ -321,6 +329,37 @@ var index = (function (_ref2) { placeholder: model[key].placeholder, autoComplete: "off" })))); + } else if (model[key].type === 'file') { + var label = !model[key].multiple && state[key] ? state[key].name : model[key].label; + + if (model[key].multiple && state[key]) { + label = Array.from(state[key]).map(function (file) { + return file.name; + }).join(', '); + } + + formItems.push(React.createElement(reactstrap.FormGroup, { + key: key, + row: true, + className: "mb-4" + }, React.createElement(reactstrap.Label, { + "for": key, + sm: 4 + }, key, " ", model[key].required ? '*' : null), React.createElement(reactstrap.Col, { + sm: 8, + className: "d-flex flex-column" + }, React.createElement(reactstrap.CustomInput, { + type: "file", + id: key, + name: key, + label: label, + onChange: function onChange(e) { + return onChangeFile(key, e, model[key]); + }, + required: model[key].required, + multiple: model[key].multiple, + accept: model[key].accept + })))); } else if (model[key].type === 'submit') { formItems.push(React.createElement(reactstrap.Row, { key: key, diff --git a/dist/json-reactform.cjs.prod.js b/dist/json-reactform.cjs.prod.js index 792fdc2..3280def 100644 --- a/dist/json-reactform.cjs.prod.js +++ b/dist/json-reactform.cjs.prod.js @@ -84,8 +84,7 @@ var index = function(_ref2) { currencyObject[name] = numberToCurrency(value), setCurrency(_extends({}, currency, {}, currencyObject)); }; return Object.keys(model).forEach((function(key) { - var SelectComponent; - "date" === model[key].type ? formItems.push(React.createElement(reactstrap.FormGroup, { + if ("date" === model[key].type) formItems.push(React.createElement(reactstrap.FormGroup, { key: key, row: !0, className: "mb-4" @@ -110,7 +109,7 @@ var index = function(_ref2) { disabled: model[key].disabled, placeholderText: model[key].placeholder, required: model[key].required - })))) : "select" === model[key].type ? formItems.push(React.createElement(reactstrap.FormGroup, { + })))); else if ("select" === model[key].type) formItems.push(React.createElement(reactstrap.FormGroup, { key: key, row: !0, className: "mb-4" @@ -153,7 +152,7 @@ var index = function(_ref2) { onChange: function(e) { return e.preventDefault(); } - })) : React.createElement(reactstrap.Spinner, null))))) : "checkbox" === model[key].type ? formItems.push(React.createElement(reactstrap.FormGroup, { + })) : React.createElement(reactstrap.Spinner, null))))); else if ("checkbox" === model[key].type) formItems.push(React.createElement(reactstrap.FormGroup, { key: key, row: !0, className: "mb-4" @@ -183,7 +182,7 @@ var index = function(_ref2) { }(key, e.target.value); } }); - }))))) : "radio" === model[key].type ? formItems.push(React.createElement(reactstrap.FormGroup, { + }))))); else if ("radio" === model[key].type) formItems.push(React.createElement(reactstrap.FormGroup, { key: key, row: !0, className: "mb-4" @@ -206,7 +205,7 @@ var index = function(_ref2) { disabled: model[key].disabled, onChange: onChangeState }); - }))))) : "currency" === model[key].type ? formItems.push(React.createElement(reactstrap.FormGroup, { + }))))); else if ("currency" === model[key].type) formItems.push(React.createElement(reactstrap.FormGroup, { key: key, row: !0, className: "mb-4" @@ -226,7 +225,36 @@ var index = function(_ref2) { disabled: model[key].disabled, placeholder: model[key].placeholder, autoComplete: "off" - })))) : "submit" === model[key].type ? formItems.push(React.createElement(reactstrap.Row, { + })))); else if ("file" === model[key].type) { + var label = !model[key].multiple && state[key] ? state[key].name : model[key].label; + model[key].multiple && state[key] && (label = Array.from(state[key]).map((function(file) { + return file.name; + })).join(", ")), formItems.push(React.createElement(reactstrap.FormGroup, { + key: key, + row: !0, + className: "mb-4" + }, React.createElement(reactstrap.Label, { + for: key, + sm: 4 + }, key, " ", model[key].required ? "*" : null), React.createElement(reactstrap.Col, { + sm: 8, + className: "d-flex flex-column" + }, React.createElement(reactstrap.CustomInput, { + type: "file", + id: key, + name: key, + label: label, + onChange: function(e) { + return function(key, _ref3, model) { + var files = _ref3.target.files, changedObject = {}, selectedFiles = model.multiple ? files : files[0]; + changedObject[key] = selectedFiles, setState(_extends({}, state, {}, changedObject)); + }(key, e, model[key]); + }, + required: model[key].required, + multiple: model[key].multiple, + accept: model[key].accept + })))); + } else "submit" === model[key].type ? formItems.push(React.createElement(reactstrap.Row, { key: key, className: "mb-4" }, React.createElement(reactstrap.Col, { @@ -258,6 +286,7 @@ var index = function(_ref2) { placeholder: model[key].placeholder, autoComplete: model[key].autoComplete ? "" : "off" })))); + var SelectComponent; })), React.useEffect((function() { if (onChange) { var changedObject = []; diff --git a/dist/json-reactform.esm.js b/dist/json-reactform.esm.js index 0a725bf..61b340f 100644 --- a/dist/json-reactform.esm.js +++ b/dist/json-reactform.esm.js @@ -172,6 +172,14 @@ var index = (function (_ref2) { setState(_extends({}, state, {}, changedObject)); }; + var onChangeFile = function onChangeFile(key, _ref3, model) { + var files = _ref3.target.files; + var changedObject = {}; + var selectedFiles = !model.multiple ? files[0] : files; + changedObject[key] = selectedFiles; + setState(_extends({}, state, {}, changedObject)); + }; + Object.keys(model).forEach(function (key) { if (model[key].type === 'date') { formItems.push(React.createElement(FormGroup, { @@ -315,6 +323,37 @@ var index = (function (_ref2) { placeholder: model[key].placeholder, autoComplete: "off" })))); + } else if (model[key].type === 'file') { + var label = !model[key].multiple && state[key] ? state[key].name : model[key].label; + + if (model[key].multiple && state[key]) { + label = Array.from(state[key]).map(function (file) { + return file.name; + }).join(', '); + } + + formItems.push(React.createElement(FormGroup, { + key: key, + row: true, + className: "mb-4" + }, React.createElement(Label, { + "for": key, + sm: 4 + }, key, " ", model[key].required ? '*' : null), React.createElement(Col, { + sm: 8, + className: "d-flex flex-column" + }, React.createElement(CustomInput, { + type: "file", + id: key, + name: key, + label: label, + onChange: function onChange(e) { + return onChangeFile(key, e, model[key]); + }, + required: model[key].required, + multiple: model[key].multiple, + accept: model[key].accept + })))); } else if (model[key].type === 'submit') { formItems.push(React.createElement(Row, { key: key, diff --git a/src/index.js b/src/index.js index 2bcae14..8103df9 100644 --- a/src/index.js +++ b/src/index.js @@ -168,6 +168,16 @@ export default ({ model, onSubmit, onChange }) => { }); }; + const onChangeFile = (key, { target: { files } }, model) => { + const changedObject = {}; + const selectedFiles = !model.multiple ? files[0] : files; + changedObject[key] = selectedFiles; + setState({ + ...state, + ...changedObject, + }); + }; + Object.keys(model).forEach(key => { if (model[key].type === 'date') { formItems.push( @@ -315,6 +325,34 @@ export default ({ model, onSubmit, onChange }) => { ); + } else if (model[key].type === 'file') { + let label = + !model[key].multiple && state[key] ? state[key].name : model[key].label; + if (model[key].multiple && state[key]) { + label = Array.from(state[key]) + .map(file => file.name) + .join(', '); + } + formItems.push( + + + + onChangeFile(key, e, model[key])} + required={model[key].required} + multiple={model[key].multiple} + accept={model[key].accept} + disabled={model[key].disabled} + /> + + + ); } else if (model[key].type === 'submit') { formItems.push(