PageSourceSearch

https://high.org/wp-content/themes/icelander-child/assets/js/global-helpers/selects.js?t=1790239380

js high.org collected 2026-09-24 08:52:10 UTC 4,411 bytes, 205 lines download raw bytes

1let container;
2let trigger;
3let arrow;
4let selectedText;
5let optionsList;
6let options;
7let hiddenField;
8let isExpanded = false;
9
10window.addEventListener('DOMContentLoaded', function (e) {
11	container = document.querySelector('.custom-select');
12	trigger = document.querySelector('.custom-select .trigger');
13	arrow = document.querySelector('.custom-select .icon');
14	selectedText = document.getElementById('selected-text');
15	optionsList = document.querySelector('.custom-select .options');
16	options = document.querySelectorAll('.custom-select .options li');
17	hiddenField = document.getElementById('hidden-field');
18
19	// Handle keyboard and mouse interactions on the trigger bar
20	if (trigger) {
21		trigger.addEventListener('keydown', handleTriggerKeypresses);
22		trigger.addEventListener('click', handleTriggerClick);
23
24		// Select options when they are clicked
25		options.forEach(function (option) {
26			option.addEventListener('click', function (e) {
27				unselectAllOptions();
28				selectOption(e.target);
29				collapseOptions();
30				trigger.focus();
31			});
32		});
33
34		// Collapse the dropdown when the user clicks off
35		document.addEventListener('click', handleBodyClick);
36	}
37});
38
39
40/**
41  Event handlers
42 */
43function handleTriggerKeypresses (e) {
44	switch (e.key) {
45		case 'ArrowUp':
46			e.preventDefault();
47
48			if (isExpanded) {
49				selectPreviousOption();
50			} else {
51				expandOptions();
52			}
53
54			break;
55
56		case 'ArrowDown':
57			e.preventDefault();
58
59			if (isExpanded) {
60				selectNextOption();
61			} else {
62				expandOptions();
63				selectFirstOption();
64			}
65
66			break;
67
68		case 'Home':
69			if (isExpanded) {
70				selectFirstOption();
71			}
72
73			break;
74
75		case 'End':
76			if (isExpanded) {
77				selectLastOption();
78			}
79
80			break;
81
82		case 'Tab':
83			collapseOptions();
84			break;
85
86		case 'Escape':
87		case 'Enter':
88
89			if (isExpanded) {
90				e.preventDefault();
91				collapseOptions(e);
92			}
93
94			break;
95	}
96}
97
98function handleBodyClick (e) {
99	if (!container.contains(e.target) && isExpanded) {
100		collapseOptions();
101	}
102}
103
104function handleTriggerClick () {
105	if (isExpanded) {
106		collapseOptions();
107		trigger.focus();
108	} else {
109		expandOptions();
110	}
111}
112
113/**
114 * Toggle arrow position
115 */
116function toggleArrowPosition (shouldToggle) {
117	if (shouldToggle) {
118		arrow.classList.add('expanded');
119	} else {
120		arrow.classList.remove('expanded');
121	}
122}
123
124
125/**
126  Show/hide option list
127 */
128function collapseOptions (e = null) {
129	trigger.setAttribute('aria-expanded', false);
130	optionsList.classList.remove('is-visible');
131	isExpanded = false;
132	toggleArrowPosition(false);
133
134	if (e) {
135		let currentOption = document.getElementById(trigger.getAttribute('aria-activedescendant'));
136
137		if (currentOption !== undefined && e.key == 'Enter') {
138			let currentOptionIndex = Array.prototype.slice.call(options).indexOf(currentOption);
139
140			options[currentOptionIndex].click();
141		}
142	}
143}
144
145function expandOptions () {
146	trigger.setAttribute('aria-expanded', true);
147	optionsList.classList.add('is-visible');
148	isExpanded = true;
149	toggleArrowPosition(true);
150}
151
152/**
153  Option selection
154 */
155function selectFirstOption () {
156	let firstOption = options[0];
157	selectOption(firstOption);
158}
159
160function selectLastOption () {
161	let lastOption = options[options.length - 1];
162	selectOption(lastOption);
163}
164
165function selectNextOption () {
166	let currentOption = document.getElementById(trigger.getAttribute('aria-activedescendant'));
167
168	if (currentOption !== undefined) {
169		let currentOptionIndex = Array.prototype.slice.call(options).indexOf(currentOption);
170
171		if (currentOptionIndex + 1 < options.length) {
172			let nextOption = options[currentOptionIndex + 1];
173			selectOption(nextOption);
174		}
175	}
176}
177
178function selectPreviousOption () {
179	let currentOption = document.getElementById(trigger.getAttribute('aria-activedescendant'));
180
181	if (currentOption !== undefined) {
182		let currentOptionIndex = Array.prototype.slice.call(options).indexOf(currentOption);
183
184		if (currentOptionIndex - 1 >= 0) {
185			let previousOption = options[currentOptionIndex - 1];
186			selectOption(previousOption);
187		}
188	}
189}
190
191function selectOption (option) {
192	unselectAllOptions();
193	option.setAttribute('aria-selected', true);
194	trigger.setAttribute('aria-activedescendant', option.getAttribute('id'));
195	selectedText.innerHTML = option.innerHTML;
196
197	// Update the hidden field
198	hiddenField.value = option.innerHTML;
199}
200
201function unselectAllOptions () {
202	options.forEach(function (option) {
203		option.removeAttribute('aria-selected');
204	});
205}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.