Range Slider
Range Slider Layout
Single Range
Single range slider layout is pretty simple:
<!-- Range Slider element -->
<div class="range-slider">
<!-- range input -->
<input type="range" min="0" max="100" step="1" value="10" />
</div>
Dual Range
Dual range slider is more simpler as it doesn't require input element because input:range doesn't support dual range:
<!-- Range Slider element -->
<div class="range-slider"></div>
Range Slider Colors
Range Slider supports all default colors. So to change its color just add color-[color] class to range slider element.
<!-- red range -->
<div class="range-slider color-red">...</div>
<!-- orange range -->
<div class="range-slider color-orange">...</div>
Range Slider App Methods
Let's look at related App methods to work with Range Slider:
app.range.create(parameters)- create Range Slider instance
- parameters - object. Object with range slider parameters
Method returns created Range Slider's instance
app.range.destroy(el)- destroy Range Slider instance
- el - HTMLElement or string (with CSS Selector) or object. Range Slider element or Range Slider instance to destroy.
app.range.get(el)- get Range Slider instance by HTML element
- el - HTMLElement or string (with CSS Selector). Range Slider element.
Method returns Range Slider's instance
app.range.getValue(el)- get Range Slider value
- el - HTMLElement or string (with CSS Selector). Range Slider element.
Method returns range slider value
app.range.setValue(el, value)- set new Range Slider value
- el - HTMLElement or string (with CSS Selector). Range Slider element.
- value - number (in case of single range) or array of values (in case of dual range)
Method returns Range Slider's instance
Range Slider Parameters
Now let's look at list of available parameters we need to create Range Slider:
Parameter | Type | Default | Description |
---|---|---|---|
el | HTMLElement string | Range Slider element. HTMLElement or string with CSS selector of range slider element | |
inputEl | HTMLElement string | Range Slider input element or CSS selector of input element. If not specified, will try to look for input type="range" inside of range slider element | |
dual | boolean | false | Enable dual range slider |
step | number | 1 | Minimal step between values |
label | boolean | false | Enables additional label around range slider knob |
formatLabel | function(value) | Method must return formatted range knob label text. As an argument it receives label value | |
min | number | Minimum value | |
max | number | Maximum value | |
value | number array | Initial value. Number in case of single range, and array of values in case of dual range | |
draggableBar | boolean | true | When enabled it is also possible to interact with range slider (change value) on range bar click and swipe. |
vertical | boolean | false | Enables vertical range slider |
verticalReversed | boolean | false | Makes vertical range slider reversed (vertical must be also enabled) |
scale | boolean | false | Enables range slider scale |
scaleSteps | number | 5 | Number of scale steps |
scaleSubSteps | number | 0 | Number of scale sub steps (each step will be divided by this value) |
formatScaleLabel | function (value) | Method must return formatted scale value. As an argument it receives currect scale step value. This method will be called as for each scale step. | |
limitKnobPosition | boolean | Limits knob position to the size of the range bar. By default enabled from iOS theme | |
on | object | Object with events handlers. For example:
|
Range Slider Methods & Properties
So to create Range Slider we have to call:
var range = app.range.create({ /* parameters */ })
After that we have its initialized instance (like range
variable in example above) with useful methods and properties:
Properties | |
---|---|
range.app | Link to global app instance |
range.el | Range Slider HTML element |
range.$el | Dom7 instance with range slider HTML element |
range.inputEl | Range Slider input HTML element |
range.$inputEl | Dom7 instance with range slider input HTML element |
range.rangeWidth | Range slider width (in px) |
range.dual | Boolean property indicating whether it is dual or not |
range.min | Range min value |
range.max | Range max value |
range.value | Range value |
range.scale | Boolean property indicating whether scale is enabled or not |
range.scaleSteps | Number of scale steps |
range.scaleSubSteps | Number of scale sub steps |
range.$scaleEl | Dom7 instance with generated scale HTML element |
range.knobs | Array where each element represents HTMLElement of created range knob (2 knobs in case of dual slider) |
range.labels | Array where each element represent HTMLElement of created range knob label (2 labels in case of dual slider) |
range.vertical | Boolean property indicating whether it is vertical or not |
range.verticalReversed | Boolean property indicating whether it is vertical and reversed or not |
range.params | Range Slider parameters |
Methods | |
range.getValue() | Returns range slider value |
range.setValue(value) | Set new range slider value |
range.updateScale() | Re-calculate and re-render slider scale |
range.destroy() | Destroys range slider instance |
range.on(event, handler) | Add event handler |
range.once(event, handler) | Add event handler that will be removed after it was fired |
range.off(event, handler) | Remove event handler |
range.off(event) | Remove all handlers for specified event |
range.emit(event, ...args) | Fire event on instance |
Range Slider Events
Range Slider will fire the following DOM events on range element and events on app and range instance:
DOM Events
Event | Target | Description |
---|---|---|
range:change | Range Slider Element<div class="range-slider"> | Event will be triggered when Range Slider value has been changed |
range:changed | Range Slider Element<div class="range-slider"> | Event will be triggered on slider knob release after value change |
range:beforedestroy | Range Slider Element<div class="range-slider"> | Event will be triggered right before Range Slider instance will be destroyed |
App and Range Slider Instance Events
Range Slider instance emits events on both self instance and app instance. App instance events has same names prefixed with range
.
Event | Arguments | Target | Description |
---|---|---|---|
change | (range, value) | range | Event will be triggered when range value has been changed. As an argument event handler receives range instance |
rangeChange | (range, value) | app | |
changed | (range, value) | range | Event will be triggered on slider knob release after value change. As an argument event handler receives range instance |
rangeChanged | (range, value) | app | |
beforeDestroy | (range) | range | Event will be triggered right before Range Slider instance will be destroyed. As an argument event handler receives range instance |
rangeBeforeDestroy | (range) | app |
Range Slider Auto Initialization
If you don't need to use Range Slider API and your Range Slider is inside of the page and presented in DOM on moment of page initialization then it can be auto initialized with just adding additional range-slider-init
class:
<!-- Add range-slider-init class -->
<div class="range-slider range-slider-init">
<input type="range" min="0" max="100" step="1" value="10" />
</div>
In this case if you need to access created Range Slider instance you can use the app.range.get
app method:
var range = app.range.get('.range-slider');
if (range.value > 50) {
// do something
}
When using auto init you may need to pass additional parameters. It can be done with two ways:
In you case you use single-range slider and you have input:range inside, then
step
,min
,max
,value
parameters can be set from same input attributes:<!-- min, max, step, value parameters will be set for same input attributes --> <div class="range-slider range-slider-init"> <input type="range" min="0" max="100" step="1" value="10" /> </div>
Otherwise, if you don't have input:range inside or you use dual range input you can set all available parameters via
data-
attributes on range slider element.<!-- parameters set via data- attributes --> <div class="range-slider range-slider-init" data-min="0" data-max="100" data-step="10" data-label="true" data-value="50" ></div>
In case you have dual range slider, then you need to pass to values using
data-value-left
anddata-value-right
attributes:<!-- parameters set via data- attributes --> <div class="range-slider range-slider-init" data-dual="true" data-min="0" data-max="100" data-step="10" data-label="true" data-value-left="30" data-value-right="60" ></div>
CSS Variables
Below is the list of related CSS variables (CSS custom properties).
Note that commented variables are not specified by default and their values is what they fallback to in this case.
:root {
/*
--f7-range-bar-active-bg-color: var(--f7-theme-color);
--f7-range-scale-bg-color: var(--f7-range-bar-bg-color);
--f7-range-scale-substep-bg-color: var(--f7-range-bar-bg-color);
*/
--f7-range-scale-step-height: 5px;
--f7-range-scale-substep-width: 1px;
--f7-range-scale-substep-height: 4px;
--f7-range-bar-bg-color: rgba(0, 0, 0, 0.2);
}
:root .dark,
:root.dark {
--f7-range-bar-bg-color: rgba(255, 255, 255, 0.2);
}
.ios {
--f7-range-size: 28px;
--f7-range-bar-size: 4px;
--f7-range-bar-border-radius: 2px;
--f7-range-knob-size: 28px;
--f7-range-knob-color: #fff;
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
--f7-range-label-size: 24px;
--f7-range-label-text-color: #000;
--f7-range-label-bg-color: #fff;
--f7-range-label-font-size: 12px;
--f7-range-label-font-weight: 500;
--f7-range-label-border-radius: 5px;
--f7-range-label-padding: 0px 2px;
--f7-range-scale-text-color: #666;
--f7-range-scale-step-width: 1px;
--f7-range-scale-font-size: 12px;
--f7-range-scale-font-weight: 400;
--f7-range-scale-label-offset: 4px;
}
.md {
--f7-range-size: 20px;
--f7-range-bar-size: 2px;
--f7-range-bar-border-radius: 0px;
--f7-range-knob-size: 12px;
--f7-range-knob-box-shadow: none;
--f7-range-label-size: 26px;
--f7-range-label-font-weight: normal;
--f7-range-label-font-size: 10px;
--f7-range-label-border-radius: 50%;
--f7-range-label-padding: 0px;
--f7-range-scale-step-width: 2px;
--f7-range-scale-font-size: 12px;
--f7-range-scale-font-weight: 400;
--f7-range-scale-label-offset: 4px;
}
.md,
.md .dark,
.md [class*='color-'] {
--f7-range-knob-color: var(--f7-theme-color);
--f7-range-label-text-color: var(--f7-md-on-primary);
--f7-range-label-bg-color: var(--f7-theme-color);
--f7-range-scale-text-color: var(--f7-md-on-surface-variant);
}
Examples
<template>
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner sliding">
<div class="title">Range Slider</div>
</div>
</div>
<div class="page-content">
<div class="block-title">Volume</div>
<div class="list list-strong-ios list-outline-ios simple-list">
<ul>
<li>
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">speaker_fill</i>
<i class="icon material-icons md-only" style="width: 24px">volume_mute</i>
</div>
<div style="width: 100%; margin: 0 16px">
<div class="range-slider range-slider-init">
<input type="range" min="0" max="100" step="1" value="10" />
</div>
</div>
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">speaker_3_fill</i>
<i class="icon material-icons md-only" style="width: 24px">volume_up</i>
</div>
</li>
</ul>
</div>
<div class="block-title">Brightness</div>
<div class="list list-strong-ios list-outline-ios simple-list">
<ul>
<li>
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">sun_min</i>
<i class="icon material-icons md-only" style="width: 24px">brightness_low</i>
</div>
<div style="width: 100%; margin: 0 16px">
<div class="range-slider range-slider-init color-orange" data-label="true">
<input type="range" min="0" max="100" step="1" value="50" />
</div>
</div>
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">sun_max_fill</i>
<i class="icon material-icons md-only" style="width: 24px">brightness_high</i>
</div>
</li>
</ul>
</div>
<div class="block-title display-flex justify-content-space-between">
Price Filter <span class="price-value">$${priceMin} - $${priceMax}</span>
</div>
<div class="list list-strong-ios list-outline-ios simple-list">
<ul>
<li class="item-row">
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">money_dollar_circle</i>
<i class="icon material-icons md-only" style="width: 24px">attach_money</i>
</div>
<div style="width: 100%; margin: 0 16px">
<div class="range-slider range-slider-init color-green" @range:change=${onPriceChange} data-label="true"
data-dual="true" data-min="0" data-max="500" data-step="1" data-value-left="200" data-value-right="400">
</div>
</div>
<div>
<i class="icon f7-icons if-not-md" style="width: 28px">money_dollar_circle_fill</i>
<i class="icon material-icons md-only" style="width: 24px">monetization_on</i>
</div>
</li>
</ul>
</div>
<div class="block-title">With Scale</div>
<div class="block block-strong-ios block-outline-ios">
<div class="range-slider range-slider-init" data-min="0" data-max="100" data-label="true" data-step="5"
data-value="25" data-scale="true" data-scale-steps="5" data-scale-sub-steps="4"></div>
</div>
<div class="block-title">Vertical</div>
<div class="block block-strong-ios block-outline-ios display-flex justify-content-center">
<div class="range-slider range-slider-init margin-right" data-vertical="true" data-min="0" data-max="100"
data-label="true" data-step="1" data-value="25" style="height: 160px"></div>
<div class="range-slider range-slider-init margin-horizontal" data-vertical="true" data-min="0" data-max="100"
data-label="true" data-step="1" data-value="50" style="height: 160px"></div>
<div class="range-slider range-slider-init margin-horizontal" data-vertical="true" data-min="0" data-max="100"
data-label="true" data-step="1" data-value="75" style="height: 160px"></div>
<div class="range-slider range-slider-init margin-left" data-dual="true" data-vertical="true" data-min="0"
data-max="100" data-label="true" data-step="1" data-value-left="25" data-value-right="75"
style="height: 160px"></div>
</div>
<div class="block-title">Vertical Reversed</div>
<div class="block block-strong-ios block-outline-ios display-flex justify-content-center">
<div class="range-slider range-slider-init color-red margin-right" data-vertical="true"
data-vertical-reversed="true" data-min="0" data-max="100" data-label="true" data-step="1" data-value="25"
style="height: 160px"></div>
<div class="range-slider range-slider-init color-red margin-horizontal" data-vertical="true"
data-vertical-reversed="true" data-min="0" data-max="100" data-label="true" data-step="1" data-value="50"
style="height: 160px"></div>
<div class="range-slider range-slider-init color-red margin-horizontal" data-vertical="true"
data-vertical-reversed="true" data-min="0" data-max="100" data-label="true" data-step="1" data-value="75"
style="height: 160px"></div>
<div class="range-slider range-slider-init color-red margin-left" data-dual="true" data-vertical="true"
data-vertical-reversed="true" data-min="0" data-max="100" data-label="true" data-step="1" data-value-left="25"
data-value-right="75" style="height: 160px"></div>
</div>
</div>
</div>
</template>
<script>
export default (props, { $f7, $el, $update }) => {
let priceMin = 200;
let priceMax = 400;
const onPriceChange = (e) => {
const range = $f7.range.get(e.target);
priceMin = range.value[0];
priceMax = range.value[1];
$update();
};
return $render;
};
</script>