Skip to content
This repository has been archived by the owner on Aug 17, 2023. It is now read-only.

How to make a currency mask #63

Open
lpepinelli opened this issue Oct 25, 2022 · 7 comments
Open

How to make a currency mask #63

lpepinelli opened this issue Oct 25, 2022 · 7 comments

Comments

@lpepinelli
Copy link

  • I'm submitting a ...
    [    ] bug report
    [    ] feature request
    [    ] question about the decisions made in the repository
    [ x ] question about how to use this project

  • Summary
    I'm trying to make a simple number mask to currency values.

<Space direction="vertical">
  <label>Entrada</label>
    <MaskedInput
      autoComplete="off"
      placeholder = "Entrada"
      mask={
        React.useMemo<MaskType>(() => [
          {
            mask: 'R$ num',
            lazy: true,
            blocks: {
              num: {
                mask: Number,
                thousandsSeparator: '.',
                padFractionalZeros: true
              }
            }
          }
        ], [])
      }
    />
</Space>

Video_1666694324

But that way only one digit appears and throws this warning on the console. What am I doing wrong?

  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)

I am following this documentation: https://imask.js.org/

image

Thanks!

@augustosnk12
Copy link

@lpepinelli did you find any solution?

@lpepinelli
Copy link
Author

Not with this library, not yet. But I found an alternative with typescript, regex and antd input component.

export const currencyMask = (value: string) => {
  let valueFormatted = value
  valueFormatted = valueFormatted.replace(/\D/g, '')
  valueFormatted = valueFormatted.replace(/(\d)(\d{2})$/, '$1,$2')
  valueFormatted = valueFormatted.replace(/(?=(\d{3})+(\D))\B/g, '.')
  return {
    maskedValue: valueFormatted,
    unmaskedValue: Number(valueFormatted.replace('.', '').replace(',', '.'))
  }
}
<Input
  prefix='R$'
  placeholder="Entrada"
  autoComplete='off'
  value={entradaInput}
  onChange={({ target }) => handleEntradaChange(target.value)} />
const handleEntradaChange = (value: string) => {
  setEntradaInput(currencyMask(value).maskedValue)
  const unmaskedValue = currencyMask(value).unmaskedValue
  console.log(unmaskedValue)
}

Video_1668014644

@antoniopresto
Copy link
Owner

You must use useMeme in the component body

@renerlemes
Copy link

renerlemes commented Apr 11, 2023

@antoniopresto how to use the example that working of @lpepinelli with useMemo?

@renerlemes
Copy link

@lpepinelli How would this function look like when I type 1, it starts formatting from right to left, that is, it would look like this: 0.01. When I typed 15 it would format to 0.15?

@lpepinelli
Copy link
Author

Hi @renerlemes

If you add a "padStart" to the function you will have the behavior that you want.

export const currencyMask = (value: string) => {
  let valueFormatted = value
  valueFormatted = valueFormatted.replace(/\D/g, '')

  // Add a leading zero for numbers with one or two digits
  valueFormatted = valueFormatted.padStart(3, '0')

  valueFormatted = valueFormatted.replace(/(\d{1})(\d{2})$/, '$1,$2')
  valueFormatted = valueFormatted.replace(/(?=(\d{3})+(\D))\B/g, '.')

  return {
    maskedValue: valueFormatted,
    unmaskedValue: Number(valueFormatted.replace('.', '').replace(',', '.'))
  }
}

I don't have my project working here to test, but I think it will work.

image

@renerlemes
Copy link

renerlemes commented Apr 11, 2023

@lpepinelli the code you suggested did not work. See the image below. But I made a small change and it worked.

export const currencyMask = (value: string) => {

let valueFormatted = value;

valueFormatted = valueFormatted.replace(/\D/g, "");

valueFormatted = valueFormatted.padStart(3, "0");

valueFormatted = valueFormatted.replace(/(\d{1})(\d{2})$/, "$1,$2");
valueFormatted = valueFormatted.replace(/(?=(\d{3})+(\D))\B/g, ".");

let beforeComma = valueFormatted.split(",")[0];

if (beforeComma === "00" || (beforeComma.length === 2 && beforeComma[0] === "0" && beforeComma[1] !== "0")) {
	valueFormatted = valueFormatted.slice(1);
}

return {
    maskedValue: valueFormatted,
    unmaskedValue: Number(valueFormatted.replace('.', '').replace(',', '.'))
}

image

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants