Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4 - how to render 2 decimal places for type='input'

This question is about restricting/validating the input when the user enters data into an input of type number.

The issue I have is that when the model first loads, any numbers that are integers or 1dp, get rendered with only 1dp. eg 40 or 40.0 both show as 40.0 (not as 40.00).

I have added this code so that after a user types a new value, it shows with 2dp:

in the template file:

(change)="setTwoNumberDecimal($event)"

in the component file:

  setTwoNumberDecimal($event) {
    $event.target.value = parseFloat($event.target.value).toFixed(2);
  }

This works to show 2dp after the user changes the value.

I tried to write a directive that should format to 2dp when the data initially loads, but although the directive does fire, it does not change the value to 2dp.

import { Directive, ElementRef, Input, Renderer2 } from '@angular/core';

@Directive ({
  selector: '[fbDecimalFormat]'
})

export class DecimalFormatDirective {

  constructor(private el: ElementRef,
              private renderer: Renderer2) {
    //renderer.setAttribute(el, 'value', parseFloat(el.nativeElement.value).toFixed(2));
    this.el.nativeElement.value = parseFloat(this.el.nativeElement.value).toFixed(2);
  }

}

FYI the commented render line did not work (error: setAttribute not recognised) - it was an attempt to be platform independent.

So the question is: How can I get the input to render its initial value with 2dps?

like image 544
rmcsharry Avatar asked Aug 23 '17 10:08

rmcsharry


People also ask

How do you limit decimal places in input field?

Use JavaScript for validation input or use step=". 01" , which allows up to two decimal places on keypress input.

How do I show two decimal places in typescript?

Use the toFixed() method to format a number to 2 decimal places, e.g. num. toFixed(2) . The toFixed method takes a parameter, representing how many digits should appear after the decimal and returns the result.

How do you move a number to 2 decimal places?

Rounding a decimal number to two decimal places is the same as rounding it to the hundredths place, which is the second place to the right of the decimal point. For example, 2.83620364 can be round to two decimal places as 2.84, and 0.7035 can be round to two decimal places as 0.70.

How do you store decimals in typescript?

All numbers are stored as floating point numbers. These numbers can be Decimal (base 10), Hexadecimal (base 16) or Octal (base 8). In the above example, let first:number = 1; stores a positive integer as a number. let second: number = 0x37CF; stores a hexadecimal as a number which is equivalent to 14287.


2 Answers

Template Forms

The solution to this was to use the built-in DecimalPipe (weirdly called number) and not use two-way binding for the model value - ie. from [(ngModel)] to [ngModel] and (ngModelChange)

    <input type="number" step="0.01" 
            (change)="setTwoNumberDecimal($event)"
            (ngModelChange)="item.value=$event"
            [ngModelOptions]="{updateOn: 'blur'}"
            [ngModel]="setting.decimal_value | number:'1.2-2'">

See this question for more info on splitting the [()] binding.

Notice also that the update fires only when the user leaves the control (blur) otherwise every time they type something it will update, which will be a frustrating UX (thanks to @Mihail's comment).

Reactive Forms

In response to the question in the comments: "Could this be used with reactive forms as well?"

The answer is:

No, using pipes with reactive forms is more complicated. You could use the pipe merely to display the value, like

 <p>{{form.get('name').value | myPipe}}</p> 

but I think the correct way is to use value accessor. More info here.

like image 194
rmcsharry Avatar answered Oct 19 '22 16:10

rmcsharry


Number.toFixed(x) Formats any number for "x" number of trailing decimals. The number is rounded up, and "0"s are used after the decimal point if needed to create the desired decimal length. In template we can format the value and validating the values

value1 = 0
value2 = 0.0

<p>
  {{value1.toFixed(2)}} - shows 0.00
  {{value2.toFixed(2)}} - shows 0.00
</p>
like image 36
MukundK Avatar answered Oct 19 '22 16:10

MukundK