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

Commit 6df9d82

Browse files
authored
Merge pull request #984 from keattang/add_field_value
Added fieldValue to mapped props when withFieldValue provided to Control
2 parents 05764e4 + 52631d5 commit 6df9d82

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

docs/api/Control.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ const length = (val) => val.length > 8;
163163
```
164164

165165
## `debounce={...}` {#prop-debounce}
166-
_(Number)_: The time in milliseconds, by which the change action will be debounced.
166+
_(Number)_: The time in milliseconds, by which the change action will be debounced.
167167

168168
## `validateOn="..."` {#prop-validateOn}
169169
_(String | Array)_: A string/array of strings specifying when validation should occur. By default, validation happens with whatever `updateOn` is set to. The `validateOn` property can have these values:
@@ -395,4 +395,9 @@ For `<Control.checkbox />`, the default `getValue` function is:
395395
_(Boolean)_: Signifies that the control is a toggle (e.g., a checkbox or a radio). If `true`, then some optimizations are made.
396396

397397
Default: `true` for `<Control.radio>` and `<Control.checkbox>`, `false` for all other controls.
398+
399+
## `withFieldValue={false}` {#prop-withFieldValue}
400+
_(Boolean)_: When `true` the `fieldValue` prop is mapped on to the child component. This prop contains information about the field's state such as its validity and whether it has been touched. This is particularly useful when using a custom component as it allows you to dynamically alter the component based on the field's state.
401+
402+
Default: `false`
398403
{% endraw %}

src/components/control-component.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ function createControlClass(s = defaultStrategy) {
608608
component,
609609
control,
610610
getRef,
611+
fieldValue,
611612
} = this.props;
612613

613614
const mappedProps = omit(this.getMappedProps(), disallowedProps);
@@ -616,6 +617,10 @@ function createControlClass(s = defaultStrategy) {
616617
mappedProps.getRef = getRef;
617618
}
618619

620+
if (controlProps.withFieldValue) {
621+
mappedProps.fieldValue = fieldValue;
622+
}
623+
619624
// If there is an existing control, clone it
620625
if (control) {
621626
return cloneElement(

test/custom-control-component-spec.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,60 @@ describe('custom <Control /> components', () => {
355355
assert.equal(input.className.trim(), 'touched');
356356
});
357357

358+
it('should pass the fieldValue object when withFieldValue is true', () => {
359+
const store = testCreateStore({
360+
testForm: formReducer('test'),
361+
test: modelReducer('test', { foo: '' }),
362+
});
363+
364+
class TextInput extends React.Component {
365+
render() {
366+
const { fieldValue, ...otherProps } = this.props;
367+
const className = [
368+
fieldValue.focus ? 'focus' : '',
369+
fieldValue.touched ? 'touched' : '',
370+
].join(' ');
371+
372+
return (
373+
<div>
374+
<input
375+
className={className}
376+
{...otherProps}
377+
onChange={this.props.onChangeText}
378+
/>
379+
</div>
380+
);
381+
}
382+
}
383+
384+
TextInput.propTypes = {
385+
onChangeText: PropTypes.func,
386+
focus: PropTypes.bool,
387+
touched: PropTypes.bool,
388+
fieldValue: PropTypes.object,
389+
};
390+
391+
const field = TestUtils.renderIntoDocument(
392+
<Provider store={store}>
393+
<Control
394+
model="test.foo"
395+
component={TextInput}
396+
withFieldValue
397+
/>
398+
</Provider>
399+
);
400+
401+
const input = TestUtils.findRenderedDOMComponentWithTag(field, 'input');
402+
403+
TestUtils.Simulate.focus(input);
404+
405+
assert.equal(input.className.trim(), 'focus');
406+
407+
TestUtils.Simulate.blur(input);
408+
409+
assert.equal(input.className.trim(), 'touched');
410+
});
411+
358412
it('should not pass default mapped props to custom controls', (done) => {
359413
const store = testCreateStore({
360414
testForm: formReducer('test'),

0 commit comments

Comments
 (0)