' : ''; // No HR for the last section in display
return html;
}
function efap_sanitize(str) {
if (!str) return '';
const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' };
return str.replace(/[&<>"']/g, m => map[m]);
}
window.efap_downloadPlanAsPDF = async function() {
if (!efap_jsPDFLoaded || !efap_html2canvasLoaded) {
alert("PDF libraries are still loading. Please wait a moment and try again."); return;
}
if (typeof html2canvas === 'undefined' || typeof jspdf === 'undefined' || typeof jspdf.jsPDF === 'undefined') {
alert("PDF generation library is not available. Please ensure an internet connection.");
console.error("EFAP: jsPDF or html2canvas is undefined."); return;
}
const { jsPDF } = jspdf;
const pdfDoc = new jsPDF({ unit: 'pt', format: 'a4', orientation: 'portrait' });
const pdfContentTarget = document.getElementById('efap-pdfContentContainer');
if (!pdfContentTarget) { console.error("EFAP: PDF content target not found."); return; }
// Populate PDF content sections
document.getElementById('efap-pdfNeeds').innerHTML = efap_getNeedsHTMLForPDF(false);
document.getElementById('efap-pdfResources').innerHTML = efap_getResourcesHTMLForPDF(false);
document.getElementById('efap-pdfDocuments').innerHTML = efap_getDocumentsHTMLForPDF(false);
document.getElementById('efap-pdfActionPlan').innerHTML = efap_getActionPlanHTMLForPDF(false);
pdfContentTarget.style.display = 'block';
try {
const canvas = await html2canvas(pdfContentTarget, { scale: 1.5, useCORS: true, backgroundColor: '#ffffff' }); // Scale up for better quality
pdfContentTarget.style.display = 'none';
const imgData = canvas.toDataURL('image/png');
const imgProps = pdfDoc.getImageProperties(imgData);
const pdfPageWidth = pdfDoc.internal.pageSize.getWidth();
const pdfPageHeight = pdfDoc.internal.pageSize.getHeight();
const margin = 40; // pt
const contentWidth = pdfPageWidth - 2 * margin;
const contentHeight = (imgProps.height * contentWidth) / imgProps.width;
let currentPos = margin;
let remainingImgHeight = contentHeight;
pdfDoc.addImage(imgData, 'PNG', margin, currentPos, contentWidth, contentHeight);
remainingImgHeight -= (pdfPageHeight - 2 * margin);
while (remainingImgHeight > 0) {
currentPos -= (pdfPageHeight - 2 * margin);
pdfDoc.addPage();
pdfDoc.addImage(imgData, 'PNG', margin, currentPos, contentWidth, contentHeight);
remainingImgHeight -= (pdfPageHeight - 2 * margin);
}
pdfDoc.save('Emergency_Financial_Aid_Plan.pdf');
} catch (error) {
console.error("EFAP: Error generating PDF:", error);
alert("An error occurred while generating the PDF. Check console for details.");
pdfContentTarget.style.display = 'none';
}
}
// --- Tab Navigation ---
window.efap_openTab = function(event, tabId) {
if (!tabContents || !tabLinks) { console.error("EFAP: Tab elements not found."); return; }
tabContents.forEach(tc => tc.style.display = 'none');
tabLinks.forEach(tl => tl.classList.remove('efap-active'));
const tabElement = document.getElementById(tabId);
if(tabElement) tabElement.style.display = 'block';
else console.error(`EFAP: Tab element for id ${tabId} not found.`);
if (event && event.currentTarget) event.currentTarget.classList.add('efap-active');
else { // Fallback
const activeBtn = Array.from(tabLinks).find(btn => btn.getAttribute('onclick').includes(tabId));
if(activeBtn) activeBtn.classList.add('efap-active');
}
currentTabIndex = Array.from(tabLinks).findIndex(tl => tl.classList.contains('efap-active'));
efap_updateNavButtons();
if (tabId === 'efapTabReview') efap_compilePlanSummary(); // Update summary when review tab is opened
}
window.efap_navigateTab = function(direction) {
let newIndex = currentTabIndex;
if (direction === 'next' && currentTabIndex < tabLinks.length - 1) newIndex++;
else if (direction === 'prev' && currentTabIndex > 0) newIndex--;
if(tabLinks[newIndex]) tabLinks[newIndex].click();
}
function efap_updateNavButtons() {
if(prevTabButton) prevTabButton.disabled = (currentTabIndex === 0);
if(nextTabButton) nextTabButton.disabled = (currentTabIndex === tabLinks.length - 1);
}
// --- Initial Setup ---
efap_initializeDefaultRows();
if(tabLinks.length > 0) efap_openTab(null, tabContents[0].id);
else console.error("EFAP: No tab links found for initial setup.");
efap_updateNavButtons();
efap_compilePlanSummary(); // Initial summary compilation
// Check for critical elements after DOM is ready
if (!planSummaryOutput || !prevTabButton || !nextTabButton) {
console.error("EFAP: One or more critical UI elements (summary output, nav buttons) are missing.");
}
const downloadButton = document.getElementById('efap-downloadPdfButton');
if (!downloadButton) {
console.error("EFAP: PDF download button not found.");
} else if (!efap_jsPDFLoaded || !efap_html2canvasLoaded) {
downloadButton.disabled = true; // Ensure it's disabled if libs not ready
}
});
