Skip to content

Commit

Permalink
Merge pull request #9800 from eVoloshchak/eVoloshchak_localizeDecimal…
Browse files Browse the repository at this point in the history
…Separator

Localize decimal separator
  • Loading branch information
sketchydroide authored Jul 19, 2022
2 parents 5272c49 + bcf54e6 commit 7541b77
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 62 deletions.
1 change: 0 additions & 1 deletion src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/components/BigNumberPad.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
57 changes: 9 additions & 48 deletions src/pages/iou/steps/IOUAmountPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -53,12 +52,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('.')),
};
}

Expand Down Expand Up @@ -113,20 +111,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
Expand All @@ -146,44 +135,18 @@ 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;
});
}

/**
* 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() {
Expand All @@ -197,8 +160,6 @@ class IOUAmountPage extends React.Component {
}

render() {
const formattedAmount = this.replaceAllDigits(this.state.amount, this.props.toLocaleDigit);

return (
<>
<View style={[
Expand All @@ -210,7 +171,7 @@ class IOUAmountPage extends React.Component {
]}
>
<TextInputWithCurrencySymbol
formattedAmount={formattedAmount}
formattedAmount={this.state.amount}
onChangeAmount={this.updateAmount}
onCurrencyButtonPress={this.navigateToCurrencySelectionPage}
placeholder={this.props.numberFormat(0)}
Expand All @@ -230,7 +191,7 @@ class IOUAmountPage extends React.Component {
<Button
success
style={[styles.w100, styles.mt5]}
onPress={() => 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')}
Expand Down
17 changes: 5 additions & 12 deletions src/pages/workspace/reimburse/WorkspaceReimburseView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 7541b77

Please sign in to comment.