I'm trying to use Directive in my Angular App, inside an input box the user must be able to insert only values with three decimal.
The decimal are separated with comma but there could be a case where the user will use dot as separator and in this case i have to replace the dot with the comma on input.
I was trying the following way to archieve it:
@Directive({
selector: '[appQuantity]',
})
export class QuantityDirective {
@Input()
public plu: Plu;
constructor(private ref: ElementRef) {}
@HostListener('input', ['$event'])
public onInput(event: any): void {
const val = this.ref.nativeElement.value;
this.ref.nativeElement.value = this.ref.nativeElement.value.replace(/\./g, ','); // here i should replace dot with comma but it's not working
if (this.plu.um === 'PZ'){ // controls if input is empty i'm setting 1
if (!val || val <= 0){
this.ref.nativeElement.value = 1;
}
}
this.plu.qta = parseFloat(this.ref.nativeElement.value); // setting the object quantity to inserted value
}
}
But it just return NaN value on parseFloat and just set the input to 1...
As per the docs for parseFloat: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat
Return value
A floating point number parsed from the given string.
Or NaN when the first non-whitespace character cannot be converted to a number.
Parsefloat expects a string 000.00
but because you are replacing the .
with a ,
you are getting NaN.
I would recommending parsing the number first then converting to your output and only setting once you are happy with the value rather than resetting the same value a few times.
@Directive({
selector: '[appQuantity]',
})
export class QuantityDirective {
@Input()
public plu: Plu;
constructor(private ref: ElementRef) {}
@HostListener('input', ['$event'])
public onInput(event: any): void {
// Use `let` instead of rewriting the value constantly (weird side effects on ui if you keep setting the value)
let val = this.ref.nativeElement.value;
// Convert `,` to `.` to allow for valid parsing
val = parseFloat( val.replace(/,/g, '.'))
if (this.plu.um === 'PZ'){ // controls if input is empty i'm setting 1
// Now that `val` is a number, `<= 0` is valid because it should not be used on strings
if (!val || val <= 0){
val = 1;
}
}
// Format as needed
const correctFormat = val.toString().replace(/\./g, ',')
// Set now
this.ref.nativeElement.value = correctFormat
this.plu.qta= correctFormat; // setting the object quantity to inserted value
}
}
Just a tip
If you are concerned about number formats, you could use toLocaleString and other built in number formatters that can handle stuff like currency and language.