Titus
Titus

Reputation: 349

How to customize ion-range in ionic 5?

I am looking for a solution with my current issue regarding on how to customize the ion-range based on the wireframe. As you can see below the difference between the wireframe and the actual worked I made.

Wireframe Design

wireframe

My actual work

enter image description here

Above, you can see the difference between the two. My question is, is there anyway or solution that I can do to get the actual look of the wireframe. Based on the wireframe, as the user moves the tick, the label aligned with the tick should be color blue also.

These are my codes I used and produced my actual work.

.html

   <div class="slidecontainer">
    <ion-range 
        class="range-position"
        min="5" 
        max="100" 
        dualknobs="true"
        pin="false"
        snaps="true"
        ticks="false"
        value="0" 
        snaps color="primary"
        list='tickmarks'>
    </ion-range>

    <div id="tickmarks" class="tick-position">
        <p>5</p>
        <p>10</p>
        <p>25</p>
        <p>50</p>
        <p>75</p>
        <p>100</p>
    </div>
</div>

.scss

// Customize Slider
   #tickmarks {
   display: flex;
   justify-content: space-between;
   padding: 0 25px;
   }

   #tickmarks p {
    position: relative;
    display: flex;
    justify-content: center;
    text-align: center;
    width: 1px;
    background: #ccd3da;
    height: 10px;
    line-height: 40px;
    margin: 0 0 20px 0;
    font-family: 'Archivo';
    font-size: 12px;
   }

Hope you can help so that I can move forward with my task. Thank you so much

Upvotes: 3

Views: 5571

Answers (2)

magikMaker
magikMaker

Reputation: 5607

You can have the the tick marks underneath the ion-range component react to the selected value in the range, like below.

Add a function that listens to the ionChange event to <ion-change>. Use that function in your component class to update a value. Then you can use that value in your template to indicate which tick should be highlighted (gets the selected CSS class).

range.component.html - for single range (one knob)

<div class="range-container">
  <ion-range
    (ionChange)="setValue($event)"        
    [value]="currentValue" 
    color="primary"
    dual-knobs="false"
    max="100"
    min="0"
    pin="false"
    snaps="true"
    step="25"
    ticks="false"
    
  >
  </ion-range>
  <ul class="tick-marks">
    <li 
      *ngFor="let number of [0, 25, 50, 75, 100]"
      [class.selected]="number === currentValue"
    >
      {{number}}
    </li>
  </ul>
</div>

range.component.html - for dual knobs

<div class="range-container">
  <ion-range
    (ionChange)="setDualValues($event)"
    [value]="currentDualValues" 
    color="primary"
    dual-knobs="true"
    max="100"
    min="0"
    pin="false"
    snaps="true"
    step="25"
    ticks="false"
  >
  </ion-range>
  <ul class="tick-marks">
    <li 
      *ngFor="let number of [0, 25, 50, 75, 100]"
      [class.selected]="number === currentDualValues.lower || number === currentDualValues.upper"
    >
      {{number}}
    </li>
  </ul>
</div>

range.component.ts- the component file

@Component({
  selector: 'app-range',
  styleUrls: ['./range.component.scss']
  templateUrl: './range.component.html'
})
export class RangeComponent {
  currentValue = 0;
  currentDualValues = {
    lower: 25,
    upper: 50
  };
  
  // use this for single slider
  setValue($event: Event): void {
    this.currentValue = parseInt(($event.target as HTMLInputElement).value, 10);
  }
  
  // use this for dual sliders (dual knobs)
  setDualValues($event: Event): void {
    this.currentDualValues = JSON.parse(JSON.stringify(($event.target as HTMLInputElement).value));
  }
}

Finally, in your CSS add the .selected class to style selected numbers as you wish, for instance like this (you will probably need to change padding of ul.tick-marks to make sure the tick marks align properly with the range selector):

range.component.scss

.range-container {
  display: flex;
  flex-direction: column;
  width: 100%;

  .tick-marks {
    display: flex;
    justify-content: space-between;
    list-style: none;
    margin: 0;
    padding: 0;

    li {
      color: var(--ion-color-dark);
      position: relative;

      &::before {
        background-color: var(--ion-color-dark);
        content: '';
        display: block;
        height: 20px;
        left: 50%;
        position: absolute;
        width: 1px;
        top: -20px;
      }

      &.selected {
        color: var(--ion-color-primary);

        &::before {
          background-color: var(--ion-color-primary); 
        }
      }
    }
  }
}

See also this stackblitz for reference.

Upvotes: 0

Najam Us Saqib
Najam Us Saqib

Reputation: 3402

You can Use (ionChange) event to make it work.

 <ion-range 
    class="range-position"
    min="5" 
    max="100" 
    dualknobs="true"
    pin="false"
    snaps="true"
    ticks="false"
    value="0"
    step="25"  // use step attribute for sure event value
    snaps color="primary"
    list='tickmarks'
    (ionChange)="changeFunction($event)">
</ion-range>
<div id="tickmarks" class="tick-position">
    <p [ngClass]="selectedValue == 0 ? 'active' : null">5</p>
    <p [ngClass]="selectedValue == 25 ? 'active' : null">25</p>
    <p [ngClass]="selectedValue == 50 ? 'active' : null">50</p>
    <p [ngClass]="selectedValue == 75 ? 'active' : null">75</p>
    <p [ngClass]="selectedValue == 100 ? 'active' : null">100</p>
</div>

.ts

selectedValue;

changeFunction($event){
   this.selectedValue =  $event.detail.value;
}

Upvotes: 2

Related Questions