Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dist/components/Field.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions dist/helpers/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]+)?/, ''));
};
}

Expand Down
6 changes: 4 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions src/components/Field.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions src/helpers/validators.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ export function alpha() {
}

export function numeric() {
const numericRegex = /[^0-9\s]/i;
return value => typeof value === 'number' || (typeof value === 'string' && !numericRegex.test(value));
return value => typeof value === 'number' || (typeof value === 'string' &&
(!value || !value.replace(/([-+]{0,1})[0-9]+(\.[0-9]+)?([eE]([+-]{0,1})[0-9]+)?/, '')));
}

export function max(criteria) {
return value => ((typeof value === 'string' && value) || typeof value === 'number') && (Number(value) <= Number(criteria));
return value => ((typeof value === 'string' && value) || typeof value === 'number') &&
(Number(value) <= Number(criteria));
}

export function min(criteria) {
Expand Down
2 changes: 1 addition & 1 deletion tests/spec_helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function updateInput(DOM, value = '', type = 'text') {
DOM.find('input').simulate('change', { target: { value }, type });
}

export function buildField(mountingFunction, validator, value, type) {
export function buildField(mountingFunction, validator, value, type="text") {
const validatorToObj = {
[validator]: value,
};
Expand Down
23 changes: 16 additions & 7 deletions tests/utilities/validators.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* globals describe it before beforeEach after afterEach */
/* globals describe it before beforeEach after afterEach xit */
import { expect } from 'chai'; // eslint-disable-line
import sinon from 'sinon'; // eslint-disable-line
import { shallow, mount } from 'enzyme'; // eslint-disable-line
Expand Down Expand Up @@ -260,38 +260,47 @@ describe('Validator Functionality', () => {
const wrapper = buildField(mount, 'number', true);
const valFunc = validators.numeric();

it('returns `true` for strings consisting of only number and space characters', () => {
it('returns `true` for strings consisting of only number characters', () => {
expect(valFunc('')).to.equal(true);
expect(valFunc('4e-10')).to.equal(true);
expect(valFunc('0.5E+10')).to.equal(true);
expect(valFunc('0123')).to.equal(true);
expect(valFunc(123e-10)).to.equal(true);
expect(valFunc(456e-10)).to.equal(true);
expect(valFunc(123)).to.equal(true);
expect(valFunc('123 123 123')).to.equal(true);
expect(valFunc('\t\n ')).to.equal(true);
});

it('returns `false` for text inputs with non-numeric/non-space characters', () => {
expect(valFunc('\t\n ')).to.equal(false);
expect(valFunc('_')).to.equal(false);
expect(valFunc('123!')).to.equal(false);
expect(valFunc('890*')).to.equal(false);
expect(valFunc('123 123 123')).to.equal(false);
expect(valFunc('1234-1234-1234-1234')).to.equal(false);
expect(valFunc('$112233')).to.equal(false);
expect(valFunc('$!\.')).to.equal(false);
expect(valFunc('Is this valid?')).to.equal(false);
});

it('is properly used by a `Field` component to validate', () => {
expect(wrapper.state()).to.have.property('valid', false);
expect(wrapper.state()).to.have.property('value', '');
expect(wrapper.state()).to.have.property('valid', false);

updateInput(wrapper, '12345\t12345 12345');
expect(wrapper.state()).to.have.property('valid', true);
expect(wrapper.state()).to.have.property('value', '12345\t12345 12345');
expect(wrapper.state()).to.have.property('valid', false);

updateInput(wrapper, '1234-1234-1234-1234');
expect(wrapper.state()).to.have.property('valid', false);
expect(wrapper.state()).to.have.property('value', '1234-1234-1234-1234');
expect(wrapper.state()).to.have.property('valid', false);

updateInput(wrapper, 123, 'number');
expect(wrapper.state()).to.have.property('valid', true);
expect(wrapper.state()).to.have.property('value', 123);

updateInput(wrapper, 0.5e3, 'number');
expect(wrapper.state()).to.have.property('valid', true);
expect(wrapper.state()).to.have.property('value', 0.5e3);
});
});

Expand Down