let items = {}; document.onreadystatechange = function() { if (document.readyState === 'interactive') { document.getElementById('search').oninput = search; const checkbox = document.getElementById('showhidden') checkbox.oninput = showhidden; fetch('/api/items').then((response) => response.json()).then((data) => { items = data; renderItems(); showhidden({target: checkbox}); }); } } function renderItems() { const container = document.getElementById('results'); const template = document.getElementById('item'); const loading = document.getElementById('loading'); let count = 0; for (const [id, item] of Object.entries(items)) { const clone = template.content.cloneNode(true); const [loc, longloc] = getLocString(items, item); clone.querySelector(".loc").textContent = loc; clone.querySelector(".loc").title = longloc; clone.querySelector(".type").textContent = item.type; clone.querySelector(".id").textContent = item.id; clone.querySelector(".name").textContent = item.name; clone.querySelector(".content").textContent = item.content; clone.querySelector(".note").textContent = item.note; clone.querySelector(".result").id = `item-${id}`; clone.querySelector("a").href = `form.html?id=${encodeURIComponent(id)}`; if (item.hidden) { clone.querySelector(".result").classList.add('hidden') } else { count++; } container.appendChild(clone); }; loading.remove(); updateCounter(count); } function getLocString(items, item) { item.ancestors = []; let next = item; let loop = false; while (next) { if (item.ancestors.includes(next)) { loop = true; if (item.ancestors.length == 1) { item.ancestors.push(null); } break; } item.ancestors.unshift(next); next = items[next.is_in]; } item.ancestors.pop(); let loc = item.ancestors.map(i => i.id).join(' ➜ ') || '⬚'; let longloc = item.ancestors.map(i => `${i.type || ''} ${i.id} ${i.name && `(${i.name})` || ''}`).join(' ➜ ') || 'universe'; if (loop) { loc += ' ↻'; longloc += ' ↻'; } return [loc, `${item.id} is in ${longloc}`]; } function search(e) { const searchAttrs = ['id', 'name', 'type', 'note', 'content']; const query = e.target.value; const regex = new RegExp(query, 'i') let count = 0; for (const elem of document.getElementsByClassName('result')) { const item = items[elem.id.slice(5)]; let found = false; if (query) { for (const a in searchAttrs) { const attr = item[searchAttrs[a]]; if (attr && attr.match(regex)) { found = true; break; } } } else { found = true; } if (found) { elem.classList.remove('filtered'); count++; } else { elem.classList.add('filtered'); } } // Indicate failed search. if (count) { e.target.classList.remove('failed'); } else { e.target.classList.add('failed'); } updateCounter(count); } function updateCounter(count){ const itemcount = document.getElementById('itemcount'); switch(count) { case 0: itemcount.textContent = 'No items found.'; break; case 1: itemcount.textContent = '1 item found.'; break; default: itemcount.textContent = `${count} items found.`; break; } } function showhidden(e){ const container = document.getElementById('results'); if (e.target.checked) { results.classList.add('showhidden'); } else { results.classList.remove('showhidden'); } } function showItem(e) { const item = items[e.target.id.slice(5)]; const ancestors = item.ancestors.concat(item); for (let i = ancestors.length-1; i >= 0; i--) { const ancestor = ancestors[i]; if (ancestor.coords_bl && ancestor.coords_tr) { if (ancestor != item) { const mapnote = `Showing ${ancestor.type || ''} ${ancestor.id} ${ancestor.name && `(${ancestor.name})` || ''}`; document.getElementById('mapnote').textContent = mapnote; } coordsToMap(ancestor.coords_bl, ancestor.coords_tr); break; } } } function hideItem(e) { clearMap(); }