MediaWiki:BibTest.js
From Illustrations in German Translations of Mark Twain's Works
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
(async function () {
const DATA_URL = "https://illus.twainframe.org/index.php?title=BibliographyData&action=raw&ctype=application/json";
let DATA = [];
let ACTIVE_TAGS = new Set();
// -------------------- INIT --------------------
document.addEventListener("DOMContentLoaded", init);
async function init() {
await loadData();
renderTags();
renderList();
}
// -------------------- LOAD DATA --------------------
async function loadData() {
const res = await fetch(DATA_URL);
DATA = await res.json();
// Alphabetisch nach Titel
DATA.sort((a, b) =>
(a.title || "").localeCompare(b.title || "")
);
}
// -------------------- TAG BAR --------------------
function renderTags() {
const tagBar = document.getElementById("tagBar");
tagBar.innerHTML = "";
const allTags = new Set();
DATA.forEach(item => {
(item.tags || []).forEach(t => allTags.add(t));
});
[...allTags].sort().forEach(tag => {
const el = document.createElement("span");
el.className = "tag inactive";
el.textContent = tag;
el.dataset.tag = tag;
el.onclick = () => toggleTag(tag, el);
tagBar.appendChild(el);
});
}
function toggleTag(tag, el) {
if (ACTIVE_TAGS.has(tag)) {
ACTIVE_TAGS.delete(tag);
el.classList.remove("active");
el.classList.add("inactive");
} else {
ACTIVE_TAGS.add(tag);
el.classList.add("active");
el.classList.remove("inactive");
}
renderList();
}
// -------------------- LIST VIEW --------------------
function renderList() {
const container = document.getElementById("listView");
container.innerHTML = "";
let filtered = DATA;
if (ACTIVE_TAGS.size > 0) {
filtered = DATA.filter(item =>
item.tags && item.tags.some(t => ACTIVE_TAGS.has(t))
);
}
filtered.forEach(item => {
const div = document.createElement("div");
div.className = "bib-entry";
div.innerHTML = buildEntry(item);
container.appendChild(div);
});
}
// -------------------- ENTRY TEMPLATE --------------------
function buildEntry(item) {
const authors = (item.authors || [])
.map(a => {
if (typeof a === "string") return a;
return (a.family || "") + (a.given ? ", " + a.given : "");
})
.join(", ");
const tags = (item.tags || []).map(t =>
`<span class="tag ${ACTIVE_TAGS.has(t) ? 'active' : 'inactive'}"
data-tag="${t}"
onclick="window.__toggleTagFromEntry('${t}')">
${t}
</span>`
).join(" ");
return `
<h3>${authors || "Unknown"}. <i>${item.title || "Untitled"}</i>. ${item.year || ""}</h3>
<div class="bib-tags">${tags}</div>
<p class="short-abstract">${item.abstract || ""}</p>
${item.url ? `<a href="${item.url}" target="_blank">Source</a>` : ""}
`;
}
// -------------------- GLOBAL TAG CLICK (from entries) --------------------
window.__toggleTagFromEntry = function(tag) {
const tagBarTags = document.querySelectorAll("#tagBar .tag");
ACTIVE_TAGS.has(tag)
? ACTIVE_TAGS.delete(tag)
: ACTIVE_TAGS.add(tag);
tagBarTags.forEach(t => {
if (t.dataset.tag === tag) {
t.classList.toggle("active", ACTIVE_TAGS.has(tag));
t.classList.toggle("inactive", !ACTIVE_TAGS.has(tag));
}
});
renderList();
};
})();