Skip to main content

max / makenotwork

2.9 KB · 74 lines History Blame Raw
1 (function() {
2 var input = document.getElementById('wiz-category');
3 var dropdown = document.getElementById('category-dropdown');
4 if (!input || !dropdown) return;
5
6 // The wait between keystrokes and the search is `Intent::Debounce`, spent
7 // through the shared helper on the core module. It used to be a 200ms
8 // timeout hand-rolled here, which was this typeahead disagreeing with the
9 // docs search for no reason anyone recorded.
10 var SEARCH = 'category-search';
11
12 function showDropdown(items, query) {
13 dropdown.innerHTML = '';
14 items.forEach(function(c) {
15 var div = document.createElement('div');
16 div.className = 'suggestion-item';
17 div.textContent = c.name;
18 div.addEventListener('mousedown', function(e) {
19 e.preventDefault();
20 input.value = c.name;
21 dropdown.classList.remove('open');
22 });
23 dropdown.appendChild(div);
24 });
25 var q = query.trim();
26 if (q.length > 0 && !items.some(function(c) { return c.name.toLowerCase() === q.toLowerCase(); })) {
27 var create = document.createElement('div');
28 create.className = 'suggestion-item suggestion-create';
29 create.textContent = 'Create: ' + q;
30 create.addEventListener('mousedown', function(e) {
31 e.preventDefault();
32 input.value = q;
33 dropdown.classList.remove('open');
34 });
35 dropdown.appendChild(create);
36 }
37 if (dropdown.children.length > 0) {
38 dropdown.classList.add('open');
39 } else {
40 dropdown.classList.remove('open');
41 }
42 }
43
44 input.addEventListener('input', function() {
45 var q = input.value.trim();
46 if (q.length < 1) { window.timing.cancelDebounce(SEARCH); dropdown.classList.remove('open'); return; }
47 window.timing.debounce(SEARCH, function() {
48 fetch('/api/categories/search?q=' + encodeURIComponent(q))
49 .then(function(r) { return r.json(); })
50 .then(function(cats) { showDropdown(cats, q); })
51 .catch(function() {});
52 });
53 });
54
55 input.addEventListener('focus', function() {
56 if (dropdown.children.length > 0) dropdown.classList.add('open');
57 });
58
59 input.addEventListener('blur', function() {
60 // Not a timing intent: the dropdown has to outlive the blur long enough
61 // for a mousedown on one of its rows to land. A race, so it keeps its
62 // own number.
63 setTimeout(function() { dropdown.classList.remove('open'); }, 150);
64 });
65
66 // AI tier toggle
67 document.querySelectorAll('input[name="ai_tier"]').forEach(function(r) {
68 r.addEventListener('change', function() {
69 var group = document.getElementById('ai-disclosure-group');
70 group.classList.toggle('hidden', this.value !== 'assisted');
71 });
72 });
73 })();
74