Skip to content

Commit 9fab3d1

Browse files
authored
Merge pull request #8 from igorsantos07/patch-2
adding allowEmpty to component
2 parents acfb4ae + 27b51e1 commit 9fab3d1

File tree

2 files changed

+63
-74
lines changed

2 files changed

+63
-74
lines changed

src/index.js

Lines changed: 54 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
1-
/**
2-
*
3-
*
4-
*/
5-
6-
import React, {PropTypes} from 'react'
1+
import React, { PropTypes } from 'react'
72
import mask from './mask.js'
83

94

105
const CurrencyInput = React.createClass({
116

12-
137
/**
14-
* Prop validation. See: https://facebook.github.io/react/docs/component-specs.html#proptypes
8+
* Prop validation.
9+
* @see https://facebook.github.io/react/docs/component-specs.html#proptypes
1510
*/
1611
propTypes: {
1712
onChange: PropTypes.func,
@@ -21,114 +16,99 @@ const CurrencyInput = React.createClass({
2116
precision: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
2217
inputType: PropTypes.string,
2318
allowNegative: PropTypes.bool,
19+
allowEmpty: PropTypes.bool,
2420
prefix: PropTypes.string,
2521
suffix: PropTypes.string
2622
},
2723

2824

2925
/**
30-
* Component lifecycle function. See: https://facebook.github.io/react/docs/component-specs.html#getdefaultprops
26+
* Component lifecycle function.
3127
*
3228
* Invoked once and cached when the class is created. Values in the mapping will be set on this.props if that
3329
* prop is not specified by the parent component
3430
*
35-
* @returns {{onChange: onChange, value: string, decimalSeparator: string, thousandSeparator: string, precision: number, inputType: string, allowNegative: boolean}}
31+
* @see https://facebook.github.io/react/docs/component-specs.html#getdefaultprops
3632
*/
37-
getDefaultProps(){
33+
getDefaultProps() {
3834
return {
39-
onChange: function(maskValue, value){/*no-op*/},
40-
value: "0",
41-
decimalSeparator: ".",
42-
thousandSeparator: ",",
43-
precision: "2",
44-
inputType: "text",
35+
onChange: function(maskValue, value, event) {/*no-op*/},
36+
value: '0',
37+
decimalSeparator: '.',
38+
thousandSeparator: ',',
39+
precision: '2',
40+
inputType: 'text',
4541
allowNegative: false,
4642
prefix: '',
4743
suffix: ''
4844
}
4945
},
5046

51-
5247
/**
53-
* Component lifecycle function. See: https://facebook.github.io/react/docs/component-specs.html#getinitialstate
54-
*
55-
* Invoked once before the component is mounted. The return value will be used as the initial value of this.state
56-
*
57-
* @returns {{maskedValue, customProps: *}}
48+
* General function used to cleanup and define the final props used for rendering
49+
* @returns {{ maskedValue: {String}, value: {Number}, customProps: {Object} }}
5850
*/
59-
getInitialState(){
60-
let customProps = Object.assign({}, this.props); //polyfilled for environments that do not support it.
51+
prepareProps(props) {
52+
let customProps = Object.assign({}, props); //polyfilled for environments that do not support it.
6153
delete customProps.onChange;
6254
delete customProps.value;
6355
delete customProps.decimalSeparator;
6456
delete customProps.thousandSeparator;
6557
delete customProps.precision;
6658
delete customProps.inputType;
6759
delete customProps.allowNegative;
60+
delete customProps.allowEmpty;
6861
delete customProps.prefix;
6962
delete customProps.suffix;
7063

64+
let initialValue = props.value;
65+
if (!initialValue) {
66+
initialValue = props.allowEmpty? null : '';
67+
}
68+
7169
const { maskedValue, value } = mask(
72-
this.props.value,
73-
this.props.precision,
74-
this.props.decimalSeparator,
75-
this.props.thousandSeparator,
76-
this.props.allowNegative,
77-
this.props.prefix,
78-
this.props.suffix
70+
initialValue,
71+
props.precision,
72+
props.decimalSeparator,
73+
props.thousandSeparator,
74+
props.allowNegative,
75+
props.prefix,
76+
props.suffix
7977
);
8078

81-
return {
82-
maskedValue,
83-
value,
84-
customProps: customProps
85-
}
79+
return { maskedValue, value, customProps };
8680
},
8781

88-
8982
/**
90-
* Component lifecycle function. See: https://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops
83+
* Component lifecycle function.
84+
* Invoked once before the component is mounted. The return value will be used as the initial value of this.state
9185
*
86+
* @returns {{ maskedValue: {String}, value: {Number}, customProps: {Object} }}
87+
* @see https://facebook.github.io/react/docs/component-specs.html#getinitialstate
88+
*/
89+
getInitialState() {
90+
return this.prepareProps(this.props);
91+
},
92+
93+
94+
/**
95+
* Component lifecycle function.
9296
* Invoked when a component is receiving new props. This method is not called for the initial render.
9397
*
9498
* @param nextProps
99+
* @see https://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops
95100
*/
96-
componentWillReceiveProps(nextProps){
97-
let customProps = Object.assign({}, nextProps); //polyfilled for environments that do not support it.
98-
delete customProps.onChange;
99-
delete customProps.value;
100-
delete customProps.decimalSeparator;
101-
delete customProps.thousandSeparator;
102-
delete customProps.precision;
103-
delete customProps.inputType;
104-
delete customProps.allowNegative;
105-
delete customProps.prefix;
106-
delete customProps.suffix;
107-
108-
const {maskedValue, value} = mask(
109-
nextProps.value,
110-
nextProps.precision,
111-
nextProps.decimalSeparator,
112-
nextProps.thousandSeparator,
113-
nextProps.allowNegative,
114-
nextProps.prefix,
115-
nextProps.suffix
116-
);
117-
118-
this.setState({
119-
maskedValue,
120-
value,
121-
customProps: customProps
122-
});
101+
componentWillReceiveProps(nextProps) {
102+
this.setState(this.prepareProps(nextProps));
123103
},
124104

125105

126106
/**
127107
* Exposes the current masked value.
128108
*
129-
* @returns {*}
109+
* @returns {String}
130110
*/
131-
getMaskedValue(){
111+
getMaskedValue() {
132112
return this.state.maskedValue;
133113
},
134114

@@ -137,9 +117,9 @@ const CurrencyInput = React.createClass({
137117
* onChange Event Handler
138118
* @param event
139119
*/
140-
handleChange(event){
120+
handleChange(event) {
141121
event.preventDefault();
142-
let {maskedValue, value} = mask(
122+
let { maskedValue, value } = mask(
143123
event.target.value,
144124
this.props.precision,
145125
this.props.decimalSeparator,
@@ -148,14 +128,15 @@ const CurrencyInput = React.createClass({
148128
this.props.prefix,
149129
this.props.suffix
150130
);
151-
this.setState({maskedValue, value});
152-
this.props.onChange(maskedValue, value);
131+
this.setState({ maskedValue, value });
132+
this.props.onChange(maskedValue, value, event);
153133
},
154134

155135

156136
/**
157-
* Component lifecycle function. See: https://facebook.github.io/react/docs/component-specs.html#render
137+
* Component lifecycle function.
158138
* @returns {XML}
139+
* @see https://facebook.github.io/react/docs/component-specs.html#render
159140
*/
160141
render() {
161142
return (

src/mask.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,16 @@ export default function mask(value, precision = 2, decimalSeparator = '.', thous
33
// provide some default values and arg validation.
44
if (precision < 0) { precision = 0; } // precision cannot be negative
55
if (precision > 20) { precision = 20; } // precision cannot be greater than 20
6+
7+
if (value === null) {
8+
return {
9+
value: '',
10+
maskedValue: ''
11+
};
12+
}
13+
614
value = String(value); //if the given value is a Number, let's convert into String to manipulate that
7-
15+
816
// extract digits. if no digits, fill in a zero.
917
let digits = value.match(/\d/g) || ['0'];
1018

0 commit comments

Comments
 (0)