-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathselect45.js
133 lines (110 loc) · 3.73 KB
/
select45.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"use strict";
const Select45 = (el) => {
let obj;
let index = 1;
const fn = {
addClasses: (node) => node.classList.add('select45'),
addStyles: (node) => node.style.display = 'none',
addElement: (node, referenceNode) => {
referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling);
},
selectOption: function (e) {
const selection = e.target;
const inner = selection.closest('ul');
const parent = inner.parentNode.closest('ul');
const target = document.getElementsByClassName(parent.dataset.target)[0];
e.preventDefault();
target.value = selection.dataset.val;
parent.getElementsByClassName('select45__selected')[0].innerText = selection.innerText;
},
setOptions: function (node) {
const options = node.getElementsByTagName('option');
const new_obj = document.createElement('ul');
const top_li = document.createElement('li');
const inner_list = document.createElement('ul');
this.addClasses(new_obj);
new_obj.dataset.target = `select45-${index}`;
top_li.setAttribute('tabindex', 1);
top_li.classList.add('select45__wrap');
top_li.addEventListener('click', this.toggleDropdown);
for (let option of options) {
const item = document.createElement('li');
const anchor = document.createElement('a');
if (option.hasAttribute('selected')) {
const a = document.createElement('a');
a.setAttribute('href', '#');
a.classList.add('select45__selected');
a.innerText = option.innerText;
top_li.append(a);
}
anchor.setAttribute('href', '#');
anchor.dataset.val = option.value;
anchor.innerText = option.innerText;
item.classList.add('select45__option');
item.append(anchor);
item.addEventListener('click', this.selectOption);
inner_list.classList.add('select45__inner');
inner_list.append(item);
}
top_li.append(inner_list);
new_obj.append(top_li);
this.addElement(new_obj, node);
},
getOffset: (node) => {
const box = node.getBoundingClientRect();
const body = document.body;
const docEl = document.documentElement;
const scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
const scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
const clientTop = docEl.clientTop || body.clientTop || 0;
const clientLeft = docEl.clientLeft || body.clientLeft || 0;
const top = box.top + scrollTop - clientTop;
const left = box.left + scrollLeft - clientLeft;
return {x: left, y: top};
},
setPosition: function (node) {
const node_height = node.clientHeight;
const node_offset = this.getOffset(node).y;
const view_height = document.documentElement.clientHeight || window.innerHeight;
if (node_height + node_offset > view_height - 15) {
node.classList.add('top');
}
},
toggleDropdown: function (e) {
const inner = this.getElementsByClassName('select45__inner')[0];
e.stopPropagation();
inner.classList.remove('top');
this.classList.toggle('active');
fn.setPosition(inner);
},
init: function (node) {
node.classList.add(`select45-${index}`);
this.addStyles(node);
this.setOptions(node);
index++;
}
};
if (typeof el === 'string') {
if (el.charAt(0) === '#') {
obj = document.getElementById(el.substring(1));
} else if (el.charAt(0) === '.') {
obj = document.getElementsByClassName(el.substring(1));
}
} else {
obj = el;
}
// Check if it's a collection of elements (array of nodes)
if (HTMLCollection.prototype.isPrototypeOf(obj)) {
for (let node of obj) {
fn.init(node);
}
} else {
fn.init(obj);
}
document.addEventListener('click', () => {
const wrappers = document.getElementsByClassName('select45__wrap');
for (let wrapper of wrappers) {
wrapper.classList.remove('active');
}
});
};