Science Vocabulary Worksheet Generator

Science Vocabulary Worksheet Generator

Worksheet Preview (Editable)

Add terms and definitions using the "Term Configuration" tab and then generate the worksheet here.

Worksheet Information

Add Term & Definition

Current Terms

No terms added yet.

"; return; } vocabulary.forEach(t => { const itemEl = document.createElement("div"); itemEl.className = "svwg-config-list-item"; itemEl.dataset.id = t.id; itemEl.innerHTML = ` ${escapeHTML(t.topic)}: ${escapeHTML(t.term)} - ${escapeHTML(t.def.substring(0, 30))}... `; configTermList.appendChild(itemEl); }); } // --- Dashboard Management --- function renderDashboard(isInitial = true) { // Get config headers dashTitle.value = configTitle.value; dashGrade.value = configGrade.value; // --- Build Dashboard Table HTML --- if (vocabulary.length === 0) { dashboardOutput.innerHTML = `

Add terms and definitions using the "Term Configuration" tab and then generate the worksheet here.

`; return; } dashboardOutput.innerHTML = `
# Vocabulary Term Definition Topic Action
`; // Populate Table Body const tbody = dashboardOutput.querySelector('#svwg-dash-table tbody'); vocabulary.forEach((t, index) => { const tr = document.createElement('tr'); tr.dataset.id = t.id; tr.innerHTML = ` ${index + 1} `; tbody.appendChild(tr); }); setupDashboardListeners(); if (!isInitial) showTab('svwg-tab-dashboard'); } /** * Attaches listeners to the dashboard elements */ function setupDashboardListeners() { const table = dashboardOutput.querySelector('#svwg-dash-table'); if (!table) return; // Event delegation for removal table.addEventListener('click', (e) => { if (e.target.dataset.action === 'remove-term') { const tr = e.target.closest('tr'); vocabulary.splice(vocabulary.findIndex(t => t.id === tr.dataset.id), 1); // Re-render entirely to renumber the questions renderDashboard(false); updateConfigTermDisplay(); } }); // Event delegation for input/change updates table.addEventListener('input', handleDashboardUpdate); table.addEventListener('change', handleDashboardUpdate); } /** * Handles updates made directly to the dashboard table cells */ function handleDashboardUpdate(e) { const target = e.target; const tr = target.closest('tr'); if (!tr) return; const tId = tr.dataset.id; const term = vocabulary.find(t => t.id === tId); if (!term) return; const field = target.dataset.field; if (!field) return; // Update the master state array term[field] = target.value; // Optional: Update config list display immediately updateConfigTermDisplay(); } /** * Generates a PDF report from the dashboard data */ function downloadPDF() { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF.autoTable === 'undefined') { alert("Error: PDF libraries could not be loaded. Please try again."); return; } const table = dashboardOutput.querySelector('#svwg-dash-table'); if (!table) { alert("Please generate the worksheet before downloading."); return; } try { const { jsPDF } = window.jspdf; const worksheetDoc = new jsPDF("p", "pt", "a4"); const answerKeyDoc = new jsPDF("p", "pt", "a4"); const margin = 40; const title = dashTitle.value || "Science Vocabulary Worksheet"; const grade = dashGrade.value || "Level/Subject"; const tableHead = [['#', 'Term', 'Definition/Description', 'Topic']]; const tableBody = []; const tableBodyKey = []; // 1. Extract data from the editable dashboard table Array.from(table.querySelectorAll('tbody tr')).forEach((tr, index) => { const term = tr.querySelector('[data-field="term"]').value; const def = tr.querySelector('[data-field="def"]').value; const topic = tr.querySelector('[data-field="topic"]').value; tableBody.push([ index + 1, term, '________________________________________________________', // Blank space for definition topic ]); tableBodyKey.push([ index + 1, term, def, topic ]); }); // --- Worksheet PDF (Term/Blank Definition) --- worksheetDoc.setFontSize(18); worksheetDoc.setFont(undefined, 'bold'); worksheetDoc.text(title, worksheetDoc.internal.pageSize.getWidth() / 2, margin, { align: 'center' }); worksheetDoc.setFontSize(12); worksheetDoc.setFont(undefined, 'normal'); worksheetDoc.text(`Subject/Level: ${grade}`, margin, margin + 30); worksheetDoc.text('Name: ______________________', worksheetDoc.internal.pageSize.getWidth() - margin, margin + 30, { align: 'right' }); worksheetDoc.autoTable({ startY: margin + 60, head: tableHead, body: tableBody.map(row => [row[0], row[1], row[2], row[3]]), // Use term and blank space theme: 'grid', headStyles: { fillColor: [0, 115, 230], textColor: [255, 255, 255], fontSize: 10 }, styles: { fontSize: 9, cellPadding: 8, overflow: 'linebreak' }, columnStyles: { 0: { cellWidth: 30, halign: 'center' }, 1: { cellWidth: 100 }, 2: { cellWidth: 'auto' }, 3: { cellWidth: 70 } }, margin: { left: margin, right: margin } }); worksheetDoc.save(`${title.replace(/ /g,"_")}_Worksheet.pdf`); // --- Answer Key PDF (Term/Definition) --- answerKeyDoc.setFontSize(18); answerKeyDoc.setFont(undefined, 'bold'); answerKeyDoc.text(`${title} - ANSWER KEY`, answerKeyDoc.internal.pageSize.getWidth() / 2, margin, { align: 'center' }); answerKeyDoc.setFontSize(12); answerKeyDoc.setFont(undefined, 'normal'); answerKeyDoc.text(`Subject/Level: ${grade}`, margin, margin + 30); answerKeyDoc.autoTable({ startY: margin + 50, head: tableHead, body: tableBodyKey, // Use Term and Definition theme: 'grid', headStyles: { fillColor: [40, 167, 69], textColor: [255, 255, 255], fontSize: 10 }, styles: { fontSize: 9, cellPadding: 8, overflow: 'linebreak' }, columnStyles: { 0: { cellWidth: 30, halign: 'center' }, 1: { cellWidth: 100 }, 2: { cellWidth: 'auto' }, 3: { cellWidth: 70 } }, margin: { left: margin, right: margin } }); answerKeyDoc.save(`${title.replace(/ /g,"_")}_AnswerKey.pdf`); } catch (error) { console.error("PDF Generation Error:", error); alert("An error occurred during PDF creation. Please ensure all data fields are filled correctly."); } } /** * Helper to escape HTML */ function escapeHTML(str) { if (!str) return ""; return str .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // --- 4. INITIALIZATION & EVENT LISTENERS --- // Tab Listeners tabButtons.forEach((btn) => { btn.addEventListener("click", () => showTab(btn.dataset.target)); }); navButtons.forEach((btn) => { btn.addEventListener("click", () => showTab(btn.dataset.target)); }); // Config Tab Listeners if (addTermForm) { addTermForm.addEventListener("submit", handleAddTerm); } if (configTermList) { configTermList.addEventListener("click", handleRemoveTerm); } if (generateBtn) { generateBtn.addEventListener("click", () => renderDashboard(false)); } // PDF Button if (pdfBtn) { pdfBtn.addEventListener("click", downloadPDF); } // Initial config list display updateConfigTermDisplay(); // Initial State: Generate dashboard with samples renderDashboard(); showTab("svwg-tab-dashboard"); });
Scroll to Top