Skip to content

Commit eee7927

Browse files
committed
- Refactor code for #193
- Added test for failing case - Bump version
1 parent c833247 commit eee7927

File tree

7 files changed

+108
-72
lines changed

7 files changed

+108
-72
lines changed

dist/react-number-format.js

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
2-
* react-number-format - 3.4.1
2+
* react-number-format - 3.4.2
33
* Author : Sudhanshu Yadav
44
* Copyright (c) 2016,2018 to Sudhanshu Yadav - ignitersworld.com , released under the MIT license.
55
*/
@@ -208,7 +208,10 @@ return /******/ (function(modules) { // webpackBootstrap
208208
var formattedValue = props.value === undefined ? lastValueWithNewFormat : this.formatValueProp();
209209
var _numAsString = this.removeFormatting(formattedValue);
210210

211-
if (parseFloat(_numAsString) !== parseFloat(lastNumStr) || lastValueWithNewFormat !== stateValue) {
211+
var floatValue = parseFloat(_numAsString);
212+
var lastFloatValue = parseFloat(lastNumStr);
213+
214+
if ((!isNaN(floatValue) || !isNaN(lastFloatValue)) && floatValue !== lastFloatValue || lastValueWithNewFormat !== stateValue) {
212215
this.setState({
213216
value: formattedValue,
214217
numAsString: _numAsString
@@ -296,6 +299,17 @@ return /******/ (function(modules) { // webpackBootstrap
296299

297300
return mask[index] || ' ';
298301
}
302+
}, {
303+
key: 'getValueObject',
304+
value: function getValueObject(formattedValue, numAsString) {
305+
var floatValue = parseFloat(numAsString);
306+
307+
return {
308+
formattedValue: formattedValue,
309+
value: numAsString,
310+
floatValue: isNaN(floatValue) ? undefined : floatValue
311+
};
312+
}
299313
}, {
300314
key: 'validateProps',
301315
value: function validateProps() {
@@ -810,13 +824,8 @@ return /******/ (function(modules) { // webpackBootstrap
810824

811825
var formattedValue = this.formatInput(inputValue) || '';
812826
var numAsString = this.removeFormatting(formattedValue);
813-
var floatValue = parseFloat(numAsString);
814827

815-
var valueObj = {
816-
formattedValue: formattedValue,
817-
value: numAsString,
818-
floatValue: isNaN(floatValue) ? undefined : floatValue
819-
};
828+
var valueObj = this.getValueObject(formattedValue, numAsString);
820829

821830
if (!isAllowed(valueObj)) {
822831
formattedValue = lastValue;
@@ -844,6 +853,8 @@ return /******/ (function(modules) { // webpackBootstrap
844853
}, {
845854
key: 'onBlur',
846855
value: function onBlur(e) {
856+
var _this2 = this;
857+
847858
var props = this.props,
848859
state = this.state;
849860
var format = props.format,
@@ -854,17 +865,13 @@ return /******/ (function(modules) { // webpackBootstrap
854865
if (!format) {
855866
numAsString = (0, _utils.fixLeadingZero)(numAsString);
856867
var formattedValue = this.formatNumString(numAsString);
857-
var valueObj = {
858-
formattedValue: formattedValue,
859-
value: numAsString,
860-
floatValue: parseFloat(numAsString)
861-
};
862868

863869
//change the state
864870
if (formattedValue !== lastValue) {
865871
// the event needs to be persisted because its properties can be accessed in an asynchronous way
866872
e.persist();
867873
this.setState({ value: formattedValue, numAsString: numAsString }, function () {
874+
var valueObj = _this2.getValueObject(formattedValue, numAsString);
868875
props.onValueChange(valueObj, e);
869876
onBlur(e);
870877
});
@@ -876,7 +883,7 @@ return /******/ (function(modules) { // webpackBootstrap
876883
}, {
877884
key: 'onKeyDown',
878885
value: function onKeyDown(e) {
879-
var _this2 = this;
886+
var _this3 = this;
880887

881888
var el = e.target;
882889
var key = e.key;
@@ -892,7 +899,8 @@ return /******/ (function(modules) { // webpackBootstrap
892899
prefix = _props11.prefix,
893900
suffix = _props11.suffix,
894901
format = _props11.format,
895-
onKeyDown = _props11.onKeyDown;
902+
onKeyDown = _props11.onKeyDown,
903+
onValueChange = _props11.onValueChange;
896904

897905
var ignoreDecimalSeparator = decimalScale !== undefined && fixedDecimalScale;
898906
var numRegex = this.getNumberRegex(false, ignoreDecimalSeparator);
@@ -938,8 +946,11 @@ return /******/ (function(modules) { // webpackBootstrap
938946
if (selectionStart <= leftBound + 1 && value[0] === '-' && typeof format === 'undefined') {
939947
var newValue = value.substring(1);
940948
var _numAsString2 = this.removeFormatting(newValue);
949+
var valueObj = this.getValueObject(newValue, _numAsString2);
950+
941951
this.setState({ value: newValue, numAsString: _numAsString2 }, function () {
942-
_this2.setPatchedCaretPosition(el, newCaretPosition, newValue);
952+
_this3.setPatchedCaretPosition(el, newCaretPosition, newValue);
953+
onValueChange(valueObj, e);
943954
});
944955
} else if (!negativeRegex.test(value[expectedCaretPosition])) {
945956
while (!numRegex.test(value[newCaretPosition - 1]) && newCaretPosition > leftBound) {
@@ -992,7 +1003,7 @@ return /******/ (function(modules) { // webpackBootstrap
9921003
}, {
9931004
key: 'onFocus',
9941005
value: function onFocus(e) {
995-
var _this3 = this;
1006+
var _this4 = this;
9961007

9971008
// Workaround Chrome and Safari bug https://bugs.chromium.org/p/chromium/issues/detail?id=779328
9981009
// (onFocus event target selectionStart is always 0 before setTimeout)
@@ -1004,12 +1015,12 @@ return /******/ (function(modules) { // webpackBootstrap
10041015
value = _el$value3 === undefined ? '' : _el$value3;
10051016

10061017

1007-
var caretPosition = _this3.correctCaretPosition(value, selectionStart);
1018+
var caretPosition = _this4.correctCaretPosition(value, selectionStart);
10081019
if (caretPosition !== selectionStart) {
1009-
_this3.setPatchedCaretPosition(el, caretPosition, value);
1020+
_this4.setPatchedCaretPosition(el, caretPosition, value);
10101021
}
10111022

1012-
_this3.props.onFocus(e);
1023+
_this4.props.onFocus(e);
10131024
}, 0);
10141025
}
10151026
}, {

dist/react-number-format.min.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/number_format.js

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,10 @@ var NumberFormat = function (_React$Component) {
140140
var formattedValue = props.value === undefined ? lastValueWithNewFormat : this.formatValueProp();
141141
var _numAsString = this.removeFormatting(formattedValue);
142142

143-
if (parseFloat(_numAsString) !== parseFloat(lastNumStr) || lastValueWithNewFormat !== stateValue) {
143+
var floatValue = parseFloat(_numAsString);
144+
var lastFloatValue = parseFloat(lastNumStr);
145+
146+
if ((!isNaN(floatValue) || !isNaN(lastFloatValue)) && floatValue !== lastFloatValue || lastValueWithNewFormat !== stateValue) {
144147
this.setState({
145148
value: formattedValue,
146149
numAsString: _numAsString
@@ -228,6 +231,17 @@ var NumberFormat = function (_React$Component) {
228231

229232
return mask[index] || ' ';
230233
}
234+
}, {
235+
key: 'getValueObject',
236+
value: function getValueObject(formattedValue, numAsString) {
237+
var floatValue = parseFloat(numAsString);
238+
239+
return {
240+
formattedValue: formattedValue,
241+
value: numAsString,
242+
floatValue: isNaN(floatValue) ? undefined : floatValue
243+
};
244+
}
231245
}, {
232246
key: 'validateProps',
233247
value: function validateProps() {
@@ -742,13 +756,8 @@ var NumberFormat = function (_React$Component) {
742756

743757
var formattedValue = this.formatInput(inputValue) || '';
744758
var numAsString = this.removeFormatting(formattedValue);
745-
var floatValue = parseFloat(numAsString);
746759

747-
var valueObj = {
748-
formattedValue: formattedValue,
749-
value: numAsString,
750-
floatValue: isNaN(floatValue) ? undefined : floatValue
751-
};
760+
var valueObj = this.getValueObject(formattedValue, numAsString);
752761

753762
if (!isAllowed(valueObj)) {
754763
formattedValue = lastValue;
@@ -776,6 +785,8 @@ var NumberFormat = function (_React$Component) {
776785
}, {
777786
key: 'onBlur',
778787
value: function onBlur(e) {
788+
var _this2 = this;
789+
779790
var props = this.props,
780791
state = this.state;
781792
var format = props.format,
@@ -786,17 +797,13 @@ var NumberFormat = function (_React$Component) {
786797
if (!format) {
787798
numAsString = (0, _utils.fixLeadingZero)(numAsString);
788799
var formattedValue = this.formatNumString(numAsString);
789-
var valueObj = {
790-
formattedValue: formattedValue,
791-
value: numAsString,
792-
floatValue: parseFloat(numAsString)
793-
};
794800

795801
//change the state
796802
if (formattedValue !== lastValue) {
797803
// the event needs to be persisted because its properties can be accessed in an asynchronous way
798804
e.persist();
799805
this.setState({ value: formattedValue, numAsString: numAsString }, function () {
806+
var valueObj = _this2.getValueObject(formattedValue, numAsString);
800807
props.onValueChange(valueObj, e);
801808
onBlur(e);
802809
});
@@ -808,7 +815,7 @@ var NumberFormat = function (_React$Component) {
808815
}, {
809816
key: 'onKeyDown',
810817
value: function onKeyDown(e) {
811-
var _this2 = this;
818+
var _this3 = this;
812819

813820
var el = e.target;
814821
var key = e.key;
@@ -824,7 +831,8 @@ var NumberFormat = function (_React$Component) {
824831
prefix = _props11.prefix,
825832
suffix = _props11.suffix,
826833
format = _props11.format,
827-
onKeyDown = _props11.onKeyDown;
834+
onKeyDown = _props11.onKeyDown,
835+
onValueChange = _props11.onValueChange;
828836

829837
var ignoreDecimalSeparator = decimalScale !== undefined && fixedDecimalScale;
830838
var numRegex = this.getNumberRegex(false, ignoreDecimalSeparator);
@@ -870,8 +878,11 @@ var NumberFormat = function (_React$Component) {
870878
if (selectionStart <= leftBound + 1 && value[0] === '-' && typeof format === 'undefined') {
871879
var newValue = value.substring(1);
872880
var _numAsString2 = this.removeFormatting(newValue);
881+
var valueObj = this.getValueObject(newValue, _numAsString2);
882+
873883
this.setState({ value: newValue, numAsString: _numAsString2 }, function () {
874-
_this2.setPatchedCaretPosition(el, newCaretPosition, newValue);
884+
_this3.setPatchedCaretPosition(el, newCaretPosition, newValue);
885+
onValueChange(valueObj, e);
875886
});
876887
} else if (!negativeRegex.test(value[expectedCaretPosition])) {
877888
while (!numRegex.test(value[newCaretPosition - 1]) && newCaretPosition > leftBound) {
@@ -924,7 +935,7 @@ var NumberFormat = function (_React$Component) {
924935
}, {
925936
key: 'onFocus',
926937
value: function onFocus(e) {
927-
var _this3 = this;
938+
var _this4 = this;
928939

929940
// Workaround Chrome and Safari bug https://bugs.chromium.org/p/chromium/issues/detail?id=779328
930941
// (onFocus event target selectionStart is always 0 before setTimeout)
@@ -936,12 +947,12 @@ var NumberFormat = function (_React$Component) {
936947
value = _el$value3 === undefined ? '' : _el$value3;
937948

938949

939-
var caretPosition = _this3.correctCaretPosition(value, selectionStart);
950+
var caretPosition = _this4.correctCaretPosition(value, selectionStart);
940951
if (caretPosition !== selectionStart) {
941-
_this3.setPatchedCaretPosition(el, caretPosition, value);
952+
_this4.setPatchedCaretPosition(el, caretPosition, value);
942953
}
943954

944-
_this3.props.onFocus(e);
955+
_this4.props.onFocus(e);
945956
}, 0);
946957
}
947958
}, {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-number-format",
33
"description": "React component to format number in an input or as a text.",
4-
"version": "3.4.1",
4+
"version": "3.4.2",
55
"main": "lib/number_format.js",
66
"author": "Sudhanshu Yadav",
77
"license": "MIT",

src/number_format.js

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,10 @@ class NumberFormat extends React.Component {
131131
const formattedValue = props.value === undefined ? lastValueWithNewFormat : this.formatValueProp();
132132
const numAsString = this.removeFormatting(formattedValue);
133133

134-
const numAsStringFloat = parseFloat(numAsString);
135-
const lastNumStrFloat = parseFloat(lastNumStr);
134+
const floatValue = parseFloat(numAsString);
135+
const lastFloatValue = parseFloat(lastNumStr);
136136

137-
if ((!isNaN(numAsStringFloat) || !isNaN(lastNumStrFloat)) &&
138-
(parseFloat(numAsString) !== parseFloat(lastNumStr) || lastValueWithNewFormat !== stateValue)) {
137+
if (((!isNaN(floatValue) || !isNaN(lastFloatValue)) && floatValue !== lastFloatValue) || lastValueWithNewFormat !== stateValue) {
139138
this.setState({
140139
value : formattedValue,
141140
numAsString,
@@ -204,6 +203,17 @@ class NumberFormat extends React.Component {
204203
return mask[index] || ' ';
205204
}
206205

206+
getValueObject(formattedValue: string, numAsString: string) {
207+
const floatValue = parseFloat(numAsString);
208+
209+
return {
210+
formattedValue,
211+
value: numAsString,
212+
floatValue: isNaN(floatValue) ? undefined : floatValue
213+
};
214+
215+
}
216+
207217
validateProps() {
208218
const {mask} = this.props;
209219

@@ -628,13 +638,8 @@ class NumberFormat extends React.Component {
628638

629639
let formattedValue = this.formatInput(inputValue) || '';
630640
const numAsString = this.removeFormatting(formattedValue);
631-
const floatValue = parseFloat(numAsString);
632641

633-
const valueObj = {
634-
formattedValue,
635-
value: numAsString,
636-
floatValue: isNaN(floatValue) ? undefined : floatValue
637-
};
642+
const valueObj = this.getValueObject(formattedValue, numAsString);
638643

639644
if (!isAllowed(valueObj)) {
640645
formattedValue = lastValue;
@@ -668,17 +673,13 @@ class NumberFormat extends React.Component {
668673
if (!format) {
669674
numAsString = fixLeadingZero(numAsString);
670675
const formattedValue = this.formatNumString(numAsString);
671-
const valueObj = {
672-
formattedValue,
673-
value: numAsString,
674-
floatValue: parseFloat(numAsString)
675-
};
676676

677677
//change the state
678678
if (formattedValue !== lastValue) {
679679
// the event needs to be persisted because its properties can be accessed in an asynchronous way
680680
e.persist();
681681
this.setState({value : formattedValue, numAsString}, () => {
682+
const valueObj = this.getValueObject(formattedValue, numAsString);
682683
props.onValueChange(valueObj, e);
683684
onBlur(e);
684685
});
@@ -737,13 +738,8 @@ class NumberFormat extends React.Component {
737738
if (selectionStart <= leftBound + 1 && value[0] === '-' && typeof format === 'undefined') {
738739
const newValue = value.substring(1);
739740
const numAsString = this.removeFormatting(newValue);
740-
const floatValue = parseFloat(numAsString);
741+
const valueObj = this.getValueObject(newValue, numAsString);
741742

742-
const valueObj = {
743-
newValue,
744-
value: numAsString,
745-
floatValue: isNaN(floatValue) ? undefined : floatValue
746-
};
747743
this.setState({value: newValue, numAsString}, () => {
748744
this.setPatchedCaretPosition(el, newCaretPosition, newValue);
749745
onValueChange(valueObj, e);

test/library/input.spec.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ describe('NumberFormat as input', () => {
166166
});
167167

168168

169-
it('should not convert empty sting to 0 if isNumericString is true', () => {
169+
it('should not convert empty string to 0 if isNumericString is true', () => {
170170
const wrapper = shallow(<NumberFormat isNumericString={true} value={''} decimalScale={2}/>);
171171
expect(wrapper.state().value).toEqual('');
172172
});
@@ -225,6 +225,14 @@ describe('NumberFormat as input', () => {
225225
expect(spy.calls.argsFor(2)[0]).toEqual({formattedValue: "123.", value: "123.", floatValue: 123});
226226
});
227227

228+
it('should not call setState again if previous and current floatValue is NaN', () => {
229+
const wrapper = shallow(<NumberFormat value="" />);
230+
const instance = wrapper.instance();
231+
spyOn(instance, 'setState');
232+
wrapper.setProps({value: ''});
233+
expect(instance.setState).not.toHaveBeenCalled();
234+
});
235+
228236
describe('Test masking', () => {
229237
it('should allow mask as string', () => {
230238
const wrapper = shallow(<NumberFormat format="#### #### ####" mask="_"/>);

0 commit comments

Comments
 (0)