From e96d0ec4e1af3181d6d5ad5a8dd29eda71728990 Mon Sep 17 00:00:00 2001 From: jrs1 Date: Fri, 9 Dec 2016 12:05:43 -0800 Subject: [PATCH] * #3 added feature to support prefix and suffix currency symbols * bumped version number to 1.0.7 --- README.md | 17 +++++++++++++++++ package.json | 2 +- src/index.js | 40 +++++++++++++++++++++++++++++++++++----- src/mask.js | 11 +++++++++-- test/index.spec.js | 38 ++++++++++++++++++++++++++++++++++++++ test/mask.spec.js | 30 +++++++++++++++++++++++++++++- 6 files changed, 129 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a5a1d9a..125a13c 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,21 @@ Specify a specific precision: ``` +## Currency + +Optionally set a currency symbol as a prefix or suffix +```javascript + // $1,234,567.89 + +``` + +```javascript + // 1,234,567.89 kr + +``` + + + All other attributes are applied to the input element. For example, you can integrate bootstrap styling: ```javascript @@ -102,5 +117,7 @@ All other attributes are applied to the input element. For example, you can int | thousandSeparator | ',' | The thousand separator | | inputType | "text" | Input field tag type. You may want to use `number` or `tel` | | allowNegative | false | Allows negative numbers in the input | +| prefix | '' | Currency prefix | +| suffix | '' | Currency suffix | diff --git a/package.json b/package.json index 0aa13c6..afc513d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-currency-input", - "version": "1.0.6", + "version": "1.0.7", "description": "React component for inputing currency amounts", "main": "lib/index.js", "scripts": { diff --git a/src/index.js b/src/index.js index f8a01a6..8ba8bed 100644 --- a/src/index.js +++ b/src/index.js @@ -20,7 +20,9 @@ const CurrencyInput = React.createClass({ thousandSeparator: PropTypes.string, precision: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), inputType: PropTypes.string, - allowNegative: PropTypes.bool + allowNegative: PropTypes.bool, + prefix: PropTypes.string, + suffix: PropTypes.string }, @@ -40,7 +42,9 @@ const CurrencyInput = React.createClass({ thousandSeparator: ",", precision: "2", inputType: "text", - allowNegative: false + allowNegative: false, + prefix: '', + suffix: '' } }, @@ -61,8 +65,18 @@ const CurrencyInput = React.createClass({ delete customProps.precision; delete customProps.inputType; delete customProps.allowNegative; + delete customProps.prefix; + delete customProps.suffix; return { - maskedValue: mask(this.props.value, this.props.precision, this.props.decimalSeparator, this.props.thousandSeparator, this.props.allowNegative), + maskedValue: mask( + this.props.value, + this.props.precision, + this.props.decimalSeparator, + this.props.thousandSeparator, + this.props.allowNegative, + this.props.prefix, + this.props.suffix + ), customProps: customProps } }, @@ -85,7 +99,15 @@ const CurrencyInput = React.createClass({ delete customProps.inputType; delete customProps.allowNegative; this.setState({ - maskedValue: mask(nextProps.value, nextProps.precision, nextProps.decimalSeparator, nextProps.thousandSeparator, nextProps.allowNegative), + maskedValue: mask( + nextProps.value, + nextProps.precision, + nextProps.decimalSeparator, + nextProps.thousandSeparator, + nextProps.allowNegative, + nextProps.prefix, + nextProps.suffix + ), customProps: customProps }); }, @@ -107,7 +129,15 @@ const CurrencyInput = React.createClass({ */ handleChange(event){ event.preventDefault(); - let maskedValue = mask(event.target.value, this.props.precision, this.props.decimalSeparator, this.props.thousandSeparator, this.props.allowNegative); + let maskedValue = mask( + event.target.value, + this.props.precision, + this.props.decimalSeparator, + this.props.thousandSeparator, + this.props.allowNegative, + this.props.prefix, + this.props.suffix + ); this.setState({maskedValue: maskedValue}); this.props.onChange(maskedValue); }, diff --git a/src/mask.js b/src/mask.js index 80c9736..c1f8084 100644 --- a/src/mask.js +++ b/src/mask.js @@ -1,5 +1,5 @@ -export default function mask(value, precision, decimalSeparator, thousandSeparator, allowNegative){ +export default function mask(value, precision, decimalSeparator, thousandSeparator, allowNegative, prefix, suffix){ // provide some default values and arg validation. if (decimalSeparator === undefined){decimalSeparator = ".";} // default to '.' as decimal separator if (thousandSeparator === undefined){thousandSeparator = ",";} // default to ',' as thousand separator @@ -7,6 +7,8 @@ export default function mask(value, precision, decimalSeparator, thousandSeparat if (precision === undefined){precision = 2;} // by default, 2 decimal places if (precision < 0) {precision = 0;} // precision cannot be negative. if (precision > 20) {precision = 20;} // precision cannot greater than 20 + if (prefix === undefined){prefix = '';} // default prefix to empty string + if (suffix === undefined){suffix = '';} // default suffix to empty string let numberIsNegative = false; if (allowNegative) { @@ -67,5 +69,10 @@ export default function mask(value, precision, decimalSeparator, thousandSeparat digits.unshift('-'); } - return digits.join(''); + // if we have a prefix or suffix, add them in. + if (prefix.length > 0){digits.unshift(prefix);} + if (suffix.length > 0){digits.push(suffix);} + + + return digits.join('').trim(); } diff --git a/test/index.spec.js b/test/index.spec.js index 9acda94..8fead0f 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -170,4 +170,42 @@ describe('react-currency-input', function(){ }); + describe('currency prefix', function() { + + before('render and locate element', function () { + this.renderedComponent = ReactTestUtils.renderIntoDocument( + + ); + + this.inputComponent = ReactTestUtils.findRenderedDOMComponentWithTag( + this.renderedComponent, + 'input' + ); + }); + + it('should render the prefix', function() { + expect(this.renderedComponent.getMaskedValue()).to.equal('$0.00'); + }); + + }); + + describe('currency suffix', function() { + + before('render and locate element', function () { + this.renderedComponent = ReactTestUtils.renderIntoDocument( + + ); + + this.inputComponent = ReactTestUtils.findRenderedDOMComponentWithTag( + this.renderedComponent, + 'input' + ); + }); + + it('should render the suffix', function() { + expect(this.renderedComponent.getMaskedValue()).to.equal('0.00 kr'); + }); + + }); + }); diff --git a/test/mask.spec.js b/test/mask.spec.js index 2e49169..f6c8293 100644 --- a/test/mask.spec.js +++ b/test/mask.spec.js @@ -5,7 +5,7 @@ import mask from '../src/mask' describe('mask', function(){ - it('should change "0" to "$0.00"', function(){ + it('should change "0" to "0.00"', function(){ expect(mask("0")).to.equal("0.00"); }); @@ -119,4 +119,32 @@ describe('mask', function(){ + describe('with currency symbol', function(){ + + it('"$" prefix should change "0" to "$0.00"', function(){ + expect(mask("0","2",".",",",true,"$","")).to.equal("$0.00"); + }); + + it('"kr" suffix should change "0" to "0.00kr"', function(){ + expect(mask("0","2",".",",",true,"","kr")).to.equal("0.00kr"); + }); + + it('can have both a prefix and a suffix', function(){ + expect(mask("0","2",".",",",true,"$","kr")).to.equal("$0.00kr"); + }); + + it('does not strip whitespaces between amount and symbol', function(){ + expect(mask("0","2",".",",",true,"$ ","")).to.equal("$ 0.00"); + expect(mask("0","2",".",",",true,""," kr")).to.equal("0.00 kr"); + }); + + it('strips whitespaces before and after value', function(){ + expect(mask("0","2",".",",",true," $ ","")).to.equal("$ 0.00"); + expect(mask("0","2",".",",",true,""," kr ")).to.equal("0.00 kr"); + }); + + }); + + + });