Путем проб и ошибок я наконец понял, как работают formatter
и parser
компонента InputNumber
, документации на https://2x.ant.design/components/table/
практически не было. В итоге я сделал следующее, что не совсем красиво, но работает:
<InputNumber
defaultValue={this.props.value !== null ? parseFloat(this.props.value) : null}
// This is what 2x.antd.design suggests to do it:
// formatter={value => ` ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
// parser={value => value.replace(/\$\s?|(,*)/g, "")}
// This my solution for German numbers
formatter={value => ` ${value}`.replace(/\./,',').replace(/\B(?=(\d{3})+(?!\d))/g, '.')}
parser={x => parseFloat(`${x}`.replace(/,/, '#').replace(/\./g, '').replace(/#/,'.')) }
onChange={this.handleChange}
/>
Идея formatter
состоит в том, чтобы сначала заменить десятичный разделитель .
на ,
. replace(/\B(?=(\d{3})+(?!\d))/g, ',')
должен найти глобально все 3-di git группы \d{3}
и заменить любой разделитель тысяч на .
, \B(?=(\d{3})+(?!\d))
найдет все, кроме последнего ,
.
Перед тем, как записывать данные обратно в переменную состояния this.props.value
, мы должны отменить эту замену, поэтому сначала мы заменяем запятую как десятичный разделитель некоторым заполнителем #
, затем удаляем все .
в строке и, наконец, делаем верните заполнитель на .
в качестве десятичного разделителя, который можно понять как parseFloat
.