Search code examples
angular-materialangular-material2angular19mat-slider

How to set different labels for start and end values in Angular Material mat-slider range?


I am using an Angular Material mat-slider with a range selection (start and end thumbs). I want to format the labels so that:

The start thumb displays: "Min: (value)"
The end thumb displays: "Max: (value)"

However, the displayWith function (formatSlideRangeLabel) only receives a single value, so I cannot differentiate between the start and end thumbs. My Code:

  <mat-slider class="ai-basic-slider"
              id="inserted-media-range"
              min="0" max="51" step="1"
              discrete showTickMarks
              [displayWith]="formatSlideRangeLabel">
    <input matSliderStartThumb>
    <input matSliderEndThumb>
  </mat-slider>

  public formatSlideRangeLabel(value: number): string {
    if (value == 51) {
      return 'Max: ∞';
    } else {
      return 'Max: ' + value;
    }

    return `${value}`;
  }

enter image description here


Solution

  • First bind the min and max values to local properties.

    <input matSliderStartThumb [(ngModel)]="min" />
    <input matSliderEndThumb [(ngModel)]="max" />
    

    Then all you need to do is check if the value from the displayWith is equal to min value that is binded using ngModel, if the values are equal then it's the min value you are dealing with.

    public formatSlideRangeLabel(value: number): string {
      if (value === this.min()) {
        // then it is max
        return 'Min: ' + value;
      } else {
        if (value == 51) {
          return 'Max: ∞';
        } else {
          return 'Max: ' + value;
        }
      }
    }
    

    To access this.min(), you have to make sure that function is executed in the component context, to achieve this, we use .bind(this).

    HTML:

    <mat-slider
      class="ai-basic-slider"
      id="inserted-media-range"
      min="0"
      max="51"
      step="1"
      discrete
      showTickMarks
      [displayWith]="formatSlideRangeLabel.bind(this)"
    >
      <input matSliderStartThumb [(ngModel)]="min" />
      <input matSliderEndThumb [(ngModel)]="max" />
    </mat-slider>
    

    TS:

    import { Component, model } from '@angular/core';
    import { MatSliderModule } from '@angular/material/slider';
    import { FormsModule } from '@angular/forms';
    
    /**
     * @title Range slider
     */
    @Component({
      selector: 'slider-range-example',
      templateUrl: 'slider-range-example.html',
      styleUrl: 'slider-range-example.css',
      imports: [MatSliderModule, FormsModule],
    })
    export class SliderRangeExample {
      min = model(0);
      max = model(0);
      public formatSlideRangeLabel(value: number): string {
        if (value === this.min()) {
          // then it is max
          return 'Min: ' + value;
        } else {
          if (value == 51) {
            return 'Max: ∞';
          } else {
            return 'Max: ' + value;
          }
        }
      }
    }
    

    Stackblitz Demo