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

client/src/js/components/rangefield.js   A

Complexity

Total Complexity 18
Complexity/F 1.38

Size

Lines of Code 76
Function Count 13

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 18
dl 0
loc 76
rs 10
c 1
b 0
f 0
cc 0
nc 1
mnd 2
bc 8
fnc 13
bpm 0.6153
cpm 1.3846
noi 0

1 Function

Rating   Name   Duplication   Size   Complexity  
A rangefield.js ➔ ??? 0 1 1
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