1- /**
2- *
3- *
4- */
5-
6- import React , { PropTypes } from 'react'
1+ import React , { PropTypes } from 'react'
72import mask from './mask.js'
83
94
105const 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 (
0 commit comments