Search code examples
angularangular-pipe

Decimal pipe not working on page load


I was trying to create a input[number] field which would act as an input time field.

I am using Decimal pipe (number:'2.0-0') and some javascript (if(parseInt(this.value,10)>23)this.value=23;) to format the input number into time format.

The input functionality works fine. When I input numbers, they are transformed to time format.

For e.g.,

0 -> 00
9 -> 09
99 -> 23 // For hour field
99 -> 59 // For minute field

My problem is that the saved data on page load is not formatting the numbers. i.e. 9 stays as 9 instead of 09 on page load.

The section of code is given below.

<div class="col-md-2" style="padding-right: 0px">
    <input type="number" class="form-control" placeholder="HH" [(ngModel)]="item.startHour"
           onchange="if(parseInt(this.value,10)>23)this.value=23;"
           name="startHour" value="{{item.startHour | number:'2.0-0'}}" [disabled]="readOnly"
           min="0" max="23" [required]="true"/>
</div>
<div class="col-md-2" style="padding-left: 0px">
    <input type="number" class="form-control" placeholder="MM" [(ngModel)]="item.startMinute"
           onchange="if(parseInt(this.value,10)>59)this.value=59;"
           name="startMinute" value="{{item.startMinute | number:'2.0-0'}}" [disabled]="readOnly"
           min="0" max="59" [required]="true"/>
</div>

I am using Angular v5 in my application. Any idea what I am doing wrong here?


Solution

  • Your problem is that you're using the ngModel directive. NgModel controls the value of the input, so the expression set in the value attribute has no effect, as it is overriden by NgModel.

    You should validate the data in the code of your component, including any coercion.

    For example, you could make a getter/setter:

    get minutes(): number {
        return this.item.startMinute;
    }
    
    set minutes(value: number) {
        item.startMinute = Math.max(value, 59);
    }
    

    This way, if by some circumstance the user inserts bad data, it it coerced to a valid value.

    Now, in youf component, you bind ngModel to minutes instead of item.startMinute. The same can be done for the hour.