2

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.

0

2 Answers 2

3

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);
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Your initial code didn't work for me, but your use of (ngModelChange) led me to split: [(ngModel)] into [value] and (ngModelChange) and after doing a bit more digging regarding order of min, max, step, value, following worked for me: <input [formControlName]="object.id" [id]="object.id" type="range" [min]="object.minValue" [max]="object.maxValue" [step]="object.step" [value]="object.answer" (ngModelChange)="object.answer=$event">
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.