Last active
April 29, 2025 19:39
-
-
Save trenkwill/a9d31142ac15cebde3fb1fbcc236c0ca to your computer and use it in GitHub Desktop.
Shopify Dawn facets price range slider with 2 handles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Add styling to the CSS file | |
.facets__price input[type='range'] { | |
-webkit-appearance: none; | |
padding: 0; | |
font: inherit; | |
outline: none; | |
color: rgb(var(--color-foreground)); | |
opacity: .8; | |
background: rgb(var(--color-foreground)); | |
box-sizing: border-box; | |
transition: opacity .2s; | |
cursor: pointer; | |
height: 1px; | |
} | |
.facets__price input[type='range']::-webkit-slider-thumb { | |
cursor: ew-resize; | |
background: rgb(var(--color-foreground)); | |
color: rgb(var(--color-foreground)); | |
height: 20px; | |
width: 20px; | |
border-radius: 50%; | |
cursor: pointer; | |
-webkit-appearance: none; | |
} | |
.facets__price input[type="range"]::-moz-range-progress { | |
background: rgb(var(--color-foreground)); | |
} | |
.facets__price input[type="range"]::-moz-range-track { | |
background: rgb(var(--color-foreground)); | |
} | |
/* IE*/ | |
.facets__price input[type="range"]::-ms-fill-lower { | |
background: rgb(var(--color-foreground)); | |
} | |
.facets__price input[type="range"]::-ms-fill-upper { | |
background: rgb(var(--color-foreground)); | |
} | |
.facets__price .range-wrap { | |
position: relative; | |
margin: 0 auto 3rem; | |
} | |
.facets__price .range { | |
width: 100%; | |
} | |
.facets__price .bubble { | |
position: absolute; | |
left: 50%; | |
transform: translateX(-50%); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// replace the PriceRange class in facets.js | |
class PriceRange extends HTMLElement { | |
constructor() { | |
super(); | |
this.querySelectorAll('input') | |
.forEach(element => element.addEventListener('change', this.onRangeChange.bind(this))); | |
// commented out in order to make range sliders work properly | |
// this.setMinAndMaxValues(); | |
this.querySelectorAll('.range-wrap').forEach(wrap => { | |
const range = wrap.querySelector(".range"); | |
const bubble = wrap.querySelector(".bubble"); | |
range.addEventListener("input", () => { | |
this.setBubble(range, bubble); | |
}); | |
this.setBubble(range, bubble); | |
}); | |
} | |
onRangeChange(event) { | |
this.adjustToValidValues(event.currentTarget); | |
this.setBubble(event.currentTarget, bubble); | |
// commented out in order to make range sliders work properly | |
// this.setMinAndMaxValues(); | |
} | |
setBubble(range, bubble) { | |
const val = range.value; | |
const min = range.min ? range.min : 0; | |
const max = range.max ? range.max : 100; | |
const newVal = Number(((val - min) * 100) / (max - min)); | |
bubble.innerHTML = val; | |
// Sorta magic numbers based on size of the native UI thumb | |
bubble.style.left = `calc(${newVal}% + (${8 - newVal * 0.15}px))`; | |
} | |
setMinAndMaxValues() { | |
const inputs = this.querySelectorAll('input'); | |
const minInput = inputs[0]; | |
const maxInput = inputs[1]; | |
if (maxInput.value) minInput.setAttribute('max', maxInput.value); | |
if (minInput.value) maxInput.setAttribute('min', minInput.value); | |
if (minInput.value === '') maxInput.setAttribute('min', 0); | |
if (maxInput.value === '') minInput.setAttribute('max', maxInput.getAttribute('max')); | |
} | |
adjustToValidValues(input) { | |
const value = Number(input.value); | |
const min = Number(input.getAttribute('min')); | |
const max = Number(input.getAttribute('max')); | |
if (value < min) input.value = min; | |
if (value > max) input.value = max; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// replace the <price-range> element that contains number inputs with range inputs | |
<price-range class="facets__price"> | |
<div class="range-wrap"> | |
<input | |
class="range" | |
name="{{ filter.min_value.param_name }}" | |
id="Filter-{{ filter.label | escape }}-GTE" | |
{% if filter.min_value.value %} | |
value=" | |
{%- if uses_comma_decimals -%} | |
{{ filter.min_value.value | money_without_currency | replace: '.', '' | replace: ',', '' }} | |
{% else %} | |
{{ filter.min_value.value | money_without_currency | replace: ',', '' }} | |
{% endif %} | |
" | |
{% else %} | |
value="0" | |
min="0" | |
step="0.5" | |
max=" | |
{%- if uses_comma_decimals -%} | |
{{ filter.range_max | divided_by: 2 | money_without_currency | replace: '.', '' | replace: ',', '' }} | |
{% else %} | |
{{ filter.range_max | divided_by: 2 | money_without_currency | replace: ',', '' }} | |
{% endif %} | |
" | |
{% endif %} | |
type="range" | |
> | |
<output class="bubble"></output> | |
</div> | |
<div class="range-wrap"> | |
<input | |
class="range" | |
name="{{ filter.max_value.param_name }}" | |
id="Filter-{{ filter.label | escape }}-LTE" | |
step="0.5" | |
{% if filter.max_value.value %} | |
value=" | |
{%- if uses_comma_decimals -%} | |
{{ filter.max_value.value | money_without_currency | replace: '.', '' | replace: ',', '' }} | |
{% else %} | |
{{ filter.max_value.value | money_without_currency | replace: ',', '' }} | |
{% endif %} | |
" | |
{% else %} | |
value="{{ filter.range_max | money_without_currency | replace: ',', '' }}" | |
min="{{ filter.range_max | divided_by: 2 | money_without_currency | replace: ',', '' }}" | |
{% endif %} | |
value="{{ filter.max_value.value | money_without_currency | replace: ',', '' }}" | |
type="range" | |
max="{{ filter.range_max | money_without_currency | replace: ',', '' }}" | |
> | |
<output class="bubble"></output> | |
</div> | |
</price-range> |
Seems that the var bubble is not defined on line 27:
this.setBubble(event.currentTarget, bubble);
Within the onRangeChange(event)
function.
Even the left handle has a max value of the medium number of the highest price, it can only move up to 100. Do you know the reason?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The price number under slider is not showing on dawn version 14.0.0, can u check please?