Formatter

So although we’ve used prefix and suffix to add some formatting before and after the values in the previous examples, we can also use the formatter function to format the values in any way we like.

The formatter function is passed the value, index and percent of the pip/handle to allow us to modify the display.

<RangeSlider formatter={(value, index, percent) => { return value }} />

Pips and Floats

There are three properties that deal with formatting; formatter, handleFormatter & rangeFormatter. These are for the pips, handles and ranges respectively.

  • If the handleFormatter is not set, then the formatter will be inherited for it
    • as long as the formatter is already set
  • But rangeFormatter is not inherited as the function parameters are different

Single Formatter

Like in the prefix example, where we added a simple prefix. This time we will also style as a currency, but we will format the whole number into a currency string using the Intl.NumberFormat API.

<script>
  let values = [1000];
  const currency = new Intl.NumberFormat( "de", { style: 'currency', currency: 'EUR' });
  const formatter = (value) => currency.format(value);
</script>

<RangeSlider {formatter} float pips all="label" max={10000} step={0.1} pipstep={50000} bind:values />
Advanced Formatting Currency
1.000,00 €
0,00 € 5.000,00 € 10.000,00 €
1000

Multiple Formatters

Here we will use the same formatter example as above for displaying the handleFormatter, but we will use a different formatter for the pip labels to demonstrate how you can use different formatters for each.

<script>
  let values = [1000];
  const currency = new Intl.NumberFormat( "jp", { style: 'currency', currency: 'JPY' });
  const short = new Intl.NumberFormat( "jp", { style: 'currency', currency: "JPY", notation: "compact" });
  const handleFormatter = (value) => currency.format(value);
  const formatter = (value) => short.format(value);
  const max = 10000000;
</script>

<RangeSlider {formatter} {handleFormatter} {max} pipstep={max/2} step={1} float pips all="label" bind:values />
Different Formatter for Handles
¥1,000
¥0 ¥5M ¥10M
1000

Formatting the rangeFloat

Above we demonstrated how to format the float using the handleFormatter property, but we can also format the rangeFloat separately using the rangeFormatter property. This has a slightly different signature to the formatter & handleFormatter properties, as we need to pass in both the first and second handle values.

<script>
  let values = [0,1000000];
  
  const short = new Intl.NumberFormat( "en-GB", { style: 'currency', currency: "GBP", notation: "compact" });
  const formatter = (v) => short.format(v);
  const rangeFormatter = (v1, v2) => `<em>from</em> <strong>${short.format(v1)}</strong> <em>to</em> <strong>${short.format(v2)}</strong>`;
</script>

<RangeSlider 
  bind:values
  range 
  rangeFloat 
  {rangeFormatter}
  {formatter}
  pips 
  all="label"
  step={1000}
  pipstep={500}
  max={1000000}
/>
Formatting the rangeFloat
from £0 to £1M
£0 £500K £1M
0,1000000

Fun Formatters

A cute example where we don’t even care about numbers, a sort-of Net Promoter Score.

<script>
  let values = [0];
  const scores = Array.from({length: 5}, () =>  "⭐" );
</script>

<span class="floating-head">
  {scores[values[0]].repeat(values[0]+1)}
</span>

<RangeSlider formatter={ v => scores[v] } max={ scores.length - 1 } range="min"
  pips all="label" bind:values />
Net Promoter Survey
0

Giga

Here’s a pretty intense example, where we use the formatter to convert the values into Gigabytes, Terabytes, Petabytes, etc. There’s a pretty hefty algorithm to scale the values logarithmically, and then a special function for styling the numbers as Giga, Tera, Peta, etc.

<script>

  let values = [1];

  // format the value to a human readable string
  const formatter = (value) => {
    const gigabyte = 1000000000;
    return prettyBytes( toGigabytes(value) * gigabyte );
    // https://github.com/sindresorhus/pretty-bytes
  }

  // take the input value from the range, and then
  // power it so it outputs in a logarithmic scale
  const toGigabytes = (value) => {
    if (value <= 10) return value;
    const MOD = (val, div) => val % div;
    const POW = (base, exp) => Math.pow(base, exp);
    const CEIL = (val) => Math.ceil(val);
    const MAX = (val, val2) => Math.max(val, val2);
    const MODULO = MAX( 1, value - 1 - MOD(value - 11, 9 ));
    const POWER = POW( 10, CEIL( MODULO / 10 ));
    return ( value - MODULO ) * POWER + POWER;
  }

</script>

<RangeSlider {formatter} float pips all="label" min={1} max={55} pipstep={9} range="min" bind:values />
Gigabytes Scale
Input Readable Raw
values[0] formatter() toGigabytes()
1 1 GB 1
1 GB
1 GB 10 GB 100 GB 1 TB 10 TB 100 TB 1 PB
1

Squares

One last example of handle and pip formatters working to compliment each other. This time we will use the handleFormatter to show the real value, and the formatter to show the square of the value.

<script>
  let values = [7];
</script>

<RangeSlider formatter={v => v + "²"} handleFormatter={v => v * v} 
  float pips all="label" max={15} bind:values />
Square Numbers
49
10² 11² 12² 13² 14² 15²
7