regex InputNumber formatter ant-design

All we need is an easy explanation of the problem, so here it is.

Guys I really not understand about regex, I’m using ant-design Input Number component to make a currency filter.

currently this is like this:

 <InputNumber
    style={{ width: 175 }}
    formatter={value => `R$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, 
    ".")}
    parser={value => value.replace(/[A-Z]|[a-z]|[$ ]|\.+/g, "")}
    onChange={(value) => setSelectedKeys(value ? value : [])}
  />

The current format, for exemple thousand five hundred is like this : 1.500
I need it to accept as well, negatives numbers (-1.500) and comma for the cents like 1.500,25

Can you guys help me ? I’ve try some solutions but can’t make it work as I need

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Guys after searching a lot,I found one solution, can’t be the better one, but at moment is doing its job..

I installed MaskedInput and text-mask-addons dependencies.

import MaskedInput from "react-text-mask";
import createNumberMask from "text-mask-addons/dist/createNumberMask";

const defaultMaskOptions = {
    prefix: "R$",
    suffix: "",
    includeThousandsSeparator: true,
    thousandsSeparatorSymbol: ".",
    allowDecimal: true,
    decimalSymbol: ",",
    decimalLimit: 2,
    integerLimit: 7,
    allowNegative: true,
    allowLeadingZeroes: false,
  };
  const currencyMask = createNumberMask(defaultMaskOptions);


const NumberFilter = (
    <Space style={{ marginRight: 20 }}>
      <MaskedInput
        mask={currencyMask}
        render={(ref, props) => (
          <Input
            placeholder="Valor inicial"
            ref={(input) => ref(input && input.input)}
            {...props}
            value={selectedKeys[0]}
            onChange={(event) => {
              props.onChange(event);
              let betweenInitial = [...selectedKeys];
              betweenInitial[0] = event.target.value;
              setSelectedKeys(betweenInitial);
            }}
          />
        )}
      />
      <RiArrowLeftRightLine />
      <MaskedInput
        mask={currencyMask}
        render={(ref, props) => (
          <Input
            placeholder="Valor final"
            ref={(input) => ref(input && input.input)}
            {...props}
            value={selectedKeys[1]}
            onChange={(event) => {
              props.onChange(event);
              let betweenFinal = [...selectedKeys];
              betweenFinal[1] = event.target.value;
              setSelectedKeys(betweenFinal);
            }}
          />
        )}
      />
    </Space>
  );

Method 2

My solution:

// formatter and parser input number
export const formatterNumber = (val) => {
  if (!val) return 0;
  return `${val}`.replace(/\B(?=(\d{3})+(?!\d))/g, ".").replace(/\.(?=\d{0,2}$)/g, ",");
}

export const parserNumber = (val) => {
  if (!val) return 0;
  return Number.parseFloat(val.replace(/\$\s?|(\.*)/g, "").replace(/(\,{1})/g, ".")).toFixed(2)
}

<InputNumber 
  {...props}
  formatter={(value) => formatNumber(value)}
  parser={(value) => parserNumber(value)}
/>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply