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

Commit bc4b9b9

Browse files
committed
Ensuring validation and forced update when Enter pressed inside input. Fixes #777
1 parent 1362352 commit bc4b9b9

File tree

2 files changed

+55
-24
lines changed

2 files changed

+55
-24
lines changed

src/components/control-component.js

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ function createControlClass(s = defaultStrategy) {
226226
});
227227
}
228228

229-
getValidateAction(value, eventName) {
229+
getValidateAction(value, eventName, forceUpdate = false) {
230230
const {
231231
validators,
232232
errors,
@@ -241,7 +241,7 @@ function createControlClass(s = defaultStrategy) {
241241
const nodeErrors = this.getNodeErrors();
242242

243243
// If it is not a change event, use the model value.
244-
const valueToValidate = containsEvent(updateOn, eventName)
244+
const valueToValidate = forceUpdate || containsEvent(updateOn, eventName)
245245
? value
246246
: modelValue;
247247

@@ -410,28 +410,22 @@ function createControlClass(s = defaultStrategy) {
410410
: value;
411411
}
412412

413-
handleChange(event) {
413+
handleChange(event, forceUpdate = false) {
414414
if (event && event.persist) event.persist();
415415

416416
this.setViewValue(this.getValue(event));
417-
this.handleUpdate(event);
417+
this.handleUpdate(event, forceUpdate);
418418
}
419419

420420
handleKeyPress(event) {
421421
const {
422422
controlProps: { onKeyPress },
423-
dispatch,
424-
getValue,
425423
} = this.props;
426424

427425
if (onKeyPress) onKeyPress(event);
428426

429-
// Get the value from the event
430-
// in case updateOn="blur" (or something other than "change")
431-
const parsedValue = this.parse(getValue(event));
432-
433427
if (event.key === 'Enter') {
434-
dispatch(this.getChangeAction(parsedValue));
428+
this.handleChange(event, true);
435429
}
436430
}
437431

@@ -500,12 +494,12 @@ function createControlClass(s = defaultStrategy) {
500494
change: controlProps.onChange,
501495
}[eventName];
502496

503-
const dispatchBatchActions = (persistedEvent) => {
497+
const dispatchBatchActions = (persistedEvent, forceUpdate = false) => {
504498
const eventActions = [
505499
eventAction && eventAction(model),
506-
containsEvent(validateOn, eventName)
507-
&& this.getValidateAction(persistedEvent, eventName),
508-
containsEvent(updateOn, eventName)
500+
(forceUpdate || containsEvent(validateOn, eventName))
501+
&& this.getValidateAction(persistedEvent, eventName, forceUpdate),
502+
(forceUpdate || containsEvent(updateOn, eventName))
509503
&& this.getChangeAction(persistedEvent),
510504
];
511505

@@ -514,7 +508,7 @@ function createControlClass(s = defaultStrategy) {
514508
return persistedEvent;
515509
};
516510

517-
return (event) => {
511+
return (event, forceUpdate = false) => {
518512
if (containsEvent(ignore, eventName)) {
519513
return controlEventHandler
520514
? controlEventHandler(event)
@@ -528,7 +522,6 @@ function createControlClass(s = defaultStrategy) {
528522
)(event);
529523
}
530524

531-
532525
return compose(
533526
(e) => {
534527
if (containsEvent(asyncValidateOn, eventName)) {
@@ -537,7 +530,7 @@ function createControlClass(s = defaultStrategy) {
537530

538531
return e;
539532
},
540-
dispatchBatchActions,
533+
(e) => dispatchBatchActions(e, forceUpdate),
541534
parser,
542535
(e) => this.getValue(e),
543536
persistEventWithCallback(controlEventHandler || identity)

test/control-component-spec.js

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,13 +1290,12 @@ Object.keys(testContexts).forEach((testKey) => {
12901290
});
12911291

12921292
describe('change on enter', () => {
1293-
const reducer = modelReducer('test');
1294-
const store = testCreateStore({
1295-
test: reducer,
1296-
testForm: formReducer('test'),
1297-
});
1298-
12991293
it('should change the model upon pressing Enter', () => {
1294+
const reducer = modelReducer('test');
1295+
const store = testCreateStore({
1296+
test: reducer,
1297+
testForm: formReducer('test'),
1298+
});
13001299
const field = TestUtils.renderIntoDocument(
13011300
<Provider store={store}>
13021301
<Control.text
@@ -1320,6 +1319,45 @@ Object.keys(testContexts).forEach((testKey) => {
13201319
get(store.getState().test, 'foo'),
13211320
'testing');
13221321
});
1322+
1323+
it('should validate the model upon pressing Enter', () => {
1324+
const reducer = modelReducer('test');
1325+
const store = testCreateStore({
1326+
test: reducer,
1327+
testForm: formReducer('test'),
1328+
});
1329+
const field = TestUtils.renderIntoDocument(
1330+
<Provider store={store}>
1331+
<Control.text
1332+
model="test.foo"
1333+
updateOn="blur"
1334+
validators={{
1335+
isNotBar: v => v !== 'bar',
1336+
}}
1337+
/>
1338+
</Provider>
1339+
);
1340+
1341+
const control = TestUtils.findRenderedDOMComponentWithTag(field, 'input');
1342+
1343+
control.value = 'bar';
1344+
1345+
TestUtils.Simulate.keyPress(control, {
1346+
key: 'Enter',
1347+
keyCode: 13,
1348+
which: 13,
1349+
});
1350+
1351+
assert.equal(
1352+
get(store.getState().test, 'foo'),
1353+
'bar');
1354+
1355+
assert.deepEqual(
1356+
store.getState().testForm.foo.errors,
1357+
{ isNotBar: true });
1358+
1359+
assert.isFalse(store.getState().testForm.foo.valid);
1360+
});
13231361
});
13241362

13251363
describe('handling onKeyPress', () => {

0 commit comments

Comments
 (0)