diff --git a/src/core-components/__tests__/button-test.js b/src/core-components/__tests__/button-test.js index 0fb709d9..5e6154b5 100644 --- a/src/core-components/__tests__/button-test.js +++ b/src/core-components/__tests__/button-test.js @@ -1,6 +1,3 @@ -/** - * Created by ivan on 16/08/15. - */ jest.dontMock('../button.js'); import React from 'react/addons'; diff --git a/src/core-components/__tests__/form-test.js b/src/core-components/__tests__/form-test.js new file mode 100644 index 00000000..83f6851b --- /dev/null +++ b/src/core-components/__tests__/form-test.js @@ -0,0 +1,59 @@ +jest.dontMock('core-components/form.js'); +jest.dontMock('core-components/form.js'); + +import React from 'react/addons'; +import Form from 'core-components/form.js'; +import Input from 'core-components/input.js'; + +var TestUtils = React.addons.TestUtils; + +describe('Form', () => { + var results = TestUtils.renderIntoDocument( +
+ ); + var inputs = TestUtils.scryRenderedComponentsWithType(results, Input); + + it('should store input value in form state', () => { + expect(results.state.form).toEqual({ + first: 'value1', + second: 'value2', + third: 'value3' + }); + }); + + it('should update form state if an input value changes', () => { + inputs[0].props.onChange({ target: {value: 'value4'}}); + + expect(results.state.form).toEqual({ + first: 'value4', + second: 'value2', + third: 'value3' + }); + }); + + it('should update input value if state value changes', () => { + results.setState({ + form: { + first: 'value6', + second: 'value7', + third: 'value8' + } + }); + + expect(inputs[0].props.value).toEqual('value6'); + expect(inputs[1].props.value).toEqual('value7'); + expect(inputs[2].props.value).toEqual('value8'); + }); + + it('should call onSubmit callback when form is submitted', () => { + TestUtils.Simulate.submit(results.getDOMNode()); + + expect(results.props.onSubmit).toBeCalledWith(results.state.form); + }); +}); \ No newline at end of file diff --git a/src/core-components/form.js b/src/core-components/form.js index 06706ce0..0b184585 100644 --- a/src/core-components/form.js +++ b/src/core-components/form.js @@ -2,6 +2,7 @@ import React from 'react/addons'; import _ from 'lodash'; import Input from 'core-components/input'; +import {reactDFS, renderChildrenWithProps} from 'utils/react-dfs'; var Form = React.createClass({ @@ -13,32 +14,28 @@ var Form = React.createClass({ } }, + componentDidMount() { + var formState = {}; + + reactDFS(this.props.children, (child) => { + if (child.type === Input) { + formState[child.props.name] = child.props.value; + } + }); + + this.setState({ + form: formState + }); + }, + render() { return ( ); }, - renderTraversedChildren(children) { - if (typeof children !== 'object' || children === null) { - return children; - } - - return React.Children.map(children, function (child) { - if (typeof child !== 'object' || child === null) { - return child; - } - - if (child.props && child.type === Input) { - return React.cloneElement(child, this.getInputProps(child.props), child.props && child.props.children); - } else { - return React.cloneElement(child, {}, this.renderTraversedChildren(child.props && child.props.children)); - } - }.bind(this)); - }, - getProps() { var props = _.clone(this.props); @@ -47,15 +44,22 @@ var Form = React.createClass({ return props; }, - getInputProps(props) { - var inputName = props.name; + getInputProps(child) { + var props = child.props; + var additionalProps = {}; - this.validations[inputName] = props.validation; + if(child.type === Input) { + let inputName = props.name; - return { - onChange: this.handleInputChange.bind(this, inputName), - value: this.state.form[inputName] || props.value - }; + this.validations[inputName] = props.validation; + + additionalProps = { + onChange: this.handleInputChange.bind(this, inputName), + value: this.state.form[inputName] || props.value + } + } + + return additionalProps; }, handleSubmit (event) {