Completed
Push — master ( 9d8ca3...5cf646 )
by Simon
8s
created

rangefield.js ➔ ???   A

Complexity

Conditions 1
Paths 0

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
rs 10
c 0
b 0
f 0
cc 1
nc 0
nop 2
1
import noUiSlider from 'nouislider';
2
3
const SETTINGS_ATTR = 'data-settings';
4
const VALUE_ATTR = 'value';
5
const SLIDER_CLASS = 'noUi-target';
6
const ELEMENT_SELECTOR = 'div[data-range=rangefield]';
7
8
const observerConfig = {
9
  attributes: false,
10
  characterData: false,
11
  childList: true,
12
  subtree: true
13
};
14
15
const format = (unit, decimalPlaces) => value => parseFloat(value).toFixed(decimalPlaces) + unit;
16
17
const fieldWithName = fieldName => document.body.querySelectorAll(`input[name=${fieldName}]`)[0];
18
19
const fieldDescriptionWithName = fieldName => document.body.getElementsByClassName(`${fieldName}-range-description`)[0];
20
21
const valueToArray = value => (!Array.isArray(value) ? [value] : value);
22
23
const hasFormatSettings = settings => settings.unit && (settings.decimalPlaces > -1);
24
25
const updateElementValue = (settings, fieldName, value) => {
26
  const input = fieldWithName(fieldName);
27
  const description = fieldDescriptionWithName(fieldName);
28
  const formatter = format(settings.unit, settings.decimalPlaces);
29
  const displayValue = hasFormatSettings(settings) ? value.map(formatter) : value;
30
31
  input.setAttribute(VALUE_ATTR, displayValue.join(','));
32
  description.innerHTML = displayValue.join(' ');
33
};
34
35
const mountRangeField = (rangefield) => {
36
  const fieldName = rangefield.getAttribute(SETTINGS_ATTR);
37
  const input = fieldWithName(fieldName);
38
  const settings = window[fieldName];
39
40
  settings.start = valueToArray(settings.start);
41
42
  if (input.hasAttribute(VALUE_ATTR)) {
43
    const values = input.getAttribute(VALUE_ATTR).split(',');
44
    if (values.length === settings.start.length) {
45
      settings.start = values;
46
    }
47
  }
48
  noUiSlider.create(rangefield, settings);
49
50
  rangefield.noUiSlider.on('update', () => {
51
    const value = valueToArray(rangefield.noUiSlider.get());
52
    updateElementValue(settings, fieldName, value);
53
  });
54
55
  updateElementValue(settings, fieldName, settings.start);
56
};
57
58
const mount = () => {
59
  // If things change and we haven't painted our UiSlider yet, go for it
60
  if (document.body.getElementsByClassName(SLIDER_CLASS).length === 0) {
61
    const ranges = document.body.querySelectorAll(ELEMENT_SELECTOR);
62
    ranges.forEach(mountRangeField);
63
  }
64
};
65
66
const onMutation = () => mount();
67
68
/** global: MutationObserver */
69
const observerFactory = callback => new MutationObserver(callback);
70
71
const loadRangeSlider = (createObserver = observerFactory) => {
72
  mount(); // mount any relevant elements in the dom on load
73
  createObserver(onMutation).observe(document.body, observerConfig);
74
};
75
76
export default loadRangeSlider;
77