diff --git a/dist/components/Field.js b/dist/components/Field.js index 1a45412..6875ffc 100644 --- a/dist/components/Field.js +++ b/dist/components/Field.js @@ -51,7 +51,7 @@ var Field = function (_React$Component) { _createClass(Field, [{ key: 'componentWillUpdate', value: function componentWillUpdate(nextProps) { - if (nextProps.value !== this.props.value && nextProps.value !== this.finalValue) { + if (nextProps.value !== this.props.value && nextProps.value !== this.state.value) { this.cancelBroadcast(); this.setState({ value: nextProps.value }); this.finalValue = nextProps.value; @@ -65,7 +65,7 @@ var Field = function (_React$Component) { }, { key: 'shouldComponentUpdate', value: function shouldComponentUpdate(nextProps) { - if (nextProps.value !== this.finalValue) return true; + if (nextProps.value !== this.state.value) return true; if (this.state.value !== this.finalValue) return true; if (this.props.match !== nextProps.match) return true; return false; @@ -138,7 +138,9 @@ var Field = function (_React$Component) { 'div', null, _react2.default.Children.map(this.props.children, function (child) { - return (0, _utilities.mapPropsToChild)(child, 'input', inputProps); + return (0, _utilities.mapPropsToChild)(child, 'input', function () { + return inputProps; + }); }) ); } diff --git a/dist/components/Form.js b/dist/components/Form.js index 3782455..e7656ed 100644 --- a/dist/components/Form.js +++ b/dist/components/Form.js @@ -40,7 +40,7 @@ var Form = function (_React$Component) { _this.state = {}; _react2.default.Children.map(props.children, function (child) { - return _this.addFieldsToState(child, false); + return _this.addFieldsToState(_this, child, false); }); return _this; } @@ -67,7 +67,7 @@ var Form = function (_React$Component) { var _this2 = this; _react2.default.Children.map(this.props.children, function (child) { - return _this2.addFieldsToState(child, true); + return _this2.addFieldsToState(_this2, child, true); }); } }, { @@ -79,7 +79,9 @@ var Form = function (_React$Component) { 'form', { onSubmit: this.onSubmit }, _react2.default.Children.map(this.props.children, function (child) { - return (0, _utilities.mapPropsToChild)(child, 'Field', (0, _utilities.makeFieldProps)(child, _this3.onFieldChange, _this3.state)); + return (0, _utilities.mapPropsToChild)(child, 'Field', function (grandChild) { + return (0, _utilities.makeFieldProps)(grandChild, _this3.onFieldChange, _this3.state); + }); }) ); } diff --git a/dist/helpers/utilities.js b/dist/helpers/utilities.js index 097b6b3..6ec1d2a 100644 --- a/dist/helpers/utilities.js +++ b/dist/helpers/utilities.js @@ -90,20 +90,20 @@ function buildStateForField(fieldProps) { return newState; } -function addFieldsToState(child) { - var mounted = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; +function addFieldsToState(component, child) { + var mounted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (typeof child.type === 'function' && child.type.name === 'Field') { var name = child.props.name; var fieldState = buildStateForField(child.props); if (mounted) { - this.setState(_defineProperty({}, name, fieldState)); + component.setState(_defineProperty({}, name, fieldState)); } else { - this.state[name] = fieldState; + component.state[name] = fieldState; // eslint-disable-line } } else if (child.props && child.props.children) { _react2.default.Children.forEach(child.props.children, function (nextChild) { - return addFieldsToState(nextChild, mounted); + return addFieldsToState(component, nextChild, mounted); }); } } @@ -124,12 +124,13 @@ function makeFieldProps(child, onChange, state) { return null; } -function mapPropsToChild(child, type, props) { +function mapPropsToChild(child, type, propFunction) { if (child.type === type || typeof child.type === 'function' && child.type.name === type) { - return _react2.default.cloneElement(child, props); - } else if (child.props && child.props.children) { + return _react2.default.cloneElement(child, propFunction(child)); + } + if (child.props && child.props.children) { var newChildren = _react2.default.Children.map(child.props.children, function (nestedChild) { - return mapPropsToChild(nestedChild, type, props); + return mapPropsToChild(nestedChild, type, propFunction); }); return _react2.default.cloneElement(child, null, newChildren); } diff --git a/dist/helpers/validators.js b/dist/helpers/validators.js index f8ea9a1..4f301f2 100644 --- a/dist/helpers/validators.js +++ b/dist/helpers/validators.js @@ -75,9 +75,8 @@ function alpha() { } function numeric() { - var numericRegex = /[^0-9\s]/i; return function (value) { - return typeof value === 'number' || typeof value === 'string' && !numericRegex.test(value); + return typeof value === 'number' || typeof value === 'string' && (!value || !value.replace(/([-+]{0,1})[0-9]+(\.[0-9]+)?([eE]([+-]{0,1})[0-9]+)?/, '')); }; } diff --git a/readme.md b/readme.md index 79cadd9..238e735 100644 --- a/readme.md +++ b/readme.md @@ -202,6 +202,8 @@ The `Field` component will behave as follows with respect to its children: > @param {String} [type='text'] - The input type of the wrapped input element. The input type for the wrapped input element. Defaults to `text`. + + *Note:* When number input is desired, it is preferred to use 'text' inputs with a `number` validator if it is expected that the user will enter `+`, `-`, or `e` characters. See `https://github.com/facebook/react/issues/1549`. #### `props[validator] = [validator]` > @param {\?} [validator=\?] - Optional. One or more validators to apply to the `Field`'s state. @@ -261,9 +263,9 @@ There are also a handful of different validators and properties (debounce, lengt This validates that the string input is comprised only of english alphabet characters and space characters. #### `props.number = numericValidation` -> @param {Boolean} [numericValidation=true] Optional. Will toggle validation for only numeric and space characters. +> @param {Boolean} [numericValidation=true] Optional. Will toggle validation for only numeric characters. - This validates that the string or number input is comprised only of numeric and space characters. + This validates that the string or number input is comprised only of numeric characters. This will allow appropriately placed `+`, `-`, `e`, and `.` characters. #### `props.max = maxValue` > @param {Number} maxValue - Validates an input field to be less than or equal to the maxValue. diff --git a/src/components/Field.jsx b/src/components/Field.jsx index 69970de..de0922a 100644 --- a/src/components/Field.jsx +++ b/src/components/Field.jsx @@ -29,7 +29,7 @@ const Field = class extends React.Component { } componentWillUpdate(nextProps) { - if ((nextProps.value !== this.props.value) && (nextProps.value !== this.finalValue)) { + if ((nextProps.value !== this.props.value) && (nextProps.value !== this.state.value)) { this.cancelBroadcast(); this.setState({ value: nextProps.value }); this.finalValue = nextProps.value; @@ -42,7 +42,7 @@ const Field = class extends React.Component { } shouldComponentUpdate(nextProps) { - if (nextProps.value !== this.finalValue) return true; + if (nextProps.value !== this.state.value) return true; if (this.state.value !== this.finalValue) return true; if (this.props.match !== nextProps.match) return true; return false; @@ -107,7 +107,7 @@ const Field = class extends React.Component { return (