Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.

Commit 213fd71

Browse files
author
Dominik Sumer
committed
switched from autobind to react-autobind, added possibility to suppress touch on setvalue, added reset functionality, added extra internal var for form validation
1 parent 463b388 commit 213fd71

File tree

8 files changed

+72
-16
lines changed

8 files changed

+72
-16
lines changed

examples/Login/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import Form from '@cat-react/form/Form';
33
import BasicInput from '../components/BasicInput';
4-
import autoBind from 'auto-bind';
4+
import autoBind from 'react-autobind';
55

66
export default class extends React.Component {
77
constructor(props) {

examples/Registration/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import Form from '@cat-react/form/Form';
33
import BasicInput from '../components/BasicInput';
4-
import autoBind from 'auto-bind';
4+
import autoBind from 'react-autobind';
55

66
export default class extends React.Component {
77
constructor(props) {

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"build_examples": "./node_modules/.bin/webpack --config examples/webpack.config.js && cp examples/favicon.ico examples/build/ && cp examples/index.html examples/build/ && ./node_modules/.bin/replace-in-file //build//g \"\" examples/build/index.html --isRegex"
1414
},
1515
"dependencies": {
16-
"auto-bind": "^1.1.0",
17-
"prop-types": "^15.5.10"
16+
"prop-types": "^15.5.10",
17+
"react-autobind": "^1.0.6"
1818
},
1919
"devDependencies": {
2020
"babel-eslint": "^7.2.3",

src/Form.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3-
import autoBind from 'auto-bind';
3+
import autoBind from 'react-autobind';
44
import validationRules from './validationRules';
55

66
export default class Form extends React.Component {
@@ -18,6 +18,7 @@ export default class Form extends React.Component {
1818
this.inputs = [];
1919
this.valid = false;
2020
this.validationQueue = [];
21+
this.validating = false;
2122

2223
autoBind(this);
2324
}
@@ -77,7 +78,7 @@ export default class Form extends React.Component {
7778
}
7879

7980
isValidating() {
80-
return this.validationQueue.length > 0;
81+
return this.validationQueue.length > 0 || this.validating;
8182
}
8283

8384
isValid() {
@@ -135,12 +136,14 @@ export default class Form extends React.Component {
135136
}
136137

137138
async startValidation() {
138-
if (this.validationQueue.length > 0) {
139+
if (this.validationQueue.length > 0 && !this.validating) {
140+
this.validating = true;
139141
const nextInputName = this.validationQueue.splice(0, 1)[0];
140142
const nextInput = this.inputs.find((input) => input.hasName(nextInputName));
141143
if (nextInput) {
142144
await nextInput.validate();
143145
}
146+
this.validating = false;
144147
this.startValidation();
145148
} else {
146149
let allValid = !this.inputs.some((input) => !input.isValid());
@@ -181,6 +184,12 @@ export default class Form extends React.Component {
181184
return values;
182185
}
183186

187+
reset() {
188+
for (let input of this.inputs) {
189+
input.reset();
190+
}
191+
}
192+
184193
render() {
185194
const {children, className} = this.props;
186195

src/Input.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3-
import autoBind from 'auto-bind';
3+
import autoBind from 'react-autobind';
44
import Form from './Form';
55

66
const CHANGE_VALUE_TIMEOUT = 350;
@@ -81,14 +81,16 @@ export default function (WrappedComponent) {
8181
return this.state.value;
8282
}
8383

84-
setValue(value) {
84+
setValue(value, suppressTouch) {
8585
clearTimeout(this.changeValueTimer);
8686
this.context._reactForm.addToValidationQueue(this);
8787
this.setState({
8888
value: value
8989
}, () => {
9090
this.changeValueTimer = setTimeout(() => {
91-
this.touch();
91+
if (!suppressTouch) {
92+
this.touch();
93+
}
9294
this.context._reactForm.startValidation();
9395
}, CHANGE_VALUE_TIMEOUT);
9496
});
@@ -150,11 +152,20 @@ export default function (WrappedComponent) {
150152
valid = await Form.validationRules[ruleName](this.context._reactForm.getValues(), this.getValue(), ruleConditions);
151153
} else if (typeof ruleConditions === 'function') {
152154
valid = await ruleConditions(this.context._reactForm.getValues(), this.getValue());
155+
} else if (ruleConditions instanceof Array) {
156+
valid = await ruleConditions[0](this.context._reactForm.getValues(), this.getValue(), ruleConditions[1]);
153157
}
154158

155159
return valid;
156160
}
157161

162+
reset() {
163+
this.setValue(this.props.value, true);
164+
this.setState({
165+
pristine: true
166+
});
167+
}
168+
158169
render() {
159170
const props = {
160171
isRequired: this.isRequired,
@@ -173,6 +184,7 @@ export default function (WrappedComponent) {
173184
}
174185
}
175186
Input.propTypes = {
187+
value: PropTypes.any,
176188
name: PropTypes.string.isRequired,
177189
validations: PropTypes.object,
178190
warnings: PropTypes.arrayOf(PropTypes.string),

tests/Form.spec.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ describe('Form', () => {
153153
let wrapper;
154154
let onValidCalled = false;
155155
let onInvalidated = false;
156-
let onValid = function() {
156+
let onValid = function () {
157157
onValidCalled = true;
158158
if (onInvalidated) {
159159
done();
@@ -163,7 +163,7 @@ describe('Form', () => {
163163
});
164164
}
165165
};
166-
let onInvalid = function(values, validating) {
166+
let onInvalid = function (values, validating) {
167167
if (!validating) {
168168
onInvalidated = true;
169169
expect(onValidCalled).toBe(true);
@@ -174,4 +174,19 @@ describe('Form', () => {
174174
};
175175
wrapper = mount(<SpecialForm onValid={onValid} onInvalid={onInvalid}/>);
176176
});
177+
178+
it('should reset the form correctly', () => {
179+
let wrapper = mount(<Form>
180+
<CustomInput name="email" value="abc"/>
181+
<CustomInput name="email2" value="jmc"/>
182+
</Form>);
183+
wrapper.instance().inputs[0].setValue('test1');
184+
wrapper.instance().inputs[1].setValue('test2');
185+
wrapper.update();
186+
expect(wrapper.instance().inputs[0].getValue()).toEqual('test1');
187+
expect(wrapper.instance().inputs[1].getValue()).toEqual('test2');
188+
wrapper.instance().reset();
189+
expect(wrapper.instance().inputs[0].getValue()).toEqual('abc');
190+
expect(wrapper.instance().inputs[1].getValue()).toEqual('jmc');
191+
});
177192
});

tests/Input.spec.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,15 @@ describe('Input', () => {
6464
}, 400);
6565
});
6666

67+
it('should reset the input correctly', () => {
68+
let wrapper = shallow(<CustomInput name="email" value="myValue2"/>, formContext);
69+
wrapper.instance().setValue('myValue3');
70+
wrapper.update();
71+
expect(wrapper.instance().getValue()).toBe('myValue3');
72+
wrapper.instance().reset();
73+
expect(wrapper.instance().getValue()).toBe('myValue2');
74+
});
75+
6776
it('should unmount correctly', () => {
6877
let wrapper = shallow(<CustomInput name="email" className="myInput"/>, formContext);
6978
const instance = wrapper.instance();
@@ -152,4 +161,15 @@ describe('Input', () => {
152161
wrapper.instance().setValue('asd');
153162
await expect(wrapper.instance().validate()).resolves.toBe(false);
154163
});
164+
165+
it('should validate the input with a custom validator and condition', async () => {
166+
let wrapper = shallow(<CustomInput name="email" dependencies={['email2']} value="itsMyValue"
167+
validations={{
168+
myValidator: [function (values, value, condition) {
169+
return value === "itsMyValue" && condition === "test";
170+
}, "test"]
171+
}}/>, formContext);
172+
173+
await expect(wrapper.instance().validate()).resolves.toBe(true);
174+
});
155175
});

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,6 @@ asynckit@^0.4.0:
246246
version "0.4.0"
247247
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
248248

249-
auto-bind@^1.1.0:
250-
version "1.1.0"
251-
resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-1.1.0.tgz#93b864dc7ee01a326281775d5c75ca0a751e5961"
252-
253249
autoprefixer@^6.3.1:
254250
version "6.7.7"
255251
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014"
@@ -4592,6 +4588,10 @@ rc@^1.1.7:
45924588
minimist "^1.2.0"
45934589
strip-json-comments "~2.0.1"
45944590

4591+
react-autobind@^1.0.6:
4592+
version "1.0.6"
4593+
resolved "https://registry.yarnpkg.com/react-autobind/-/react-autobind-1.0.6.tgz#936bb58edf6b89b619c50f82f0e617159fdfd4f1"
4594+
45954595
react-dom@^15.6.1:
45964596
version "15.6.1"
45974597
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.1.tgz#2cb0ed4191038e53c209eb3a79a23e2a4cf99470"

0 commit comments

Comments
 (0)