Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

Commit 7b8ef36

Browse files
committed
Adding event as second argument to Form onSubmit + documentation and unit tests. Fixes #664
1 parent 6d635ad commit 7b8ef36

File tree

4 files changed

+57
-6
lines changed

4 files changed

+57
-6
lines changed

docs/api/Form.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,11 @@ _(Function)_: The handler function called when the form is submitted. This works
9595

9696
- The submit event's default action is prevented by default, using `event.preventDefault()`.
9797
- The `onSubmit` handler _will not execute_ if the form is invalid.
98-
- The `onSubmit` handler receives the form model data, not the event.
98+
- The `onSubmit` handler receives the form model data as the first argument, and the event as the second argument.
9999

100-
The function passed into `onSubmit={...}` will be called with one argument: the form's model value.
100+
The function passed into `onSubmit={...}` will be called with two arguments:
101+
1. the form's model value
102+
2. the native submit event (if applicable).
101103

102104
### Example
103105
```jsx

docs/guides/faqs.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,41 @@ For single or multiple checkboxes that represent boolean keyed values in a model
118118
<Control.checkbox model="user.pets.goat" />
119119
```
120120

121+
### How do I create a file upload form?
122+
The second argument of the `<Form onSubmit={(values, event) => ...}>` prop provides the event emitted when the form was submitted. Adapted from the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects):
123+
124+
```jsx
125+
class UploadForm extends Component {
126+
onSubmit = (values, event) => {
127+
const formData = new FormData(event.target);
128+
129+
const request = new XMLHttpRequest();
130+
request.open('POST', '/upload', true);
131+
request.onload = function(oEvent) {
132+
if (request.status == 200) {
133+
console.log('Uploaded!');
134+
} else {
135+
console.log('Error uploading.');
136+
}
137+
};
138+
139+
request.send(formData);
140+
event.preventDefault();
141+
}
142+
render() {
143+
return (
144+
<Form
145+
model="user"
146+
encType="multipart/form-data"
147+
onSubmit={this.onSubmit}
148+
>
149+
<Control.file model=".avatar" />
150+
<button>Upload!</button>
151+
</Form>
152+
);
153+
};
154+
}
155+
```
156+
121157
### Other Questions and Answers
122158
- https://github.com/davidkpiano/react-redux-form/issues/675#issuecomment-281164930

src/components/form-component.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ function createFormClass(s = defaultStrategy) {
7171
this.handleValidSubmit = this.handleValidSubmit.bind(this);
7272
this.handleInvalidSubmit = this.handleInvalidSubmit.bind(this);
7373
this.attachNode = this.attachNode.bind(this);
74+
75+
this.state = {
76+
lastSubmitEvent: null,
77+
};
7478
}
7579

7680
getChildContext() {
@@ -279,7 +283,7 @@ function createFormClass(s = defaultStrategy) {
279283

280284
dispatch(s.actions.setPending(model, true, options));
281285

282-
if (onSubmit) onSubmit(modelValue);
286+
if (onSubmit) onSubmit(modelValue, this.state.lastSubmitEvent);
283287
}
284288

285289
handleInvalidSubmit(options) {
@@ -323,6 +327,7 @@ function createFormClass(s = defaultStrategy) {
323327

324328
handleSubmit(e) {
325329
if (e && !this.props.action) e.preventDefault();
330+
if (e && e.persist) e.persist();
326331

327332
const {
328333
modelValue,
@@ -339,11 +344,13 @@ function createFormClass(s = defaultStrategy) {
339344
: true;
340345

341346
if (!validators && onSubmit && formValid) {
342-
onSubmit(modelValue);
347+
onSubmit(modelValue, e);
343348

344349
return modelValue;
345350
}
346351

352+
this.setState({ lastSubmitEvent: e });
353+
347354
this.validate(this.props, false, true);
348355

349356
return modelValue;

test/form-component-spec.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,7 @@ Object.keys(testContexts).forEach((testKey) => {
782782
});
783783

784784
let submitValue = null;
785+
let submitEventValue = null;
785786

786787
const form = TestUtils.renderIntoDocument(
787788
<Provider store={store}>
@@ -796,8 +797,9 @@ Object.keys(testContexts).forEach((testKey) => {
796797
errors={{
797798
bar: (val) => val !== 'bar' && 'bar invalid',
798799
}}
799-
onSubmit={(val) => {
800+
onSubmit={(val, event) => {
800801
submitValue = val;
802+
submitEventValue = event;
801803
return true;
802804
}}
803805
>
@@ -834,6 +836,7 @@ Object.keys(testContexts).forEach((testKey) => {
834836
store.getState().testForm.foo.valid);
835837

836838
assert.isNull(submitValue);
839+
assert.isNull(submitEventValue);
837840
});
838841

839842
it('should set submitFailed to true if form is invalid and submitted', () => {
@@ -842,7 +845,7 @@ Object.keys(testContexts).forEach((testKey) => {
842845
assert.isTrue(store.getState().testForm.$form.submitFailed);
843846
});
844847

845-
it('should call onSubmit with model value if form is valid', () => {
848+
it('should call onSubmit with model value and event if form is valid', () => {
846849
barControl.value = 'bar';
847850

848851
TestUtils.Simulate.change(barControl);
@@ -873,6 +876,9 @@ Object.keys(testContexts).forEach((testKey) => {
873876
baz: 'valid',
874877
foo: 'valid',
875878
});
879+
880+
assert.instanceOf(submitEventValue.target, window.HTMLElement,
881+
'second argument should be event with a target');
876882
});
877883
});
878884

0 commit comments

Comments
 (0)