apooravc
apooravc

Reputation: 23

Angular input range slider rounding off decimal data-binded values

I've created a range slider in a form in Angular which is used to record values and display recorded values.

<input [formControlName]="object.id" [id]="object.id" type="range" [(ngModel)]="object.answer" [step]="object.step" [min]="object.minValue" [max]="object.maxValue">

With object containing key-value pairs for id, answer, step, min, max which comes from database.

For following object,

{ id: 1, answer: 4, step: 0.25, minValue: 3, maxValue: 4 }

slider is displaying correct value, i.e., 4.

However, with answer: 3.25 and answer: 3.75, it is displaying 3 and 4 resp. Slider seems to be rounding off decimal answer values to nearest integer.

I looked up MDN for input range and under the step section, there was a note which said:

When the data entered by the user doesn't adhere to the stepping configuration, the user agent may round to the nearest valid value, preferring numbers in the positive direction when there are two equally close options.

But, aren't 3.25 or 3.75 valid values? Both can be written as (min + multiple of step) <= max for given min: 3, max: 4 and step: 0.25

I also looked up how to disable user-agent validation here and used novalidate attribute in form tag and slider was still not displaying correctly for decimal values. But, it displays correctly for integer values in specified range.

Edit 1: I tried checking with different types of 'step' values. It is displaying correctly for integer steps (1, 2, 3), decimal > 1 steps (1.1, 1.5, 2.5). It seems to be not displaying correctly with decimal < 1 steps (0.5, 0.3).

Edit 2: Also, if I use step="0.25" instead of [step]="object.step", it's displaying correctly. So, static step is working, but property bind-ed step value is not working properly and that too for step values < 1.

Upvotes: 2

Views: 2346

Answers (2)

Basil Sajeev
Basil Sajeev

Reputation: 1

I assigned $event.target.value to ngModel variable on (input) event.

Upvotes: 0

Ashish Kumar Jaryal
Ashish Kumar Jaryal

Reputation: 812

Live Example
I've tried to replicate your scenario with little tweaking and it seems to be working fine. Please have a look if it help you. Feel free to tweak the model values of obj as per your requirements.

Template:

<hello name="{{ name }}"></hello>
<p>
    Start editing to see some magic happen :)
  <br>Please see the console :)
</p>
<input 
[id]="obj.id" type="range" 
[step]="obj.step" [min]="obj.minValue" [max]="obj.maxValue" [(ngModel)]="obj.answer" 
 (ngModelChange)="valueChanged($event)"
>

Component:

import { Component, VERSION, OnChanges } from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  name = "Angular " + VERSION.major;
  obj = {
    id: 1,
    answer: 0,
    step: 0.25,
    minValue: 0,
    maxValue: 47.8
  };
  constructor() {}

  valueChanged(event:any){
    console.log(event);
    console.log(this.obj);
  }
}

Upvotes: 3

Related Questions