PageSourceSearch

https://www.sdu.nl/content/mu-plugins/sdu-mcae-gravityforms/assets/jobtitle-autocomplete.js?ver=1790677583

js sdu.nl collected 2026-10-01 12:07:44 UTC 7,738 bytes, 305 lines download raw bytes

1(function(window, document) {
2	'use strict';
3
4	var config = window.sduMcaeGravityFormsJobtitles || {};
5	var options = normalizeOptions(Array.isArray(config.options) ? config.options : []);
6	var activeInput = null;
7
8	function normalizeOptions(rawOptions) {
9		var normalized = [];
10		var seen = {};
11
12		for (var index = 0; index < rawOptions.length; index++) {
13			var option = sanitizeOption(rawOptions[index]);
14			var key = normalizeText(option);
15
16			if (! option || seen[key] || key === 'overig') {
17				continue;
18			}
19
20			seen[key] = true;
21			normalized.push(option);
22		}
23
24		normalized.push('overig');
25
26		return normalized;
27	}
28
29	function sanitizeOption(value) {
30		value = String(value || '').replace(/[\u0000-\u001f\u007f]/g, '').trim();
31
32		return value.length > 100 ? value.substring(0, 100) : value;
33	}
34
35	function normalizeText(value) {
36		value = String(value || '').toLowerCase();
37
38		if (value.normalize) {
39			value = value.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
40		}
41
42		return value.replace(/[^a-z0-9]+/g, '');
43	}
44
45	function initAll(scope) {
46		scope = scope && scope.querySelectorAll ? scope : document;
47
48		var inputs = scope.querySelectorAll('[data-sdu-mcae-jobtitle-field]');
49
50		for (var index = 0; index < inputs.length; index++) {
51			initInput(inputs[index]);
52		}
53	}
54
55	function initInput(input) {
56		if (! input || input.getAttribute('data-sdu-mcae-jobtitle-ready') === '1') {
57			return;
58		}
59
60		input.setAttribute('data-sdu-mcae-jobtitle-ready', '1');
61		input.setAttribute('aria-autocomplete', 'list');
62		input.removeAttribute('list');
63		input.classList.add('sdu-mcae-jobtitle-input');
64
65		var container = input.parentNode;
66		if (container) {
67			container.classList.add('ginput_container_sdu_mcae_jobtitle');
68			container.setAttribute('role', 'combobox');
69			container.setAttribute('aria-expanded', 'false');
70			container.setAttribute('aria-haspopup', 'listbox');
71			if (window.getComputedStyle && window.getComputedStyle(container).position === 'static') {
72				container.style.position = 'relative';
73			}
74		}
75
76		var results = document.createElement('div');
77		results.className = 'sdu-mcae-jobtitle-results';
78		results.hidden = true;
79		results.id = (input.id || 'sdu-mcae-jobtitle') + '_results';
80
81		input.setAttribute('aria-controls', results.id);
82		if (container) {
83			container.setAttribute('aria-owns', results.id);
84		}
85
86		if (input.nextSibling) {
87			input.parentNode.insertBefore(results, input.nextSibling);
88		} else {
89			input.parentNode.appendChild(results);
90		}
91
92		input.addEventListener('focus', function() {
93			activeInput = input;
94			renderResults(input, results);
95		});
96
97		input.addEventListener('input', function() {
98			activeInput = input;
99			renderResults(input, results);
100		});
101
102		input.addEventListener('keydown', function(event) {
103			handleKeydown(event, input, results);
104		});
105
106		results.addEventListener('mousedown', function(event) {
107			event.preventDefault();
108		});
109
110		results.addEventListener('click', function(event) {
111			var option = event.target && event.target.closest ? event.target.closest('[data-sdu-mcae-jobtitle-option]') : null;
112
113			if (! option) {
114				return;
115			}
116
117			selectOption(input, results, option.getAttribute('data-sdu-mcae-jobtitle-option'));
118		});
119
120		input.addEventListener('blur', function() {
121			window.setTimeout(function() {
122				hideResults(input, results);
123			}, 150);
124		});
125	}
126
127	function getMatches(query) {
128		var normalizedQuery = normalizeText(query);
129		var matches = [];
130		var hasOther = false;
131
132		for (var index = 0; index < options.length; index++) {
133			var option = options[index];
134			var normalizedOption = normalizeText(option);
135
136			if (normalizedOption === 'overig') {
137				hasOther = true;
138				continue;
139			}
140
141			if (! normalizedQuery || normalizedOption.indexOf(normalizedQuery) !== -1) {
142				matches.push(option);
143			}
144		}
145
146		if (hasOther) {
147			matches.push('overig');
148		}
149
150		return matches;
151	}
152
153	function renderResults(input, results) {
154		var matches = getMatches(input.value);
155
156		results.innerHTML = '';
157
158		for (var index = 0; index < matches.length; index++) {
159			var option = document.createElement('button');
160			option.type = 'button';
161			option.className = 'sdu-mcae-jobtitle-option';
162			option.setAttribute('role', 'option');
163			option.setAttribute('data-sdu-mcae-jobtitle-option', matches[index]);
164			option.textContent = matches[index];
165			results.appendChild(option);
166		}
167
168		results.hidden = matches.length === 0;
169		if (results.hidden) {
170			results.removeAttribute('role');
171		} else {
172			results.setAttribute('role', 'listbox');
173		}
174		setExpanded(input, results.hidden ? 'false' : 'true');
175
176		var container = input.parentNode;
177		if (container) {
178			if (results.hidden) {
179				container.classList.remove('is-open');
180			} else {
181				container.classList.add('is-open');
182			}
183		}
184
185		setActiveOption(results, 0);
186	}
187
188	function hideResults(input, results) {
189		results.hidden = true;
190		results.removeAttribute('role');
191		setExpanded(input, 'false');
192
193		var container = input.parentNode;
194		if (container) {
195			container.classList.remove('is-open');
196		}
197	}
198
199	function setExpanded(input, expanded) {
200		var container = input.parentNode;
201
202		if (container) {
203			container.setAttribute('aria-expanded', expanded);
204		}
205	}
206
207	function handleKeydown(event, input, results) {
208		if (results.hidden && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
209			renderResults(input, results);
210			event.preventDefault();
211			return;
212		}
213
214		if (results.hidden) {
215			return;
216		}
217
218		var items = getResultItems(results);
219		var activeIndex = getActiveIndex(items);
220
221		if (event.key === 'ArrowDown') {
222			setActiveOption(results, Math.min(activeIndex + 1, items.length - 1));
223			event.preventDefault();
224		} else if (event.key === 'ArrowUp') {
225			setActiveOption(results, Math.max(activeIndex - 1, 0));
226			event.preventDefault();
227		} else if (event.key === 'Enter') {
228			if (items[activeIndex]) {
229				selectOption(input, results, items[activeIndex].getAttribute('data-sdu-mcae-jobtitle-option'));
230				event.preventDefault();
231			}
232		} else if (event.key === 'Escape') {
233			hideResults(input, results);
234			event.preventDefault();
235		}
236	}
237
238	function getResultItems(results) {
239		return results.querySelectorAll('[data-sdu-mcae-jobtitle-option]');
240	}
241
242	function getActiveIndex(items) {
243		for (var index = 0; index < items.length; index++) {
244			if (items[index].getAttribute('aria-selected') === 'true') {
245				return index;
246			}
247		}
248
249		return 0;
250	}
251
252	function setActiveOption(results, index) {
253		var items = getResultItems(results);
254
255		for (var itemIndex = 0; itemIndex < items.length; itemIndex++) {
256			items[itemIndex].setAttribute('aria-selected', itemIndex === index ? 'true' : 'false');
257		}
258	}
259
260	function selectOption(input, results, value) {
261		input.value = value || '';
262		input.dispatchEvent(new Event('input', { bubbles: true }));
263		input.dispatchEvent(new Event('change', { bubbles: true }));
264		hideResults(input, results);
265		input.focus();
266	}
267
268	function bindGravityFormsEvents() {
269		if (window.jQuery) {
270			window.jQuery(document).on('gform_post_render', function() {
271				initAll(document);
272			});
273		}
274
275		document.addEventListener('gform/postRender', function() {
276			initAll(document);
277		});
278	}
279
280	document.addEventListener('click', function(event) {
281		if (! activeInput) {
282			return;
283		}
284
285		var container = activeInput.parentNode;
286
287		if (container && ! container.contains(event.target)) {
288			var results = container.querySelector('.sdu-mcae-jobtitle-results');
289
290			if (results) {
291				hideResults(activeInput, results);
292			}
293		}
294	});
295
296	if (document.readyState === 'loading') {
297		document.addEventListener('DOMContentLoaded', function() {
298			initAll(document);
299			bindGravityFormsEvents();
300		});
301	} else {
302		initAll(document);
303		bindGravityFormsEvents();
304	}
305})(window, document);

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.