ngx-mask
ngx-mask copied to clipboard
Currency mask without need to type decimal separator
Hi,
I'm trying to mask a value as brazilian currency. I want a mask which the user don't need to type the decimal separator (in my case, a comma) and the typed number is formatted to BRL currency automatically. For example:
Typed value > Masked value > Control value: 1 > R$ 0,01 > 0.01 10 > R$ 0,10 > 0.10 100 > R$ 1,00 > 1 123456 > R$ 1.234,56 > 1234.56
Actually, the pattern to get the control value according to typed value is a division by 100:
1 : 100 = 0.01 10 : 100 = 0.10 ...
The closest I got was
<input mask="separator.2" [thousandSeparator]="'.'" [decimalMarker]="','" prefix="R$ " />
but user must type the comma to have the decimal part.
Is possible to get this type of mask only with ngx-mask
and without write some extra code?
I've added the code below to the checkInputPrecision
method in the mask-applier.service.ts
file. I got the expected result for this proposed issue. However, the cursor in the input field is not stayed, and it's moved to before the decimal separator.
I've used the "split" method because I don't have extensive knowledge of pattern method.
private checkInputPrecision = (
inputValue: string,
precision: number,
decimalMarker: IConfig['decimalMarker'],
beginByDecimal = false
): string => {
if (precision < Infinity) {
const precisionRegEx = new RegExp(this._charToRegExpExpression(decimalMarker) + `\\d{${precision}}.*$`);
const precisionMatch = inputValue.match(precisionRegEx);
if (beginByDecimal) {
if (!precisionMatch) {
const splited = inputValue.split(decimalMarker);
const decimalLength = splited.length === 2 ? splited[1].length : 0;
const diff = precision - decimalLength;
if (diff > 0) {
const integer = splited[0].length > diff ? splited[0].substring(0, splited[0].length - diff) : '';
const toChange =
splited[0].length > diff ? splited[0].substring(splited[0].length - diff, splited[0].length) : splited[0];
const end = splited.length === 2 ? splited[1] : '';
let decimal = toChange + end;
decimal =
precision - decimal.length > 0
? Array(precision - decimal.length)
.fill(0)
.join('') +
'' +
decimal
: decimal;
inputValue = integer + decimalMarker + decimal;
}
} else {
const splited = inputValue.split(decimalMarker);
const decimalLength = splited.length === 2 ? splited[1].length : 0;
const diff = decimalLength - precision;
if (diff > 0) {
let integer = splited[0];
const toChange = splited[1].substring(0, diff);
const end = splited[1].substring(diff, splited[1].length);
integer = integer + toChange;
inputValue = integer + decimalMarker + end;
}
}
} else {
if (precisionMatch && precisionMatch[0].length - 1 > precision) {
const diff = precisionMatch[0].length - 1 - precision;
inputValue = inputValue.substring(0, inputValue.length - diff);
}
if (precision === 0 && inputValue.endsWith(decimalMarker)) {
inputValue = inputValue.substring(0, inputValue.length - 1);
}
}
}
return inputValue;
};
Pretty sad we have to use another projects just because ngx-mask does not care to solve this high requested problem.
Would be very appreciated feature.