Scientific Glossary Builder
Create, categorize, and export definitions for scientific concepts and terms.
Enter your terms and definitions. The **Discipline** field is used for categorization and filtering.
Review the final catalog. Use the filter to display terms by specific scientific discipline.
No terms found matching the selected filter.
`; return; } filteredTerms.forEach((term) => { const cardDiv = document.createElement('div'); cardDiv.className = 'glossary-preview-card shadow-sm'; cardDiv.innerHTML = `${term.discipline.toUpperCase()}
${term.term}
${term.definition}
`; glossaryList.appendChild(cardDiv); }); } // --- Tab Switching --- function sgb_showTab(targetId, element) { tabButtons.forEach(btn => btn.classList.remove('sgb-active')); document.querySelectorAll('.sgb-tab-content').forEach(content => content.classList.remove('active')); if (element) { element.classList.add('sgb-active'); } document.getElementById(targetId).classList.add('active'); if (targetId === 'review') { sgb_renderReview(dom.disciplineFilter.value); } } window.sgb_showTab = sgb_showTab; // --- PDF Export --- function sgb_downloadPDF() { sgb_collectTermData(); const filterDiscipline = dom.disciplineFilter.value; if (typeof jspdf === 'undefined' || typeof jspdf.plugin.autotable === 'undefined') { alert('Error: PDF library not fully loaded for export.'); return; } const filteredTerms = filterDiscipline === 'all' ? SGB_STATE.terms : SGB_STATE.terms.filter(c => c.discipline === filterDiscipline); if (filteredTerms.length === 0) { alert('No terms match the current filter selection for export.'); return; } const { jsPDF } = jspdf; const doc = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); doc.setFont('sans-serif', 'normal'); const margin = 40; const pageWidth = doc.internal.pageSize.getWidth(); let yPos = margin; // --- Header --- doc.setFontSize(18); doc.setFont('sans-serif', 'bold'); doc.setTextColor('#0891b2'); // Cyan-600 doc.text(`Scientific Glossary: ${filterDiscipline === 'all' ? 'All Disciplines' : filterDiscipline}`, pageWidth / 2, yPos, { align: 'center' }); yPos += 30; // --- Glossary Table --- doc.setFontSize(10); const tableHeaders = ['ID', 'Discipline', 'Term / Concept', 'Definition / Explanation']; const tableBody = filteredTerms.map((term, index) => [ (index + 1).toString(), term.discipline, term.term, term.definition ]); doc.autoTable({ head: [tableHeaders], body: tableBody, startY: yPos, theme: 'grid', styles: { fontSize: 9, cellPadding: 6, overflow: 'linebreak' }, headStyles: { fillColor: [8, 145, 178], textColor: 255, fontStyle: 'bold' }, // Cyan-600 alternateRowStyles: { fillColor: [245, 255, 255] }, columnStyles: { 0: { cellWidth: 20, halign: 'center' }, 2: { cellWidth: 120 }, // Term gets space 3: { cellWidth: 280 } // Definition gets space }, didDrawPage: function(data) { yPos = data.cursor.y; } }); doc.save(`Scientific_Glossary_${filterDiscipline.replace(/\s/g, '_')}.pdf`); } // --- Initialization --- document.addEventListener('DOMContentLoaded', () => { // 1. Assign DOM elements dom.disciplineFilter = document.getElementById('discipline-filter'); tabButtons = document.querySelectorAll('.sgb-tab-btn'); // CRITICAL: Assign tabButtons here // 2. Attach listeners document.getElementById('sgb-add-term-btn').addEventListener('click', sgb_addTerm); document.getElementById('matrix-next-btn').addEventListener('click', () => sgb_showTab('review', document.querySelector('.sgb-tab-btn[data-tab="review"]'))); document.getElementById('sgb-download-pdf').addEventListener('click', sgb_downloadPDF); tabButtons.forEach(btn => { btn.addEventListener('click', (e) => sgb_showTab(e.target.dataset.tab, e.target)); }); // Filter listener dom.disciplineFilter.addEventListener('change', () => sgb_renderReview(dom.disciplineFilter.value)); // 3. Initial population sgb_renderMatrixTable(); });