Research Journal Entry Generator

Research Journal Entry Generator

1. Entry Metadata
2. Objective & Setup
3. Findings & Reflection

Click "Generate Entry Draft" to preview your entry.

Add New Entry Template

My Templates

Template Name Action

${content}

`; } }); reviewArea.innerHTML = html; pdfDownloadBtn.disabled = false; switchTab(1); // Switch to review tab } /** * PDF Generation Function * V.A.1, IX: MUST be fully functional and nicely formatted. */ function downloadPDF() { const data = getFormData(); const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'pt', 'a4'); let currentY = 40; const margin = 40; const pageWidth = doc.internal.pageSize.width; const maxWidth = pageWidth - (margin * 2); const checkPageBreak = (spaceNeeded) => { if (currentY + spaceNeeded > doc.internal.pageSize.height - margin) { doc.addPage(); currentY = margin; } }; // Helper to add text and manage Y position const addText = (text, size = 11, style = 'normal', indent = 0) => { doc.setFontSize(size); doc.setFont('Helvetica', style); // Estimate height needed for text wrapping const lines = doc.splitTextToSize(text, maxWidth - indent); checkPageBreak(lines.length * (size * 0.9)); doc.text(lines, margin + indent, currentY); currentY += (lines.length * (size * 1.2)); // Line height multiplier }; // --- PDF Content --- // Title Block doc.setFontSize(20); doc.setFont('Helvetica', 'bold'); doc.setTextColor(0, 0, 0); doc.text("Research Journal Entry", pageWidth / 2, currentY, { align: 'center' }); currentY += 15; // Metadata Table const metaHead = [["Project", "Entry ID", "Date"]]; const metaBody = [[data.entry_project || 'N/A', data.entry_id || 'N/A', data.entry_date || 'N/A']]; doc.autoTable({ startY: currentY, head: metaHead, body: metaBody, theme: 'grid', headStyles: { fillColor: [230, 230, 230], textColor: [0] }, styles: { fontSize: 10, cellPadding: 5, font: 'Helvetica' } }); currentY = doc.autoTable.previous.finalY + 20; // Content Sections data.sections.forEach(section => { const content = data[section.id.replace(/-/g, '_')]; if (content && content.trim() !== '') { // Section Header checkPageBreak(25); doc.setFontSize(14); doc.setFont('Helvetica', 'bold'); doc.setTextColor(0, 123, 255); // Primary color doc.text(section.title.toUpperCase(), margin, currentY); currentY += 10; // Content doc.setTextColor(0); addText(content, 11, 'normal', 5); currentY += 10; // Extra space after content } }); doc.save(`${data.entry_project || 'Research'}_Entry_${data.entry_id || 'Draft'}.pdf`); } // --- Event Listeners --- generateBtn.addEventListener('click', generateEntry); pdfDownloadBtn.addEventListener('click', downloadPDF); // --- Tab Navigation --- function switchTab(tabIndex) { tabs.forEach((tab, index) => { tab.classList.toggle('active', index === tabIndex); contents[index].classList.toggle('active', index === tabIndex); }); currentTab = tabIndex; updateNavButtons(); } function updateNavButtons() { prevBtn.disabled = currentTab === 0; nextBtn.disabled = currentTab === tabs.length - 1; } tabs.forEach((tab, index) => { tab.addEventListener('click', () => switchTab(index)); }); nextBtn.addEventListener('click', () => { if (currentTab < tabs.length - 1) switchTab(currentTab + 1); }); prevBtn.addEventListener('click', () => { if (currentTab > 0) switchTab(currentTab - 1); }); // --- Initial Setup --- setInitialDate(); loadDefaultTemplates(); updateNavButtons(); function loadDefaultTemplates() { // Just loads the hardcoded default templates for initial run renderTemplates(); } });
Scroll to Top