Skip to content

Commit 5947a1b

Browse files
committed
Call beforeMaskedValueChange in constructor
1 parent c05e2bd commit 5947a1b

File tree

4 files changed

+71
-46
lines changed

4 files changed

+71
-46
lines changed

.size-snapshot.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"dist/react-input-mask.js": {
3-
"bundled": 38237,
4-
"minified": 13886,
5-
"gzipped": 4872
3+
"bundled": 38943,
4+
"minified": 14064,
5+
"gzipped": 4921
66
},
77
"lib/react-input-mask.development.js": {
8-
"bundled": 33041,
9-
"minified": 14566,
10-
"gzipped": 4628
8+
"bundled": 33715,
9+
"minified": 14861,
10+
"gzipped": 4668
1111
}
1212
}

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ The following props are considered experimental because they are more prone to i
5757

5858
### `beforeMaskedValueChange` : `function`
5959
In case you need to implement more complex masking behavior, you can provide `beforeMaskedValueChange` function to change masked value and cursor position before it will be applied to the input. `beforeMaskedValueChange` receives following arguments:
60-
1. **newState** (object): New input state. Contains `value` and `selection` fields. `selection` is null on input blur. Example: `{ value: '12/1_/____', selection: { start: 4, end: 4 } }`
61-
2. **oldState** (object): Input state before change. Contains `value` and `selection` fields. `selection` is null on input focus.
60+
1. **newState** (object): New input state. Contains `value` and `selection` fields. `selection` is null on input blur or when function is called before input mount. Example: `{ value: '12/1_/____', selection: { start: 4, end: 4 } }`
61+
2. **oldState** (object): Input state before change. Contains `value` and `selection` fields. `selection` is null on input focus or when function is called before input mount.
6262
3. **userInput** (string): Raw entered or pasted string. `null` if user didn't enter anything (e.g. triggered by deletion or rerender due to props change).
6363
4. **maskOptions** (object): Mask options. Example:
6464
```js

src/index.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class InputElement extends React.Component {
2828
constructor(props) {
2929
super(props);
3030

31-
const { mask, maskChar, formatChars, alwaysShowMask } = props;
31+
const { mask, maskChar, formatChars, alwaysShowMask, beforeMaskedValueChange } = props;
3232
let { defaultValue, value } = props;
3333

3434
this.maskOptions = parseMask(mask, maskChar, formatChars);
@@ -40,13 +40,30 @@ class InputElement extends React.Component {
4040
value = defaultValue;
4141
}
4242

43-
value = getStringValue(value);
43+
let newValue = getStringValue(value);
4444

45-
if (this.maskOptions.mask && (alwaysShowMask || value)) {
46-
value = formatValue(this.maskOptions, value);
45+
if (this.maskOptions.mask && (alwaysShowMask || newValue)) {
46+
newValue = formatValue(this.maskOptions, newValue);
47+
48+
if (isFunction(beforeMaskedValueChange)) {
49+
let oldValue = props.value;
50+
if (props.value == null) {
51+
oldValue = defaultValue;
52+
}
53+
oldValue = getStringValue(oldValue);
54+
55+
const modifiedValue = beforeMaskedValueChange(
56+
{ value: newValue, selection: null },
57+
{ value: oldValue, selection: null },
58+
null,
59+
this.getModifyMaskedValueConfig()
60+
);
61+
62+
newValue = modifiedValue.value;
63+
}
4764
}
4865

49-
this.value = value;
66+
this.value = newValue;
5067
}
5168

5269
componentDidMount() {

tests/input/input.js

+41-33
Original file line numberDiff line numberDiff line change
@@ -882,44 +882,52 @@ describe('react-input-mask', () => {
882882
})();
883883
});
884884

885-
it('should allow to modify value with beforeMaskedValueChange', createInput(
886-
<Input mask="99999-9999" maskChar={null} value="" />, (input, inputNode) => {
887-
setInputProps(input, {
888-
onChange: (event) => {
889-
setInputProps(input, {
890-
value: event.target.value
891-
});
892-
},
893-
beforeMaskedValueChange: (newState, oldState, userInput) => {
894-
let { value } = newState;
895-
let selection = newState.selection;
896-
let cursorPosition = selection ? selection.start : null;
897-
if (value.endsWith('-') && userInput !== '-' && !input.props.value.endsWith('-')) {
898-
if (cursorPosition === value.length) {
899-
cursorPosition--;
900-
selection = { start: cursorPosition, end: cursorPosition };
901-
}
902-
value = value.slice(0, -1);
903-
}
904-
905-
return {
906-
value,
907-
selection
908-
};
885+
it('should allow to modify value with beforeMaskedValueChange', (() => {
886+
const beforeMaskedValueChange = (newState, oldState, userInput, options, inputInstance) => {
887+
let { value } = newState;
888+
let selection = newState.selection;
889+
let cursorPosition = selection ? selection.start : null;
890+
if (value.endsWith('-') && userInput !== '-' && (!inputInstance || !inputInstance.props.value.endsWith('-'))) {
891+
if (cursorPosition === value.length) {
892+
cursorPosition--;
893+
selection = { start: cursorPosition, end: cursorPosition };
909894
}
910-
});
895+
value = value.slice(0, -1);
896+
}
911897

912-
inputNode.focus();
913-
TestUtils.Simulate.focus(inputNode);
898+
return {
899+
value,
900+
selection
901+
};
902+
};
914903

915-
setInputProps(input, { value: '12345' });
916-
expect(inputNode.value).to.equal('12345');
904+
return createInput(
905+
<Input mask="99999-9999" maskChar={null} value="12345" beforeMaskedValueChange={beforeMaskedValueChange} />, (input, inputNode) => {
906+
expect(inputNode.value).to.equal('12345');
917907

918-
input.setCursorPosition(5);
908+
setInputProps(input, {
909+
onChange: (event) => {
910+
setInputProps(input, {
911+
value: event.target.value
912+
});
913+
},
914+
beforeMaskedValueChange: (newState, oldState, userInput, options) => {
915+
return beforeMaskedValueChange(newState, oldState, userInput, options, input);
916+
}
917+
});
919918

920-
simulateInputKeyPress(input, '-');
921-
expect(inputNode.value).to.equal('12345-');
922-
}));
919+
inputNode.focus();
920+
TestUtils.Simulate.focus(inputNode);
921+
922+
setInputProps(input, { value: '12345' });
923+
expect(inputNode.value).to.equal('12345');
924+
925+
input.setCursorPosition(5);
926+
927+
simulateInputKeyPress(input, '-');
928+
expect(inputNode.value).to.equal('12345-');
929+
});
930+
})());
923931

924932
it('shouldn\'t modify value on entering non-allowed character', createInput(
925933
<Input mask="9999" defaultValue="1234" />, (input, inputNode) => {

0 commit comments

Comments
 (0)