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: | ||
/** | /** | ||
* Bibliography Tag Filter and Sorting | * Bibliography Tag Filter and Sorting | ||
*/ | */ | ||
| Line 15: | Line 14: | ||
if (!tagBar || !bibliography) return; | if (!tagBar || !bibliography) return; | ||
// Sammle alle | // Sammle alle Original-Taggamen aus den Einträgen | ||
const | const allTagsMap = new Map(); // normalized -> original name | ||
document.querySelectorAll('.bib-entry').forEach( | document.querySelectorAll('.bib-entry .tag').forEach(tagEl => { | ||
const | const originalName = tagEl.textContent.trim(); | ||
const normalized = normalizeTag(originalName); | |||
allTagsMap.set(normalized, originalName); | |||
}); | }); | ||
// | // Lösche alte Tags aus tagBar | ||
tagBar.innerHTML = ''; | tagBar.innerHTML = ''; | ||
// Erstelle neue Tags mit Original-Namen | |||
Array.from(allTagsMap.entries()) | |||
.sort((a, b) => a[1].localeCompare(b[1])) // Sortiere nach original name | |||
.forEach(([normalized, originalName]) => { | |||
const span = document.createElement('span'); | |||
span.className = 'tag inactive'; | |||
span.textContent = originalName; // Zeige original name | |||
span.dataset.normalized = normalized; // Speichere normalized für Filterung | |||
span.onclick = () => toggleTag(originalName, span, normalized); | |||
tagBar.appendChild(span); | |||
}); | |||
// Sortiere Einträge alphabetisch | // Sortiere Einträge alphabetisch | ||
| Line 40: | Line 41: | ||
} | } | ||
function toggleTag( | function toggleTag(tagName, element, normalized) { | ||
if (ACTIVE_TAGS.has( | if (ACTIVE_TAGS.has(normalized)) { | ||
ACTIVE_TAGS.delete( | ACTIVE_TAGS.delete(normalized); | ||
element.classList.remove('active'); | element.classList.remove('active'); | ||
element.classList.add('inactive'); | element.classList.add('inactive'); | ||
} else { | } else { | ||
ACTIVE_TAGS.add( | ACTIVE_TAGS.add(normalized); | ||
element.classList.add('active'); | element.classList.add('active'); | ||
element.classList.remove('inactive'); | element.classList.remove('inactive'); | ||
| Line 65: | Line 66: | ||
}); | }); | ||
entries.forEach(entry => container.appendChild(entry)); | entries.forEach(entry => container.appendChild(entry)); | ||
} | |||
function normalizeTag(tag) { | |||
return tag.toLowerCase().replace(/\s+/g, '_').replace(/,/g, '').replace(/\./g, '').replace(/'/g, '').replace(/"/g, ''); | |||
} | } | ||
| Line 79: | Line 83: | ||
} else { | } else { | ||
// AND-Logik: Entry muss ALLE aktiven Tags haben | // AND-Logik: Entry muss ALLE aktiven Tags haben | ||
const hasAllTags = Array.from(ACTIVE_TAGS).every( | const hasAllTags = Array.from(ACTIVE_TAGS).every(activeTag => { | ||
return entryTags.includes(activeTag); | |||
}); | |||
entry.style.display = hasAllTags ? 'block' : 'none'; | entry.style.display = hasAllTags ? 'block' : 'none'; | ||
} | } | ||
Revision as of 01:59, 12 May 2026
/**
* Bibliography Tag Filter and Sorting
*/
(function() {
'use strict';
let ACTIVE_TAGS = new Set();
function init() {
const tagBar = document.getElementById('tagBar');
const bibliography = document.getElementById('listView');
if (!tagBar || !bibliography) return;
// Sammle alle Original-Taggamen aus den Einträgen
const allTagsMap = new Map(); // normalized -> original name
document.querySelectorAll('.bib-entry .tag').forEach(tagEl => {
const originalName = tagEl.textContent.trim();
const normalized = normalizeTag(originalName);
allTagsMap.set(normalized, originalName);
});
// Lösche alte Tags aus tagBar
tagBar.innerHTML = '';
// Erstelle neue Tags mit Original-Namen
Array.from(allTagsMap.entries())
.sort((a, b) => a[1].localeCompare(b[1])) // Sortiere nach original name
.forEach(([normalized, originalName]) => {
const span = document.createElement('span');
span.className = 'tag inactive';
span.textContent = originalName; // Zeige original name
span.dataset.normalized = normalized; // Speichere normalized für Filterung
span.onclick = () => toggleTag(originalName, span, normalized);
tagBar.appendChild(span);
});
// Sortiere Einträge alphabetisch
sortEntries();
}
function toggleTag(tagName, element, normalized) {
if (ACTIVE_TAGS.has(normalized)) {
ACTIVE_TAGS.delete(normalized);
element.classList.remove('active');
element.classList.add('inactive');
} else {
ACTIVE_TAGS.add(normalized);
element.classList.add('active');
element.classList.remove('inactive');
}
filterEntries();
}
function sortEntries() {
const container = document.getElementById('listView');
if (!container) return;
const entries = Array.from(container.querySelectorAll('.bib-entry'));
entries.sort((a, b) => {
const titleA = a.querySelector('h3')?.textContent || '';
const titleB = b.querySelector('h3')?.textContent || '';
return titleA.localeCompare(titleB);
});
entries.forEach(entry => container.appendChild(entry));
}
function normalizeTag(tag) {
return tag.toLowerCase().replace(/\s+/g, '_').replace(/,/g, '').replace(/\./g, '').replace(/'/g, '').replace(/"/g, '');
}
function filterEntries() {
const entries = document.querySelectorAll('.bib-entry');
entries.forEach(entry => {
const entryTags = (entry.getAttribute('data-tags') || '').split(' ').filter(t => t);
if (ACTIVE_TAGS.size === 0) {
entry.style.display = 'block';
} else {
// AND-Logik: Entry muss ALLE aktiven Tags haben
const hasAllTags = Array.from(ACTIVE_TAGS).every(activeTag => {
return entryTags.includes(activeTag);
});
entry.style.display = hasAllTags ? 'block' : 'none';
}
});
}
// Abstract-Button Toggle
document.addEventListener('click', function(e) {
if (e.target.classList.contains('expand-btn')) {
const abstractDiv = e.target.nextElementSibling;
if (abstractDiv && abstractDiv.classList.contains('abstract')) {
abstractDiv.classList.toggle('hidden');
e.target.textContent = abstractDiv.classList.contains('hidden')
? 'Show Abstract'
: 'Hide Abstract';
}
}
});
// Starte wenn DOM bereit
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();