Skip to content

Commit e0949e8

Browse files
authored
Merge pull request davidkpiano#985 from brycesenz/master
Adding in formatter functionality
2 parents f9fdaff + 1ad5414 commit e0949e8

File tree

3 files changed

+83
-2
lines changed

3 files changed

+83
-2
lines changed

src/components/control-component.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ const propTypes = {
8888
component: PropTypes.any,
8989
dispatch: PropTypes.func,
9090
parser: PropTypes.func,
91+
formatter: PropTypes.func,
9192
ignore: PropTypes.oneOfType([
9293
PropTypes.arrayOf(PropTypes.string),
9394
PropTypes.string,
@@ -149,7 +150,7 @@ function createControlClass(s = defaultStrategy) {
149150
this.willValidate = false;
150151

151152
this.state = {
152-
viewValue: props.modelValue,
153+
viewValue: this.format(props.modelValue),
153154
};
154155
}
155156

@@ -360,7 +361,12 @@ function createControlClass(s = defaultStrategy) {
360361

361362
setViewValue(viewValue) {
362363
if (!this.props.isToggle) {
363-
this.setState({ viewValue: this.parse(viewValue) });
364+
if (this.props.formatter) {
365+
const parsedValue = this.parse(viewValue);
366+
this.setState({ viewValue: this.format(parsedValue) });
367+
} else {
368+
this.setState({ viewValue: this.parse(viewValue) });
369+
}
364370
}
365371
}
366372

@@ -436,6 +442,12 @@ function createControlClass(s = defaultStrategy) {
436442
: value;
437443
}
438444

445+
format(value) {
446+
return this.props.formatter
447+
? this.props.formatter(value)
448+
: value;
449+
}
450+
439451
handleChange(event) {
440452
if (event && event.persist) event.persist();
441453

src/components/field-component.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const fieldPropTypes = {
2929
PropTypes.string,
3030
]),
3131
parser: PropTypes.func,
32+
formatter: PropTypes.func,
3233
updateOn: PropTypes.oneOfType([
3334
PropTypes.arrayOf(PropTypes.string),
3435
PropTypes.string,
@@ -242,6 +243,7 @@ function createFieldClass(customControlPropsMap = {}, s = defaultStrategy) {
242243
updateOn: 'change',
243244
asyncValidateOn: 'blur',
244245
parser: identity,
246+
formatter: identity,
245247
changeAction: actions.change,
246248
dynamic: true,
247249
component: 'div',

test/field-formatter-spec.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { assert } from 'chai';
2+
import React from 'react';
3+
import TestUtils from 'react-dom/test-utils';
4+
import { combineReducers, createStore } from 'redux';
5+
import { Provider } from 'react-redux';
6+
7+
import { modelReducer, Field, formReducer } from '../src';
8+
9+
describe('<Field formatter={...} />', () => {
10+
it('should format the initial value immediately', () => {
11+
const store = createStore(combineReducers({
12+
test: modelReducer('test', { foo: 'initial' }),
13+
testForm: formReducer('test', { foo: 'initial' }),
14+
}));
15+
16+
const formatValue = val => val.toUpperCase();
17+
18+
const field = TestUtils.renderIntoDocument(
19+
<Provider store={store}>
20+
<Field
21+
model="test.foo"
22+
formatter={formatValue}
23+
>
24+
<input type="text" />
25+
</Field>
26+
</Provider>
27+
);
28+
29+
const input = TestUtils.findRenderedDOMComponentWithTag(field, 'input');
30+
31+
assert.equal(input.value, 'INITIAL');
32+
33+
assert.equal(store.getState().test.foo, 'initial');
34+
});
35+
36+
it('should update the viewValue with only the data returned by formatter', () => {
37+
const initial = { foo: '0123456789' };
38+
const expected = '0123';
39+
const inputValue = '012345678912341268374612837';
40+
41+
const store = createStore(combineReducers({
42+
test: modelReducer('test', initial),
43+
testForm: formReducer('test', initial),
44+
}));
45+
46+
const formatValue = val => val.substring(0, 4);
47+
48+
const field = TestUtils.renderIntoDocument(
49+
<Provider store={store}>
50+
<Field
51+
model="test.foo"
52+
formatter={formatValue}
53+
>
54+
<input type="text" />
55+
</Field>
56+
</Provider>
57+
);
58+
59+
const input = TestUtils.findRenderedDOMComponentWithTag(field, 'input');
60+
input.value = inputValue;
61+
TestUtils.Simulate.change(input);
62+
63+
assert.equal(input.value, expected);
64+
65+
assert.equal(store.getState().test.foo, inputValue);
66+
});
67+
});

0 commit comments

Comments
 (0)