diff --git a/src/CONST.js b/src/CONST.js index 96fe7084239e..3ec93906cc96 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -680,7 +680,6 @@ const CONST = { CARD_SECURITY_CODE: /^[0-9]{3,4}$/, CARD_EXPIRATION_DATE: /^(0[1-9]|1[0-2])([^0-9])?([0-9]{4}|([0-9]{2}))$/, PAYPAL_ME_USERNAME: /^[a-zA-Z0-9]+$/, - RATE_VALUE: /^\d{1,8}(\.\d*)?$/, // Adapted from: https://gist.github.com/dperini/729294 // eslint-disable-next-line max-len diff --git a/src/components/BigNumberPad.js b/src/components/BigNumberPad.js index 2e8082a963d7..61a7a159e9ee 100644 --- a/src/components/BigNumberPad.js +++ b/src/components/BigNumberPad.js @@ -63,7 +63,7 @@ class BigNumberPad extends React.Component { style={[styles.flex1, marginLeft]} text={column === '<' ? column : this.props.toLocaleDigit(column)} onLongPress={() => this.handleLongPress(column)} - onPress={() => this.props.numberPressed(column)} + onPress={() => this.props.numberPressed(column === '<' ? column : this.props.toLocaleDigit(column))} onPressIn={ControlSelection.block} onPressOut={() => { clearInterval(this.state.timer); diff --git a/src/pages/iou/steps/IOUAmountPage.js b/src/pages/iou/steps/IOUAmountPage.js index 8d2bc5d00783..84ee153942de 100755 --- a/src/pages/iou/steps/IOUAmountPage.js +++ b/src/pages/iou/steps/IOUAmountPage.js @@ -6,7 +6,6 @@ import { import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; -import _ from 'underscore'; import ONYXKEYS from '../../../ONYXKEYS'; import styles from '../../../styles/styles'; import BigNumberPad from '../../../components/BigNumberPad'; @@ -59,12 +58,11 @@ class IOUAmountPage extends React.Component { this.updateAmountNumberPad = this.updateAmountNumberPad.bind(this); this.updateAmount = this.updateAmount.bind(this); - this.stripCommaFromAmount = this.stripCommaFromAmount.bind(this); this.focusTextInput = this.focusTextInput.bind(this); this.navigateToCurrencySelectionPage = this.navigateToCurrencySelectionPage.bind(this); this.state = { - amount: props.selectedAmount, + amount: props.selectedAmount.replace('.', this.props.fromLocaleDigit('.')), }; } @@ -119,20 +117,11 @@ class IOUAmountPage extends React.Component { * @returns {Boolean} */ validateAmount(amount) { - const decimalNumberRegex = new RegExp(/^\d+(,\d+)*(\.\d{0,2})?$/, 'i'); + const decimalSeparator = this.props.fromLocaleDigit('.'); + const decimalNumberRegex = RegExp(String.raw`^\d+([${decimalSeparator}]\d{0,2})?$`, 'i'); return amount === '' || (decimalNumberRegex.test(amount) && this.calculateAmountLength(amount) <= CONST.IOU.AMOUNT_MAX_LENGTH); } - /** - * Strip comma from the amount - * - * @param {String} amount - * @returns {String} - */ - stripCommaFromAmount(amount) { - return amount.replace(/,/g, ''); - } - /** * Update amount with number or Backspace pressed for BigNumberPad. * Validate new amount with decimal number regex up to 6 digits and 2 decimal digit to enable Next button @@ -152,7 +141,7 @@ class IOUAmountPage extends React.Component { this.setState((prevState) => { const amount = `${prevState.amount}${key}`; - return this.validateAmount(amount) ? {amount: this.stripCommaFromAmount(amount)} : prevState; + return this.validateAmount(amount) ? {amount} : prevState; }); } @@ -160,36 +149,10 @@ class IOUAmountPage extends React.Component { * Update amount on amount change * Validate new amount with decimal number regex up to 6 digits and 2 decimal digit * - * @param {String} text - Changed text from user input - */ - updateAmount(text) { - this.setState((prevState) => { - const amount = this.replaceAllDigits(text, this.props.fromLocaleDigit); - return this.validateAmount(amount) - ? {amount: this.stripCommaFromAmount(amount)} - : prevState; - }); - } - - /** - * Replaces each character by calling `convertFn`. If `convertFn` throws an error, then - * the original character will be preserved. - * - * @param {String} text - * @param {Function} convertFn - `this.props.fromLocaleDigit` or `this.props.toLocaleDigit` - * @returns {String} + * @param {String} amount - Changed amount from user input */ - replaceAllDigits(text, convertFn) { - return _.chain([...text]) - .map((char) => { - try { - return convertFn(char); - } catch { - return char; - } - }) - .join('') - .value(); + updateAmount(amount) { + this.setState(prevState => (this.validateAmount(amount) ? {amount} : prevState)); } navigateToCurrencySelectionPage() { @@ -203,8 +166,6 @@ class IOUAmountPage extends React.Component { } render() { - const formattedAmount = this.replaceAllDigits(this.state.amount, this.props.toLocaleDigit); - return ( <> this.props.onStepComplete(this.state.amount)} + onPress={() => this.props.onStepComplete(this.state.amount.replace(this.props.fromLocaleDigit('.'), '.'))} pressOnEnter isDisabled={!this.state.amount.length || parseFloat(this.state.amount) < 0.01} text={this.props.translate('common.next')} diff --git a/src/pages/workspace/reimburse/WorkspaceReimburseView.js b/src/pages/workspace/reimburse/WorkspaceReimburseView.js index 9ae0b280e24f..d01190a221c9 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimburseView.js +++ b/src/pages/workspace/reimburse/WorkspaceReimburseView.js @@ -77,16 +77,13 @@ class WorkspaceReimburseView extends React.Component { } getRateDisplayValue(value) { - const numValue = parseFloat(value); - if (Number.isNaN(numValue)) { - return ''; - } - - return numValue.toFixed(3); + return value.toString().replace('.', this.props.fromLocaleDigit('.')); } setRate(value) { - const isInvalidRateValue = value !== '' && !CONST.REGEX.RATE_VALUE.test(value); + const decimalSeparator = this.props.fromLocaleDigit('.'); + const rateValueRegex = RegExp(String.raw`^\d{1,8}([${decimalSeparator}]\d{0,3})?$`, 'i'); + const isInvalidRateValue = value !== '' && !rateValueRegex.test(value); this.setState(prevState => ({ rateValue: !isInvalidRateValue ? value : prevState.rateValue, @@ -115,16 +112,12 @@ class WorkspaceReimburseView extends React.Component { } updateRateValue(value) { - const numValue = parseFloat(value); + const numValue = parseFloat(value.replace(this.props.fromLocaleDigit('.'), '.')); if (_.isNaN(numValue)) { return; } - this.setState({ - rateValue: numValue.toFixed(3), - }); - Policy.setCustomUnitRate(this.props.policyID, this.state.unitID, { customUnitRateID: this.state.rateID, name: this.state.rateName,