Skip to content

Commit

Permalink
Merge pull request #111 from reebalazs/fix-text-input-2
Browse files Browse the repository at this point in the history
Fix text input values, and form reset
  • Loading branch information
mbrookes authored Jul 11, 2016
2 parents b559bd8 + 74c0c8d commit 8928830
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 17 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"karma-sinon": "^1.0.4",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.7.0",
"material-ui": "0.15.0-beta.1",
"material-ui": "^0.15.0",
"mocha": "^2.4.5",
"phantomjs-prebuilt": "^2.1.4",
"react": "^15.0.0",
Expand Down
34 changes: 27 additions & 7 deletions src/FormsyText.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,38 @@ const FormsyText = React.createClass({

mixins: [Formsy.Mixin],


getInitialState() {
return {
value: this.props.defaultValue || this.props.value || '',
};
return { value: this.controlledValue() };
},

componentWillMount() {
this.setValue(this.props.defaultValue || this.props.value || '');
this.setValue(this.controlledValue());
},

componentWillReceiveProps(nextProps) {
const isValueChanging = nextProps.value !== this.props.value;
if (isValueChanging || nextProps.defaultValue !== this.props.defaultValue) {
const value = this.controlledValue(nextProps);
if (isValueChanging || this.props.defaultValue === this.getValue()) {
this.setState({ value });
this.setValue(value);
}
}
},

componentWillReceiveProps(props) {
this.setState({ value: this.getValue() || '' });

componentWillUpdate(nextProps, nextState) {
if (nextState._isPristine && // eslint-disable-line no-underscore-dangle
nextState._isPristine !== this.state._isPristine) { // eslint-disable-line no-underscore-dangle
// Calling state here is valid, as it cannot cause infinite recursion.
const value = this.controlledValue(nextProps);
this.setValue(value);
this.setState({ value });
}
},

controlledValue(props = this.props) {
return props.value || props.defaultValue || '';
},

handleBlur: function handleBlur(event) {
Expand Down
195 changes: 186 additions & 9 deletions test/test.FormsyText.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
/* eslint-env mocha, jasmine */
/* global expect */

import React from 'react';
import React, { Component, PropTypes } from 'react';
import FormsyText from '../src/FormsyText';
import TextField from 'material-ui/TextField';
import { Simulate } from 'react-addons-test-utils';
import { mountTestForm } from './support';
import { Form } from 'formsy-react';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import { mount } from 'enzyme';

const setup = () => {
function makeChildrenFn(props) {
const fn = () => (
<FormsyText ref="text"
name="text"
validations="maxLength:10"
validationErrors={{ maxLength: 'Text is too long' }}
{ ...props }
/>
);
fn.DisplayName = 'FormsyText';
return fn;
}

const setup = (props) => {
const childrenFn = makeChildrenFn(props);
const formWrapper = mountTestForm(childrenFn);
const formsyTextWrapper = formWrapper.find(FormsyText);
return {
Expand All @@ -17,18 +33,51 @@ const setup = () => {
};
};

const childrenFn = () => (
<FormsyText
name="text"
validations="maxLength:10"
validationErrors={{ maxLength: 'Text is too long' }}
/>
);
class TestForm extends Component {

static childContextTypes = {
muiTheme: PropTypes.object.isRequired,
};

static propTypes = {
defaultValue: PropTypes.string,
value: PropTypes.string,
}

getChildContext() {
return { muiTheme: getMuiTheme() };
}

componentWillMount() {
const { value, defaultValue } = this.props;
this.state = { value, defaultValue };
}

render() {
const { value, defaultValue, ...extraProps } = { ...this.props, ...this.state };
return (
<Form { ...extraProps }>
<FormsyText ref="text" name="text"
value={value}
defaultValue={defaultValue}
/>
</Form>
);
}
}

function makeTestParent(props) {
const parent = mount(<TestForm {...props} />);
const formWrapper = parent.find(Form);
const formsyTextWrapper = parent.find(FormsyText);
return { parent, formWrapper, formsyTextWrapper };
}

const fillInText = (wrapper, text) => {
const inputDOM = wrapper.find('input').node;
inputDOM.value = text;
Simulate.change(inputDOM);
Simulate.blur(inputDOM);
};

describe('FormsyText', () => {
Expand Down Expand Up @@ -59,4 +108,132 @@ describe('FormsyText', () => {
formsyForm.validateForm();
expect(formsyTextWrapper).to.not.contain.text('Text is too long');
});

describe('value properties handle', () => {
describe('initial', () => {
it('value', () => {
const { formsyTextWrapper, formWrapper } = setup({
value: 'VALUE',
});
const formsyForm = formWrapper.find(Form).node;
let formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('VALUE');
fillInText(formsyTextWrapper, 'some text');
formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('some text');
});

it('defaultValue', () => {
const { formsyTextWrapper, formWrapper } = setup({
defaultValue: 'DEFAULT-VALUE',
});
const formsyForm = formWrapper.find(Form).node;
let formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('DEFAULT-VALUE');
fillInText(formsyTextWrapper, 'some text');
formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('some text');
});

it('value + defaultValue', () => {
const { formsyTextWrapper, formWrapper } = setup({
value: 'VALUE',
defaultValue: 'DEFAULT-VALUE',
});
const formsyForm = formWrapper.find(Form).node;
let formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('VALUE');
fillInText(formsyTextWrapper, 'some text');
formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('some text');
});
});

describe('updating', () => {
it('value', () => {
const props = {
value: 'VALUE',
};
const { parent, formWrapper, formsyTextWrapper } = makeTestParent(props);
const formsyForm = formWrapper.node;
parent.setState({ value: 'NEW VALUE' });
let formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('NEW VALUE');
fillInText(formsyTextWrapper, 'some text');
formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('some text');
parent.setState({ value: 'NEWER VALUE' });
formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('NEWER VALUE');
});

it('defaultValue', () => {
const props = {
defaultValue: 'VALUE',
};
const { parent, formWrapper, formsyTextWrapper } = makeTestParent(props);
const formsyForm = formWrapper.node;
parent.setState({ defaultValue: 'NEW VALUE' });
let formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('NEW VALUE');
fillInText(formsyTextWrapper, 'some text');
formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('some text');
parent.setState({ defaultValue: 'NEWER VALUE' });
// defaultValues does not override the typed in value.
formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('some text');
});
});

describe('resetting to', () => {
it('value', () => {
const { formsyTextWrapper, formWrapper } = setup({
value: 'VALUE',
});
const formsyForm = formWrapper.find(Form).node;
fillInText(formsyTextWrapper, 'some text');
formsyForm.reset();
const formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('VALUE');
});

it('defaultValue', () => {
const { formsyTextWrapper, formWrapper } = setup({
defaultValue: 'VALUE',
});
const formsyForm = formWrapper.find(Form).node;
fillInText(formsyTextWrapper, 'some text');
formsyForm.reset();
const formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('VALUE');
});

it('value + defaultValue', () => {
const { formsyTextWrapper, formWrapper } = setup({
value: 'VALUE',
defaultValue: 'DEFAULT-VALUE',
});
const formsyForm = formWrapper.find(Form).node;
fillInText(formsyTextWrapper, 'some text');
formsyForm.reset();
const formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('VALUE');
});

it('updated value', () => {
const props = {
value: 'VALUE',
};
const { parent, formWrapper, formsyTextWrapper } = makeTestParent(props);
const formsyForm = formWrapper.node;
parent.setState({ value: 'NEW VALUE' });
fillInText(formsyTextWrapper, 'some text');
formsyForm.reset();
// Reset reverts to the last value that has been set.
const formValues = formsyForm.getCurrentValues();
expect(formValues.text).to.eq('NEW VALUE');
});
});
});
});

0 comments on commit 8928830

Please sign in to comment.