Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

masked method work incorrectly with unmasked results #249

Open
le0pard opened this issue Nov 27, 2024 · 9 comments
Open

masked method work incorrectly with unmasked results #249

le0pard opened this issue Nov 27, 2024 · 9 comments

Comments

@le0pard
Copy link
Contributor

le0pard commented Nov 27, 2024

Describe the bug

All inputs have activated number mask with local pt-BR. Last input calculate sum for all other inputs and have mask too:

const mask = new Mask({ number: { locale: 'pt-BR', fraction: 2 } })
const totalAmount = Array.rom(document.querySelectorAll('.inputs')).reduce((agg, target) => {
  const value = target.value ? parseFloat(mask.unmasked(target.value.toString())) : 0

  return agg + (isNaN(value) ? 0 : value)
}, 0)
document.querySelector('.totalInput').value = totalAmount.toString()
document.querySelector('.totalInput').dispatchEvent(new Event('input', { bubbles: true })) // trigger mask.js

This lead that number incorrectly masked in total field. Instead of 10.34 it get 1034. So this mean:

mask.masked(mask.unmasked('10.234,54')) !== '10.234,54'

Steps to reproduce

const { Mask } = Maska;

const mask = new Mask({ number: { locale: 'pt-BR', fraction: 2 } })
console.log('correct', mask.unmasked('10.234,54')) // correct 10234.54
console.log('incorrect', mask.masked('10234.54')) // incorrect 1.023.454 (should be "10.234,54")
console.log('incorrect', mask.masked(mask.unmasked('10.234,54')), '!==', '10.234,54')

Reproduction link

Example

@rozsazoltan
Copy link

rozsazoltan commented Nov 27, 2024

#225 - If I understand correctly, in both cases, the masked handles the float attribute value as an integer: what is incorrectly or not expected.

@le0pard
Copy link
Contributor Author

le0pard commented Nov 27, 2024

question here: should mask.masked(mask.unmasked(a)) === a or we should expect non deterministic results?

@rozsazoltan - it is number (float), not integers. and it lost fraction

@le0pard
Copy link
Contributor Author

le0pard commented Nov 27, 2024

I think problem, that for mask.masked it should not expect value in opts.locale, but in locale, which it did mask.unmasked, which looks like en

@beholdr
Copy link
Owner

beholdr commented Nov 27, 2024

Yes, it's a known issue with some locales. You can pass initially formatted value as a workaround:

mask.masked(Intl.NumberFormat({ locale: 'pt-BR' }).format(10234.54)) // = 10.234,54

@le0pard
Copy link
Contributor Author

le0pard commented Nov 27, 2024

Yes, but why mask.masked(mask.unmasked(a)) === a non deterministic? If you return unmasked in locale, which you not expect to handle in masked, this mean logic is incorrect.

@le0pard
Copy link
Contributor Author

le0pard commented Dec 3, 2024

const mask = new Mask({ number: { locale: 'pt-BR', fraction: 2 } })

Intl.NumberFormat('pt-BR').format(10234.54) // 10.234,54
mask.masked('10.234,54') // 10.234,54 - same, just waste cpu time

as I understand, expectation:

const number = 10223.34
const numberAsStr = number.toString() // '10223.34'
mask.masked('10223.34') // should return '10.223,34', but not working
mask.unmasked('10.223,34') // should return '10223.34', so parseFloat('10223.34') => 10223.34

and this is not happening now

@beholdr
Copy link
Owner

beholdr commented Dec 5, 2024

Yeah, it’s currently not working with locales that have dot as separator. 10223.34 is not the same as 10.234,54 that’s why I suggest to pass value pre-formatted with Intl.NumberFormat.format()

If you have a universal solution for parsing all locales, PR are welcome.

@le0pard
Copy link
Contributor Author

le0pard commented Dec 5, 2024

@beholdr I think stuff like "parsing" and "formating" need to be split, so parsing can work with normal numbers (not only based on locale), while "formating" do format based requested locale

@beholdr
Copy link
Owner

beholdr commented Dec 6, 2024

@le0pard I agree with that, but it’s more complicated. Problem is not to parse a correctly formatted number like 10.234,56. Problem is to parse a partially formatted number, like you have 10.234,56 and then press a backspace and get 10.234,5 which you should parse to correct float. I just couldn't solve this case at the time.

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

No branches or pull requests

3 participants