Search code examples
javascriptangularangular-directiveangular-pipe

Need angular 2+ currency pipe to show 2 decimals and accept various user input


I have an input that I need to display currency in. I need it to always show 2 decimal places and no dollar symbol. I decided to use the number pipe since I was not concerned about the dollar symbol. This input is editable by the user but when I use the pipe, I am getting undesirable behavior.

Here is what the code looks like for the input:

<input type="text"
[ngModel]="myCurrencyVar | number:'1.2-2'"
(ngModelChange)="myCurrencyVar=$event">

The problem with this approach is that if the user wants to enter something like $2.55, as they type, the value will jump to 2.00 when they type the digit 2 and then they have to hit the delete key twice to clear out the zeros, then when they hit the 5 key it will become $2.50 then the user has to delete the last zero again to enter in the final 5.

I also tried:

<input type="text"
[ngModel]="myCurrencyVar | number:'1.0-2'"
(ngModelChange)="myCurrencyVar=$event">

But that approach will show something like $2.5 when it needs to be $2.50 on screen. I need it to show the cents all the time without having this weird behavior.

I also tried with the currency pipe:

currency:'USD':'':'1.2-2'"

Is there any way to accomplish having 2 decimals always displaying without it acting all goofy when the user types?


UPDATE 1

This is what I changed it to after I got the suggestion to update to two-way binding, but the model doesn't seem to update when I change the dollar amount in the input:

<input type="text"
([ngModel])="myCurrencyVar"
currencyMask [options]="{ prefix: '' }">

UPDATE 2

My solution to the screen update problem was to go back to using (ngModelChange) and adding an update() function after the $event was passed in like so:

<input type="text"
[ngModel]="myCurrencyVar | number:'1.0-2'"
(ngModelChange)="myCurrencyVar=$event;update()">

Solution

  • From my experience, I've used to pipes to only change read-only data or how data is displayed. For changing the formatting of an input in Angular, I reverted to using custom directives.

    Here's a directive that I think accomplishes what you're trying to do:

    https://www.npmjs.com/package/ng2-currency-mask