Skip to content

Commit cad7940

Browse files
committed
[fixed] incorrectly limited padded zeros
fixes jquense#355 and also reverts jquense#194 which I liked but was too prone to error, as its hard to tell when the user is "deleting" or starting to type a number. instead everything will be cleaned up on blur
1 parent 0c2407e commit cad7940

File tree

2 files changed

+47
-46
lines changed

2 files changed

+47
-46
lines changed

.eslintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"no-underscore-dangle": 0,
2727
"no-multi-spaces": 0,
2828
"no-unused-expressions": 0,
29-
"no-unused-vars": [2, {"vars": "all", "args": "after-used"}],
29+
"no-unused-vars": [2, {"vars": "all", "args": "after-used", "varsIgnorePattern": "^_$"}],
3030
"no-use-before-define": 0,
3131
"key-spacing": 0,
3232
"consistent-return": 0,

src/NumberInput.jsx

Lines changed: 46 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import CustomPropTypes from './util/propTypes';
3-
import { number as numberLocalizer } from './util/localizers';
3+
import { number as numberLocalizer } from './util/localizers';
44

55
let getFormat = props => numberLocalizer.getFormat('default', props.format)
66

@@ -9,21 +9,21 @@ export default React.createClass({
99
displayName: 'NumberPickerInput',
1010

1111
propTypes: {
12-
value: React.PropTypes.number,
12+
value: React.PropTypes.number,
1313
placeholder: React.PropTypes.string,
1414

15-
format: CustomPropTypes.numberFormat,
15+
format: CustomPropTypes.numberFormat,
1616

17-
parse: React.PropTypes.func,
18-
culture: React.PropTypes.string,
17+
parse: React.PropTypes.func,
18+
culture: React.PropTypes.string,
1919

20-
min: React.PropTypes.number,
20+
min: React.PropTypes.number,
2121

22-
onChange: React.PropTypes.func.isRequired,
23-
onKeyDown: React.PropTypes.func
22+
onChange: React.PropTypes.func.isRequired,
23+
onKeyDown: React.PropTypes.func
2424
},
2525

26-
getDefaultProps(){
26+
getDefaultProps() {
2727
return {
2828
value: null,
2929
editing: false
@@ -35,8 +35,6 @@ export default React.createClass({
3535
, decimal = numberLocalizer.decimalChar(null, props.culture)
3636
, format = getFormat(props);
3737

38-
this._beginningWithSign = false;
39-
4038
if (value == null || isNaN(props.value))
4139
value = ''
4240
else
@@ -67,48 +65,35 @@ export default React.createClass({
6765
className='rw-input'
6866
onChange={this._change}
6967
onBlur={this._finish}
70-
onKeyPress={this._typing}
7168
aria-disabled={this.props.disabled}
7269
aria-readonly={this.props.readOnly}
7370
disabled={this.props.disabled}
7471
readOnly={this.props.readOnly}
7572
placeholder={this.props.placeholder}
76-
value={value}/>
73+
value={value}
74+
/>
7775
)
7876
},
7977

80-
_typing(e) {
81-
var current = e.target.value
82-
, newVal = e.key;
83-
84-
this._beginningWithSign = current.trim() === '' && this.isSign(newVal)
85-
86-
this.props.onKeyPress
87-
&& this.props.onKeyPress(e)
88-
},
89-
9078
_change(e) {
9179
var val = e.target.value
9280
, number = this._parse(e.target.value)
93-
, atSign = this.isSign(val.trim())
94-
, startingWithSign = this._beginningWithSign;
9581

96-
this._beginningWithSign = false;
82+
let isIntermediate = this.isIntermediateValue(number, val);
9783

98-
if (val == null || val.trim() === '' || (atSign && !startingWithSign)) {
84+
if (val == null || val.trim() === '') {
9985
this.current('')
10086
return this.props.onChange(null)
10187
}
10288

103-
if (this.isFlushable(number, val)) {
104-
if (number !== this.props.value)
89+
if (!isIntermediate) {
90+
if (number !== this.props.value) {
10591
return this.props.onChange(number)
106-
else
107-
this.setState(this.getDefaultState()) // 5. -> 5
92+
}
10893
}
109-
110-
if (number < this.props.min || (atSign && startingWithSign) || this.isAtDelimiter(number, val))
94+
else {
11195
this.current(e.target.value)
96+
}
11297
},
11398

11499
_finish() {
@@ -117,7 +102,10 @@ export default React.createClass({
117102

118103
// if number is below the min
119104
// we need to flush low values and decimal stops, onBlur means i'm done inputing
120-
if (!isNaN(number) && (number < this.props.min || this.isAtDelimiter(number, str)) ) {
105+
if (this.isIntermediateValue(number, str)) {
106+
if (isNaN(number)) {
107+
number = null;
108+
}
121109
this.props.onChange(number)
122110
}
123111
},
@@ -136,29 +124,42 @@ export default React.createClass({
136124
return strVal
137125
},
138126

139-
isFlushable(num, str) {
140-
return (
141-
this.isValid(num)
142-
&& !this.isAtDelimiter(num, str)
143-
&& !this.isSign(str)
144-
)
127+
isIntermediateValue(num, str) {
128+
return !!(
129+
num < this.props.min ||
130+
this.isSign(str) ||
131+
this.isAtDelimiter(num, str) ||
132+
this.isPaddedZeros(str)
133+
);
145134
},
146135

147136
isSign(val) {
148137
return (val || '').trim() === '-';
149138
},
150139

140+
isPaddedZeros(str) {
141+
let localeChar = numberLocalizer.decimalChar(null, this.props.culture)
142+
let [_, decimals] = str.split(localeChar);
143+
144+
return !!(
145+
decimals &&
146+
decimals.match(/0+$/)
147+
)
148+
},
149+
151150
isAtDelimiter(num, str, props = this.props) {
152151
var localeChar = numberLocalizer.decimalChar(null, props.culture)
153152
, lastIndex = str.length - 1
154153
, char;
155154

156-
if (str.length <= 1) return false
155+
if (str.length < 1) return false
157156

158157
char = str[lastIndex]
159158

160-
return char === localeChar
161-
&& str.indexOf(char) === lastIndex
159+
return !!(
160+
char === localeChar &&
161+
str.indexOf(char) === lastIndex
162+
)
162163
},
163164

164165
isValid(num) {
@@ -168,8 +169,8 @@ export default React.createClass({
168169
},
169170

170171
//this intermediate state is for when one runs into the decimal or are typing the number
171-
current(val) {
172-
this.setState({ stringValue: val })
172+
current(stringValue) {
173+
this.setState({ stringValue })
173174
}
174175

175176
});

0 commit comments

Comments
 (0)