Giter VIP home page Giter VIP logo

react-currency-input's Introduction

react-currency-input

An ES2015 react component for currency. Supports custom decimal and thousand separators as well as precision.

Build Status

Changes

v1.3.0:

  • Deprecated "onChange" option in favor of "onChangeEvent". This fixes the argument order to better match React's default input handling
  • Updated dependencies to React 15
  • Added parseFloat polyfill
  • Persist events to deal with an issue of event pooling
  • Other bug fixes.

Installation

npm install react-currency-input --save

Integration

You can store the value passed in to the change handler in your state.

import React from 'react'
import CurrencyInput from 'react-currency-input';

const MyApp = React.createClass({
    getInitialState(){
        return ({amount: "0.00"});
    },

    handleChange(event, maskedvalue, floatvalue){
        this.setState({amount: maskedvalue});
    },
    render() {
        return (
            <div>
                <CurrencyInput value={this.state.amount} onChangeEvent={this.handleChange}/>
            </div>
        );
    }
});
export default MyApp

You can also assign a reference then access the value using a call to getMaskedValue().

import React from 'react'
import CurrencyInput from 'react-currency-input';

const MyApp = React.createClass({
    handleSubmit(event){
        event.preventDefault();
        console.log(this.refs.myinput.getMaskedValue())
    },
    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <CurrencyInput ref="myinput" />
            </form>
        );
    }
});
export default MyApp

Separators and Precision

Specify custom decimal and thousand separators:

    // 1.234.567,89
    <CurrencyInput decimalSeparator="," thousandSeparator="." />

Specify a specific precision:

    // 123,456.789
    <CurrencyInput precision="3" />
    // 123,456,789
    <CurrencyInput precision="0" />

Currency

Optionally set a currency symbol as a prefix or suffix

    // $1,234,567.89
    <CurrencyInput prefix="$" />
    // 1,234,567.89 kr
    <CurrencyInput suffix=" kr" />

Negative signs come before the prefix

    // -$20.00
    <CurrencyInput prefix="$" value="-20.00" />

All other attributes are applied to the input element. For example, you can integrate bootstrap styling:

    <CurrencyInput className="form-control" />

Options

Option Default Value Description
value 0 The initial currency value
onChange n/a Callback function to handle value changes. Deprecated, use onChangeEvent.
onChangeEvent n/a Callback function to handle value changes
precision 2 Number of digits after the decimal separator
decimalSeparator '.' The decimal separator
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
allowEmpty false If no value is given, defines if it starts as null (true) or '' (false)
selectAllOnFocus false Selects all text on focus or does not
prefix '' Currency prefix
suffix '' Currency suffix
autoFocus false Autofocus

*Note: Enabling any mask-related features such as prefix, suffix or separators with an inputType="number" or "tel" could trigger errors. Most of those characters would be invalid in such input types.

react-currency-input's People

Contributors

aesopwolf avatar becousae avatar darostreet avatar gektorgrom avatar igorsantos07 avatar jsharpe avatar jsillitoe avatar malbernaz avatar panupan avatar sevos avatar slavakisel avatar tncalvert avatar viniciusdacal avatar zhuangya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

react-currency-input's Issues

Value is restarting after the fourth digit

This behavior is happening:

jul-03-2017 14-23-25

<Currency
  ref={currency => { this.currency = currency }}
  className={currencyClass}
  precision={2}
  decimalSeparator=","
  value={this.state.value}
  thousandSeparator="."
  prefix="R$ "
  onChange={this.handleValue}
/>

Troubleshooting helper -> console log from react-currency-input/lib/index.js:231
version -> 1.2.6
Google Chrome -> Version 59.0.3071.115 (Official Build) (64-bit)

Does Not Work with Safari

If you have multiple inputs, the last one is focused and will not unfocus on Safari (both mobile and web)

Tried many different things, but unable to get anything to work. Any suggestions?

negative values input order... enter - before value

When entering negative values I would say user exspectation is that you first enter - and then the number. This seems not to be possible right now or I'm missing something. You first have to enter a number and after that you can add the -

Component isn't compatible with React 16

I've been searching for a good currency input for React and that's the best I've found in a while. I started using it at some projects and had a great experience, but I couldn't use it recently since that specific project is using React 16.

Is there any interest of the community to do so? What would be needed? I could help if there is demand :)

inputType=number is troublesome with any mask

If the developer enables any mask-related feature - such as prefix, suffix or separators - an input type=number or tel would trigger errors, because most of those characters would be invalid in such input types.

If that option is really to be used, at least disclose in the documentation/README that it should not be used together with mask-related attributes.

screenshot_010

how to trigger focus() on <CurrencyInput />

I would like to trigger the focus() event on the when a button is pressed. However, I'm not sure how to do so.

When I use ref={el => this.input = el}, I don't get access to the component.

Can we expose a way to add a ref to the component so that we can call focus() and other triggers? Thank you.

input component on IE10 fails with parseFloat function

in code line 89, file src/index.js

initialValue = Number.parseFloat(initialValue);

running on IE10, throw next error

react
react2

this, doesn't happen on chrome, firefox, edge.

this was solved, change this line to

initialValue = initialValue * 1;

Usage with redux-forms

I'm trying to use this component with redux-forms. I've gotten the following snippet below.

<Field name="rate" type="text" id="Rate"
           component={props => (
                <CurrencyInput  
                    prefix="$" 
                    precision="0" 
                    thousandSeparator="," 
                     value={ props.input.value } 
                     onChange={ props.input.onChange } />)} />

This does seem to render the input text correctly and even renders the initial values passed to it correctly. But on saving the form the value sent to the backend includes all the formatting(i.e. the masked value). What is the preferred way to use this with redux-forms. Perhaps an example of the same would be helpful.

Do i need to update the form onSubmit to use the actual value and not the masked value?

See Redux Form - Custom Component

IE 11 issue

When using component in IE 11 app can't be loaded.

I am getting following error message:

screen shot 2017-02-10 at 4 12 07 pm

Typing jumps around

Typing in the input field seems to alternate as I type between the front and the end of the input.

If I type "123456789" into a box with a value of "$0" in it without moving my cursor or hitting any other buttons, the displayed value is "$9,876,543,102".

If I delete the value completely and then type the same string I get "$987,654,213" (entering into a completely empty input box).

Obviously I have a prefix of '$' and a precision of '0' in this example. The issue arises even without either of those though.

Component is essentially unusable in this state.

Add `tabindex`

We have a SPA with multipage inputs (one on each page). Lack of tabindex="-1" resulted in users being able to go between pages in mobile safari without any other interactions besides tabbing along.

tabindex attribute would be a nice to have : )

Thank you!

React.createClass becoming deprecated

CurrencyInput: React.createClass is deprecated and will be removed in version 16. Use plain JavaScript classes instead. If you're not yet ready to migrate, create-react-class is available on npm as a drop-in replacement.

I also get this (though I'm not sure if that's the same):
Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.

Return negative number as raw value when numberIsNegative

The raw value passed to onChange(masked, raw, event) ignores negative values.

onChange={(masked, raw) => {
    console.log('allowNegative: ', allowNegative);
    console.log('masked: ', masked);
    console.log('raw: ', raw);
}}

image

Shouldn't we return the negative raw value instead?

Add prop to disable selecting all text in field on focus

In case if user wants to add digit to input, he has to click twice on it, because first click(focus) selects whole text, which is not really UX-good.

The solution (line 213, handleFocus function):

this.props.selectAllOnFocus && event.target.setSelectionRange(selectionStart, selectionEnd);

Uncaught TypeError: this.updater.enqueueCallback is not a function at CurrencyInput

My implementation is below:

App.js

...
    const numberOpts = {
      style: 'currency',
      currency: 'BRL',
      thousandSeparator: '.',
      decimalSeparator: ',',
      digits: 2,
      prefix: '$',
      sufix: null,
    }

MyComponent.js

handleChangePrice(event, maskedValue, floatValue) {
    event.preventDefault()

    console.log('handle change price: ', maskedValue, floatValue)
}

<CurrencyInput
  className='form-control'
  ref='price'
  onChangeEvent={this.handleChangePrice}
  value={srv.price}
  thousandSeparator={this.props.numberOpts.thousandSeparator}
  decimalSeparator={this.props.numberOpts.decimalSeparator}
  precision={this.props.numberOpts.digits}
  prefix={this.props.numberOpts.prefix}
  sufix={this.props.numberOpts.sufix}
  />

and the output was:

Uncaught TypeError: this.updater.enqueueCallback is not a function
    at CurrencyInput../node_modules/react-currency-input/node_modules/react/lib/ReactBaseClasses.js.ReactComponent.setState (http://localhost:3000/static/js/bundle.js:53711:18)
    at CurrencyInput.handleChange (http://localhost:3000/static/js/bundle.js:36004:18)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:60275:14)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:60314:16)
    at Object.invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:60171:27)
    at Object.invokeGuardedCallbackAndCatchFirstError (http://localhost:3000/static/js/bundle.js:60185:43)

What's happening?

Trouble with Synthetic Events

For no apparent (?) reason I started seeing warnings/errors in my console referring to this doc page: Event Pooling. That happened because I was using e.target.name to define which property of my object I should update, but it started to fail. I work-arounded that using a function that returns a function, scoping the field name instead of relying in the target name (like onChange: name => (masked, value, e) => [...])

It seems that the inner implementation should call event.persist() somewhere, before passing it down to the handler we specify :)

Function custom props don't get applied to input

I use this component with an onKeyUp event to trigger an API request. This used to work, but it stopped after this commit: 94e30dd.
This happens because JSON.stringify cannot serialize functions.
I understand this was a patch to support older environments, but is also broken for other keyboard events.
I see that in one of the last versions you had added the Object.assign polyfill. In my opinion, this is a better solution to the problem.
You could also have used the spread operator.

let customProps = {...props};

It is also an ES6 feature, but I supposed it is ok to use it here since it is already being used in master.
Anyway, I've downgraded to a previous version to fix my website for now, but I'll be happy to help if you wanna discuss a solution.

Thanks

React and it's packages are installed as normal dependencies rather then peer.

How to reproduce:

# download the package
yarn add react-currency-input

# list it's dependencies
cat node_modules/react-currency-input/package.json | jq '.dependencies'

# output:
{
  "react": "^15.5.0",
  "react-dom": "^15.5.0",
  "prop-types": "^15.5.0"
}

There are two problems here:

  • the first is that React and it's packages (react-dom and prop-types) should be installed as peer dependencies rather than normal ones. I'm having a problem in which a project I'm working on have two conflicting versions of react.
  • the second one is that at the current time the npm package is not in sync with this repo - which is what actually made me realize about this issue. I'm getting this error:
Uncaught TypeError: this.updater.enqueueCallback is not a function
  at CurrencyInput../node_modules/react-currency-input/node_modules/react/lib/ReactBaseClasses.js.ReactComponent.setState

which is explained in this thread.

I'll be happy to submit a PR in the case you are too busy too make these changes.

Thank you very much for this awesome project, it's been a life saver!

Starts input with no value

It is possible to show the value only when user starts to change the value, even when the value didnt change the value is starting with 00,00.

Thats what I would like to achieve
image

And that is what happens
image

Weird cursor behavior on Android Chrome with most common keyboards

When testing my app on (real) mobile phones I noticed the cursor jumps somewhere in the beginning of the string when there are few digits to be formatted.
I saw this in two Android 6.0.1 devices (Sony Z3 Compact, Nexus 5), both running Chrome 57.
On the Sony it happens with SwiftKey and the Xperia Keyboard (default one), but not with the Hacker's Keyboard. On the Nexus the same behavior happened (with the default GBoard in place of Xperia Keyboard).

Example:

<CurrencyInput prefix="R$ " precision={2} allowNegative={false} alowEmpty decimalSeparator="," thousandSeparator="."/>
  1. Initial display: empty
  2. Type in: 1234
  3. Final display: R$ 4.320,01

20170422_021650

Big size

Hi , it seems that it adds about 600KB to bundle , is it by purpose?

onChange event does not work.

Anyone face this problem, with simple code as present at Readme onChangeEvent does not trigger
onChange event?

handleChange = (event, value, maskedValue) => {
this.setState({ amount: value })
}

render() {
const { amount } = this.state

return (
  <CurrencyInput value={amount} onChange={this.handleChange} />
)

}
`

Non-standard conversion from given value into displayed value

If a string (or a number, when it works (#6)) is given as value with not enough decimals when a said precision is needed, some integers are turned into decimals.

Example: <CurrencyInput value="6300" precision="2"/> yields a field like [63.00] instead of [6300.00].

An easy way to avoid that when receiving numbers is as follows, but string values would require manual work:

    if (typeof value == 'number') {
      value = Number(value).toLocaleString(undefined, {
            style                : 'decimal',
            minimumFractionDigits: precision,
            maximumFractionDigits: precision
      })
    }

1.3.2 infinite loop of "handleFocus" on mobile safari, crashes browser

Hey, sorry I don't have more details but had to rollback to from 1.3.2 to 1.2.6 this morning (last known working version). 1.3.2 was causing an infinite loop somewhere in the "handleFocus" function, but only on iphones. It might have been when unfocusing (blurring) the input but I didn't check exactly.

Getting error message when using number input

I am getting the following error when trying to use a numeric input.

Uncaught DOMException: Failed to execute 'setSelectionRange' on 'HTMLInputElement': The input element's type ('number') does not support selection.

My component call looks like this:

<CurrencyInput
  name="customerAllocationMicros"
  allowNegative
  value={(line.customerAllocationMicros / 1000)}
  onChangeEvent={this.updateAllocationLine(index)}
  disabled={disableControls}
/>

line is part of an array in my state, and updateAllocationLine takes the index to that array and returns a function that will update the correct array member via setState.

Any ideas?

How to right-align cursor on focus

I have an Input that is rendering with autoFocus=true. I would like the cursor to appear to the right of the value 0, but instead it appears at the left. This means that when a user inputs a 1, the value becomes 10 instead of 1. If the cursor could be positioned to the right of the initial 0, this could be avoided.

Any suggestions? Thank you.

raw value

First of all, thank you for this component.
I would like to know if there is a way to get the raw value, as a float number, as in the example:
"$ 1.30" => 1.30

Maybe we could receive this value as the second parameter in the onChange callback function.

React native compatibility?

try to install it and use it in react native but it give me this error

Error: Unable to resolve module 'react-dom'

Unable to edit input when prefix is added

when you specify prefix for example "$", CurrencyInput not working and onChange action give you always last 1 character and if you didn't use prefix field at all, CurrencyInput working normal
I use react and react-dom "^15.4.2",

Material-UI + CurrencyInput

Hi!
I am facing a problem when using currency input with material-ui lib.
Have a look at the code:

captura de tela 2017-08-30 as 16 28 24

Below this part I have others fields in the form.
However, I am not able to fill any other element in the form because the focus always go back to the <CurrencyInput> input.

Am I missing something?

Tks

value is not a controlled input ?

currently I would like to have a maximum value for my input. As currently we don't support max and min, the work around is to prevent the value to be changed in setState if value > maximumValue.

But, the displayed value is still changed Although the value in state is not changed.

Problem with handleFocus

We're a facing a problem when the component is mounting and it triggers autofocus, on file lib/index.js:210

var selectionEnd = this.theInput.value.length - this.props.suffix.length;

It's causing the following error:

Uncaught TypeError: Cannot read property 'value' of undefined
    at CurrencyInput.handleFocus (***)

Backspace is troublesome with suffixes

  1. add a field with a suffix
  2. focus it and type away. All good.
  3. go to the next field or whatnot
  4. get back to it, click the end of the input, and try to backspace it
  5. ๐Ÿ’ฅ you can't backspace because the suffix is unremovable. It should, actually, backspace the last digit on the mask.

digits larger than 16

This is a pretty nice project that you have but I noticed that if you enter more than 16 digits it starts to act extremely weird. I.e. if you do it with the prefix '$' and the value of 12345678901234.56 and then go to add a 7 the number instead is now 123456789012346.00. The behavior is odd.

Focus in Safari

Using version 1.3.6 with React 16.3.2 in Safari, the field starts autofocused. I need it to follow the tabIndex as well, but everytime I type it tries to focus back in the CurrencyInput component.

Any thoughts?

Negative value do not work for some locale

Hi,

I have a problem where the state is not calculated correct for negative values

image

I have found that it is the following code in index.js that is the problem

initialValue = Number(initialValue).toLocaleString(undefined, {
                style                : 'decimal',
                minimumFractionDigits: props.precision,
                maximumFractionDigits: props.precision
            })

The minus sign is change to "โˆ’" (โ€Ž2212 MINUS SIGN) instead of "-" (โ€Ž002D HYPHEN-MINUS)

This result in that the logic for the following line fails

let negativeSignCount = (value.match(/-/g) || []).length;

Because it is looking for "-" (โ€Ž002D HYPHEN-MINUS), and in my case where the char is "โˆ’" (โ€Ž2212 MINUS SIGN) negativeSignCount equals 0, instead of 1

The solution should be to change:

initialValue = Number(initialValue).toLocaleString(undefined, {
                style                : 'decimal',
                minimumFractionDigits: props.precision,
                maximumFractionDigits: props.precision
            })

to

initialValue = Number(initialValue).toFixed(props.precision);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.