Experiment Replication Checklist

Experiment Replication Checklist

1. Experiment Metadata
2. Materials & Setup
3. Step-by-Step Methodology

Manage Replication Verification Points

These are the specific requirements a replicator must meet to ensure validity.

Add New Verification Point

Defined Verification Points

Category Type Requirement Actions

Experiment Replication Checklist Draft

Click "Generate Checklist Document" to preview the final document.

Domain: ${data.exp_domain || 'N/A'}

Summary: ${data.exp_summary || 'N/A'}

2. Materials & Methodology

Key Materials:

${data.exp_materials || 'N/A'}

Detailed Methodology:

${data.exp_methodology || 'N/A'}

3. Replication Verification Checklist

Items to verify before attempting replication:

    `; // --- 2. Checklist --- const groupedChecks = verificationChecks.reduce((acc, check) => { acc[check.category] = acc[check.category] || []; acc[check.category].push(check); return acc; }, {}); Object.entries(groupedChecks).forEach(([category, checks]) => { html += `

    ${category} (${checks.filter(c => c.type === 'Required').length} Required)

    `; checks.forEach(check => { const color = check.type === 'Required' ? 'var(--danger-color)' : 'var(--success-color)'; html += `
  • [ ] ${check.type.toUpperCase()}: ${check.point}
  • `; }); }); html += `
`; reviewContent.innerHTML = html; pdfDownloadBtn.disabled = false; switchTab(2); // Switch to review tab }; /** * PDF Generation Function */ const downloadPDF = () => { const data = getMetaFormData(); const jsPDF = window.jspdf.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; } }; const addSectionHeader = (title, color = [0, 0, 0]) => { checkPageBreak(25); doc.setFontSize(16); doc.setFont('Helvetica', 'bold'); doc.setTextColor(color[0], color[1], color[2]); doc.text(title, margin, currentY); currentY += 10; doc.setLineWidth(0.5); doc.setDrawColor(200); doc.line(margin, currentY, pageWidth - margin, currentY); currentY += 12; doc.setTextColor(0); }; const addText = (text, size = 10, style = 'normal', indent = 0) => { doc.setFontSize(size); doc.setFont('Helvetica', style); const lines = doc.splitTextToSize(text, maxWidth - indent); checkPageBreak(lines.length * 9); doc.text(lines, margin + indent, currentY); currentY += (lines.length * 9); }; const addKeyValue = (key, value, isBold = false) => { doc.setFontSize(10); doc.setFont('Helvetica', isBold ? 'bold' : 'normal'); const keyText = `${key}: `; const keyWidth = doc.getStringUnitWidth(keyText) * 10; const valueLines = doc.splitTextToSize(value, maxWidth - keyWidth); doc.text(keyText, margin, currentY); doc.setFont('Helvetica', 'normal'); doc.text(valueLines[0], margin + keyWidth, currentY); currentY += 10; for(let i = 1; i < valueLines.length; i++) { doc.text(valueLines[i], margin + keyWidth, currentY); currentY += 10; } }; // --- PDF Content --- // Title Block doc.setFontSize(20); doc.setFont('Helvetica', 'bold'); doc.setTextColor(0, 128, 128); doc.text(`EXPERIMENT REPLICATION CHECKLIST`, pageWidth / 2, currentY, { align: 'center' }); currentY += 15; // 1. Metadata addSectionHeader("1. Experiment Identification", [0, 128, 128]); addKeyValue("Title", data.exp_title, true); addKeyValue("Researcher", data.lead_researcher, true); addKeyValue("Date Completed", data.exp_date, true); addKeyValue("Domain", data.exp_domain, true); currentY += 5; addText("Summary / Goal:", 10, 'bold'); addText(data.exp_summary, 10, 'normal', 10); currentY += 10; // 2. Materials & Methodology addSectionHeader("2. Materials & Methodology", [0, 128, 128]); addText("Key Materials:", 10, 'bold'); addText(data.exp_materials, 10, 'normal', 10); currentY += 5; addText("Detailed Procedure:", 10, 'bold'); addText(data.exp_methodology, 10, 'normal', 10); currentY += 10; // 3. Verification Checklist addSectionHeader("3. Replication Verification Checklist", [0, 128, 128]); const groupedChecks = verificationChecks.reduce((acc, check) => { acc[check.category] = acc[check.category] || []; acc[check.category].push(check); return acc; }, {}); const allChecks = Object.entries(groupedChecks).flatMap(([category, checks]) => { const header = { content: category, styles: { fontStyle: 'bold', fillColor: [240, 240, 240], textColor: [0] } }; const checkRows = checks.map(check => { const color = check.type === 'Required' ? [244, 67, 54] : [76, 175, 80]; return [`[ ]`, check.type, check.point, color]; }); return [header, ...checkRows]; }); const finalChecks = allChecks.filter(item => typeof item !== 'string'); const checkTableHead = [["", "Type", "Verification Requirement"]]; const checkTableBody = finalChecks.map(item => { if (item.content) { return [{ content: item.content, colSpan: 3, styles: item.styles }]; } else { return [ item[0], // [ ] { content: item[1], styles: { textColor: item[3] } }, // Type item[2] // Requirement ]; } }); doc.autoTable({ startY: currentY, head: checkTableHead, body: checkTableBody, theme: 'grid', headStyles: { fillColor: [74, 78, 105], textColor: [255] }, // Secondary color styles: { fontSize: 9, cellPadding: 5, font: 'Helvetica' }, columnStyles: { 0: { cellWidth: 20, font: 'Courier' }, 1: { cellWidth: 70, fontStyle: 'bold' } } }); currentY = doc.autoTable.previous.finalY + 10; doc.save(`${data.exp_title.replace(/\s/g, '_')}_Replication_Checklist.pdf`); }; // --- Tab Navigation --- const switchTab = (tabIndex) => { tabs.forEach((tab, index) => { tab.classList.toggle('active', index === tabIndex); contents[index].classList.toggle('active', index === tabIndex); }); currentTab = tabIndex; updateNavButtons(); if (tabIndex === 2) { renderReviewSheet(); } } const updateNavButtons = () => { prevBtn.disabled = currentTab === 0; nextBtn.disabled = currentTab === tabs.length - 1; } tabs.forEach((tab, index) => { tab.addEventListener('click', () => { const tabNode = tab.closest('.checklist-tab-button'); const newIndex = Array.from(tabNode.parentNode.children).indexOf(tabNode); switchTab(newIndex); }); }); nextBtn.addEventListener('click', () => { if (currentTab < tabs.length - 1) switchTab(currentTab + 1); }); prevBtn.addEventListener('click', () => { if (currentTab > 0) switchTab(currentTab - 1); }); // --- Event Listeners and Initial Load --- generateReviewBtn.addEventListener('click', renderReviewSheet); pdfDownloadBtn.addEventListener('click', downloadPDF); // Initial Setup setInitialDate(); renderVerificationChecks(); updateNavButtons(); });
Scroll to Top