@randstad-design/orbit-multitheme
Version:
multitheme Front-end code based on Randstad Human Forward components
121 lines (109 loc) • 3.74 kB
JavaScript
/**
* slider.js
* handles slider input field
*
*/
import ElementHelpers from '../helpers/element-helpers';
/**
* Declare constants
*/
const attributeBase = 'data-rs-slider';
export class Slider {
constructor(element) {
this.element = element;
this.rangeSlider = null;
this.init();
}
/**
* Declare attribute constants
*/
get attributes() {
return {
rangeLine: `${attributeBase}-range-line`,
bullet: `${attributeBase}-label`,
tooltip: `${attributeBase}-tooltip`,
format: `${attributeBase}-format`,
output: {
min: `${attributeBase}-min`,
max: `${attributeBase}-max`,
label: `${attributeBase}-label-value`
}
}
}
init() {
this.rangeSlider = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.rangeLine);
this.bullet = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.bullet);
this.label = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.output.label);
this.tooltip = ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.tooltip);
this.format = this.element.getAttribute(this.attributes.format);
this.addEventHandlers();
this.setOutputValues();
}
/**
* Add event handlers
*/
addEventHandlers() {
// ie11 check, ie11 reacts to "change" event instead of "input" event
let eventType = !ElementHelpers.isIE11() ? 'input' : 'change';
this.rangeSlider.addEventListener(eventType, () => {
this.setBulletPosition();
});
}
setOutputValues() {
ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.output.min).innerText = this.formatNumber(this.rangeSlider.min);
ElementHelpers.getElementByAttributeWithinElement(this.element, this.attributes.output.max).innerText = this.formatNumber(this.rangeSlider.max);
this.setBulletPosition();
}
/**
* Set bullet position
*/
setBulletPosition() {
let bulletWidth = 13;
let offsetSides = 11;
// handle bullet based on current current slider value
let sliderValue = parseInt(this.rangeSlider.value);
if (isNaN(sliderValue)) {
this.bullet.setAttribute('hidden', '');
return;
}
// write current value to bullet
this.label.innerText = this.formatNumber(sliderValue);
// set bullet position
const sliderWidth = this.rangeSlider.offsetWidth - bulletWidth;
const min = this.rangeSlider.min;
const max = this.rangeSlider.max;
let bulletOffsetX = (this.bullet.offsetWidth - offsetSides) / 2;
let newLeft = (sliderWidth * ((this.rangeSlider.value - min) / (max - min))) - bulletOffsetX;
let newLeftMax = sliderWidth - this.bullet.offsetWidth + bulletWidth + offsetSides;
if (newLeft < -1 * offsetSides) {
this.tooltip.style.marginLeft = newLeft + ((this.bullet.offsetWidth + offsetSides) / 2) + 'px';
newLeft = -1 * offsetSides;
} else if (newLeft > newLeftMax) {
this.tooltip.style.marginRight = offsetSides + (sliderWidth - newLeft) - (this.bullet.offsetWidth / 2) + (offsetSides / 2) + 'px';
newLeft = newLeftMax;
} else {
this.tooltip.style.marginRight = 'auto';
this.tooltip.style.marginLeft = 'auto'
}
this.bullet.style.left = newLeft + 'px';
}
formatNumber(number) {
let output = number;
if (typeof this.format === 'undefined' || this.format === null) { // attribute not set
return output;
} else if (this.format.trim() === '') { // attribute set, no value
// default format
output = new Intl.NumberFormat().format(number)
} else { //attribute set with value
// render for given format (nl-NL / ar-EG)
output = new Intl.NumberFormat(this.format).format(number);
}
return output;
}
/**
* Get selector
*/
static getSelector() {
return `[${attributeBase}]`;
}
}