From fbd09119d3758eaa195ced779c76739f621a81ec Mon Sep 17 00:00:00 2001 From: Semigradsky Date: Tue, 1 Dec 2015 17:00:43 +0300 Subject: [PATCH] Added `dynamic form fields` example. --- examples/README.md | 4 + examples/components/Input.js | 5 +- examples/components/MultiCheckboxSet.js | 66 ++++++++++++++ examples/components/RadioGroup.js | 46 ++++++++++ examples/components/Select.js | 5 +- examples/custom-validation/app.js | 7 +- examples/dynamic-form-fields/app.css | 24 +++++ examples/dynamic-form-fields/app.js | 112 ++++++++++++++++++++++++ examples/dynamic-form-fields/index.html | 14 +++ examples/global.css | 19 +++- examples/index.html | 1 + 11 files changed, 295 insertions(+), 8 deletions(-) create mode 100644 examples/components/MultiCheckboxSet.js create mode 100644 examples/components/RadioGroup.js create mode 100644 examples/dynamic-form-fields/app.css create mode 100644 examples/dynamic-form-fields/app.js create mode 100644 examples/dynamic-form-fields/index.html diff --git a/examples/README.md b/examples/README.md index 691cc4f..e542748 100644 --- a/examples/README.md +++ b/examples/README.md @@ -34,3 +34,7 @@ If it is not helped try update your node.js and npm. 3. [**Reset Values**](reset-values) Reset text input, checkbox and select to their pristine values. + +4. [**Dynamic Form Fields**](dynamic-form-fields) + + Dynamically adding and removing fields to form. diff --git a/examples/components/Input.js b/examples/components/Input.js index a73e060..fd66834 100644 --- a/examples/components/Input.js +++ b/examples/components/Input.js @@ -18,14 +18,15 @@ const MyInput = React.createClass({ // when the value is empty and the required prop is // passed to the input. showError() is true when the // value typed is invalid - const className = this.props.className + ' ' + (this.showRequired() ? 'required' : this.showError() ? 'error' : null); + const className = 'form-group' + (this.props.className || ' ') + + (this.showRequired() ? 'required' : this.showError() ? 'error' : ''); // An error message is returned ONLY if the component is invalid // or the server has returned an error message const errorMessage = this.getErrorMessage(); return ( -
+
a === b }; + }, + componentDidMount() { + const value = this.props.value || []; + this.setValue(value); + this.setState({ value: value, cmp: this.props.cmp || this.state.cmp }); + }, + + changeValue(value, event) { + const checked = event.currentTarget.checked; + + let newValue = []; + if (checked) { + newValue = this.state.value.concat(value); + } else { + newValue = this.state.value.filter(it => !this.state.cmp(it, value)); + } + + this.setValue(newValue); + this.setState({ value: newValue }); + }, + + render() { + const className = 'form-group' + (this.props.className || ' ') + + (this.showRequired() ? 'required' : this.showError() ? 'error' : ''); + const errorMessage = this.getErrorMessage(); + + const { name, title, items } = this.props; + return ( +
+ + {items.map((item, i) => ( +
+ + {JSON.stringify(item)} +
+ )) + } + {errorMessage} +
+ ); + } + +}); + +export default MyRadioGroup; diff --git a/examples/components/RadioGroup.js b/examples/components/RadioGroup.js new file mode 100644 index 0000000..985e620 --- /dev/null +++ b/examples/components/RadioGroup.js @@ -0,0 +1,46 @@ +import React from 'react'; +import Formsy from 'formsy-react'; + +const MyRadioGroup = React.createClass({ + mixins: [Formsy.Mixin], + + componentDidMount() { + const value = this.props.value; + this.setValue(value); + this.setState({ value }); + }, + + changeValue(value) { + this.setValue(value); + this.setState({ value }); + }, + + render() { + const className = 'form-group' + (this.props.className || ' ') + + (this.showRequired() ? 'required' : this.showError() ? 'error' : ''); + const errorMessage = this.getErrorMessage(); + + const { name, title, items } = this.props; + return ( +
+ + {items.map((item, i) => ( +
+ + {item.toString()} +
+ )) + } + {errorMessage} +
+ ); + } + +}); + +export default MyRadioGroup; diff --git a/examples/components/Select.js b/examples/components/Select.js index 57a286d..cf619be 100644 --- a/examples/components/Select.js +++ b/examples/components/Select.js @@ -9,7 +9,8 @@ const MySelect = React.createClass({ }, render() { - const className = this.props.className + ' ' + (this.showRequired() ? 'required' : this.showError() ? 'error' : null); + const className = 'form-group' + (this.props.className || ' ') + + (this.showRequired() ? 'required' : this.showError() ? 'error' : ''); const errorMessage = this.getErrorMessage(); const options = this.props.options.map((option, i) => ( @@ -19,7 +20,7 @@ const MySelect = React.createClass({ )); return ( -
+
{errorMessage} diff --git a/examples/dynamic-form-fields/app.css b/examples/dynamic-form-fields/app.css new file mode 100644 index 0000000..803891f --- /dev/null +++ b/examples/dynamic-form-fields/app.css @@ -0,0 +1,24 @@ +.many-fields-conf { + width: 400px; + margin: 0 auto; +} + +.many-fields { + width: 600px; + margin: 0 auto; +} + +.field { + overflow: hidden; +} + +.many-fields .form-group { + width: calc(100% - 20px); + float: left; +} +.many-fields .remove-field { + margin-top: 30px; + margin-left: 8px; + display: inline-block; + text-decoration: none; +} diff --git a/examples/dynamic-form-fields/app.js b/examples/dynamic-form-fields/app.js new file mode 100644 index 0000000..9549c4a --- /dev/null +++ b/examples/dynamic-form-fields/app.js @@ -0,0 +1,112 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Form } from 'formsy-react'; + +import MyInput from './../components/Input'; +import MySelect from './../components/Select'; +import MyRadioGroup from './../components/RadioGroup'; +import MyMultiCheckboxSet from './../components/MultiCheckboxSet'; + +const Fields = props => { + function onRemove(pos) { + return event => { + event.preventDefault(); + props.onRemove(pos); + }; + } + const foo = 'required'; + return ( +
+ {props.data.map((field, i) => ( +
+ { + field.type === 'input' ? + ( + + ) : + ( + + ) + } + X +
+ )) + } +
+ ); +}; + +const App = React.createClass({ + getInitialState() { + return { fields: [], canSubmit: false }; + }, + submit(data) { + alert(JSON.stringify(data, null, 4)); + }, + addField(fieldData) { + fieldData.validations = fieldData.validations.length ? + fieldData.validations.reduce((a, b) => Object.assign({}, a, b)) : + null; + fieldData.id = Date.now(); + this.setState({ fields: this.state.fields.concat(fieldData) }); + }, + removeField(pos) { + const fields = this.state.fields; + this.setState({ fields: fields.slice(0, pos).concat(fields.slice(pos+1)) }) + }, + enableButton() { + this.setState({ canSubmit: true }); + }, + disableButton() { + this.setState({ canSubmit: false }); + }, + render() { + const { fields, canSubmit } = this.state; + return ( +
+
+ JSON.stringify(a) === JSON.stringify(b)} + items={[ + {isEmail: true}, + {isEmptyString: true}, + {isNumeric: true}, + {isAlphanumeric: true}, + {equals: 5}, + {minLength: 3}, + {maxLength: 7} + ]} + /> + + + + +
+ + + +
+ ); + } +}); + +ReactDOM.render(, document.getElementById('example')); diff --git a/examples/dynamic-form-fields/index.html b/examples/dynamic-form-fields/index.html new file mode 100644 index 0000000..d912f94 --- /dev/null +++ b/examples/dynamic-form-fields/index.html @@ -0,0 +1,14 @@ + + + + Dynamic Form Fields + + + + +

Formsy React Examples / Dynamic Form Fields

+
+ + + + diff --git a/examples/global.css b/examples/global.css index ebdad7f..50aaa2a 100644 --- a/examples/global.css +++ b/examples/global.css @@ -49,11 +49,28 @@ form { color: #555; background-color: #FFF; background-image: none; - border: 1px solid #CCC; + border: 2px solid #CCC; border-radius: 4px; box-sizing: border-box; } +.form-group.error input[type='text'], +.form-group.error input[type='email'], +.form-group.error input[type='number'], +.form-group.error input[type='password'], +.form-group.error select { + border-color: red; + color: red; +} + +.form-group.required input[type='text'], +.form-group.required input[type='email'], +.form-group.required input[type='number'], +.form-group.required input[type='password'], +.form-group.required select { + border-color: #FF9696; +} + .validation-error { color: red; margin: 5px 0; diff --git a/examples/index.html b/examples/index.html index 175c07b..ce7941e 100644 --- a/examples/index.html +++ b/examples/index.html @@ -10,6 +10,7 @@
  • Login Page
  • Custom Validation
  • Reset Values
  • +
  • Dynamic Form Fields