BibTest.js: Difference between revisions
From Illustrations in German Translations of Mark Twain's Works
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
let | let BIB_DATA = []; | ||
let | let ACTIVE_TAGS = new Set(); | ||
/* ========================= | /* ========================= | ||
| Line 6: | Line 6: | ||
========================= */ | ========================= */ | ||
document.addEventListener("DOMContentLoaded", () => { | document.addEventListener("DOMContentLoaded", async () => { | ||
await loadData(); | |||
render(); | |||
}); | |||
/* ========================= | /* ========================= | ||
LOAD | LOAD DATA FROM WIKI | ||
========================= */ | ========================= */ | ||
function | async function loadData() { | ||
const res = await fetch("BibliographyData"); | |||
BIB_DATA = await res.json(); | |||
console.log("📚 Loaded entries:", BIB_DATA.length); | |||
} | |||
/* ========================= | /* ========================= | ||
TAG EXTRACTION | |||
========================= */ | ========================= */ | ||
function | function getAllTags(data) { | ||
const tagSet = new Set(); | |||
data.forEach(item => { | |||
(item.tags || []).forEach(t => tagSet.add(t)); | |||
}); | |||
return [...tagSet].sort((a, b) => a.localeCompare(b)); | |||
} | |||
/* ========================= | /* ========================= | ||
RENDER TAG BAR | |||
========================= */ | ========================= */ | ||
function renderTags( | function renderTags() { | ||
const container = document.getElementById("tagBar"); | |||
const container = document.getElementById(" | |||
container.innerHTML = ""; | container.innerHTML = ""; | ||
const tags = getAllTags(BIB_DATA); | |||
tags.forEach(tag => { | |||
const el = document.createElement("span"); | const el = document.createElement("span"); | ||
el.className = "tag" | el.className = "tag" + (ACTIVE_TAGS.has(tag) ? " active" : ""); | ||
el.textContent = tag; | |||
el. | |||
el. | el.onclick = () => { | ||
if (ACTIVE_TAGS.has(tag)) { | |||
ACTIVE_TAGS.delete(tag); | |||
} else { | |||
ACTIVE_TAGS.add(tag); | |||
} | |||
render(); | |||
}; | |||
container.appendChild(el); | container.appendChild(el); | ||
}); | }); | ||
} | |||
/* ========================= | /* ========================= | ||
FILTER LOGIC | |||
========================= */ | ========================= */ | ||
function | function filterData(data) { | ||
if (ACTIVE_TAGS.size === 0) return data; | |||
return data.filter(item => | |||
(item.tags || []).some(t => ACTIVE_TAGS.has(t)) | |||
); | |||
} | |||
/* ========================= | /* ========================= | ||
SORT (ALPHABETICAL) | |||
========================= */ | ========================= */ | ||
function | function sortData(data) { | ||
return [...data].sort((a, b) => | |||
(a.authors?.[0]?.family || "Unknown") | |||
.localeCompare(b.authors?.[0]?.family || "Unknown") | |||
); | |||
} | } | ||
/* ========================= | /* ========================= | ||
RENDER LIST | RENDER LIST VIEW | ||
========================= */ | ========================= */ | ||
function renderList(data) { | function renderList(data) { | ||
const container = document.getElementById("listView"); | const container = document.getElementById("listView"); | ||
container.innerHTML = ""; | container.innerHTML = ""; | ||
data.forEach(item => { | data.forEach(item => { | ||
const | const author = item.authors?.[0] | ||
? `${item.authors[0].family}, ${item.authors[0].given || ""}` | |||
: "Unknown Author"; | |||
const tagsHTML = (item.tags || []).map(tag => | |||
< | `<span class="tag small ${ACTIVE_TAGS.has(tag) ? "active" : ""}" | ||
onclick="toggleTag('${tag}')">${tag}</span>` | |||
).join(" "); | |||
const div = document.createElement("div"); | |||
div.className = "bib-entry"; | |||
div.innerHTML = ` | |||
<h3>${author}. <i>${item.title}</i>. ${item.year || ""}</h3> | |||
< | <div class="bib-tags">${tagsHTML}</div> | ||
< | <p class="short-abstract">${item.abstract || ""}</p> | ||
< | ${item.url ? `<a href="${item.url}" target="_blank">Source</a>` : ""} | ||
`; | `; | ||
container.appendChild( | container.appendChild(div); | ||
}); | }); | ||
} | |||
/* ========================= | /* ========================= | ||
TAG TOGGLE FROM LIST | |||
========================= */ | ========================= */ | ||
function | function toggleTag(tag) { | ||
if (ACTIVE_TAGS.has(tag)) { | |||
ACTIVE_TAGS.delete(tag); | |||
} else { | |||
ACTIVE_TAGS.add(tag); | |||
} | |||
render(); | |||
} | |||
/* ========================= | /* ========================= | ||
MAIN RENDER PIPELINE | |||
========================= */ | ========================= */ | ||
function | function render() { | ||
const filtered = filterData(BIB_DATA); | |||
const sorted = sortData(filtered); | |||
renderTags(); | |||
renderList(sorted); | |||
} | } | ||
Revision as of 23:32, 11 May 2026
let BIB_DATA = [];
let ACTIVE_TAGS = new Set();
/* =========================
INIT
========================= */
document.addEventListener("DOMContentLoaded", async () => {
await loadData();
render();
});
/* =========================
LOAD DATA FROM WIKI
========================= */
async function loadData() {
const res = await fetch("BibliographyData");
BIB_DATA = await res.json();
console.log("📚 Loaded entries:", BIB_DATA.length);
}
/* =========================
TAG EXTRACTION
========================= */
function getAllTags(data) {
const tagSet = new Set();
data.forEach(item => {
(item.tags || []).forEach(t => tagSet.add(t));
});
return [...tagSet].sort((a, b) => a.localeCompare(b));
}
/* =========================
RENDER TAG BAR
========================= */
function renderTags() {
const container = document.getElementById("tagBar");
container.innerHTML = "";
const tags = getAllTags(BIB_DATA);
tags.forEach(tag => {
const el = document.createElement("span");
el.className = "tag" + (ACTIVE_TAGS.has(tag) ? " active" : "");
el.textContent = tag;
el.onclick = () => {
if (ACTIVE_TAGS.has(tag)) {
ACTIVE_TAGS.delete(tag);
} else {
ACTIVE_TAGS.add(tag);
}
render();
};
container.appendChild(el);
});
}
/* =========================
FILTER LOGIC
========================= */
function filterData(data) {
if (ACTIVE_TAGS.size === 0) return data;
return data.filter(item =>
(item.tags || []).some(t => ACTIVE_TAGS.has(t))
);
}
/* =========================
SORT (ALPHABETICAL)
========================= */
function sortData(data) {
return [...data].sort((a, b) =>
(a.authors?.[0]?.family || "Unknown")
.localeCompare(b.authors?.[0]?.family || "Unknown")
);
}
/* =========================
RENDER LIST VIEW
========================= */
function renderList(data) {
const container = document.getElementById("listView");
container.innerHTML = "";
data.forEach(item => {
const author = item.authors?.[0]
? `${item.authors[0].family}, ${item.authors[0].given || ""}`
: "Unknown Author";
const tagsHTML = (item.tags || []).map(tag =>
`<span class="tag small ${ACTIVE_TAGS.has(tag) ? "active" : ""}"
onclick="toggleTag('${tag}')">${tag}</span>`
).join(" ");
const div = document.createElement("div");
div.className = "bib-entry";
div.innerHTML = `
<h3>${author}. <i>${item.title}</i>. ${item.year || ""}</h3>
<div class="bib-tags">${tagsHTML}</div>
<p class="short-abstract">${item.abstract || ""}</p>
${item.url ? `<a href="${item.url}" target="_blank">Source</a>` : ""}
`;
container.appendChild(div);
});
}
/* =========================
TAG TOGGLE FROM LIST
========================= */
function toggleTag(tag) {
if (ACTIVE_TAGS.has(tag)) {
ACTIVE_TAGS.delete(tag);
} else {
ACTIVE_TAGS.add(tag);
}
render();
}
/* =========================
MAIN RENDER PIPELINE
========================= */
function render() {
const filtered = filterData(BIB_DATA);
const sorted = sortData(filtered);
renderTags();
renderList(sorted);
}