Custom Budget Category Allocation Tool

Define Your Income (e.g., Monthly)

$

Income Sources:

Total Income: $0.00

Create Expense Categories

Your Expense Categories:

No expense categories added yet.

Allocate Your Budget

Total Income to Allocate: $0.00

Define income and categories in Tab 1 first. Then, allocate here.

Budget Allocation Summary

Please define income, categories, and allocations in the previous tabs to view the summary.

Download Budget Plan

Total Allocated Expenses: $${pdfTotalAllocated.toFixed(2)}

Remaining/Unallocated Income: $${pdfRemaining.toFixed(2)}

`; if (allocationPieChartInstance && expenseCategories.filter(c => c.allocatedAmount > 0).length > 0) { try { const chartImg = allocationPieChartInstance.toBase64Image(); pdfHtml += `

Allocation Chart

Budget Allocation Chart
`; } catch(e) { pdfHtml += "

(Chart image not available for PDF)

"; } } pdfHtml += `
`; if(pdfOutputEl) pdfOutputEl.innerHTML = pdfHtml; const opt = { margin: [0.5, 0.5, 0.5, 0.5], filename: `Custom_Budget_Allocation_${new Date().toISOString().slice(0,10)}.pdf`, image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, useCORS: true, logging: false }, jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' } }; if (typeof html2pdf !== 'undefined' && pdfOutputEl) { html2pdf().from(pdfOutputEl).set(opt).save() .catch(err => { console.error("PDF generation failed:", err); alert("PDF generation error."); }); } else { alert("PDF library not loaded or output element not found."); } }); } // --- Tab Navigation --- window.cbat_openTab = function(evt, tabName) { tabs.forEach(tab => { if(tab) tab.style.display = 'none'; }); tabLinks.forEach(link => { if(link) link.classList.remove('active'); }); const activeTabContent = toolContainer.querySelector('#' + tabName); if(activeTabContent) activeTabContent.style.display = 'block'; else { console.error(`Tab content for ${tabName} not found.`); return; } let clickedIndex = -1; if (evt && evt.currentTarget) { evt.currentTarget.classList.add('active'); clickedIndex = tabLinks.indexOf(evt.currentTarget); } else { clickedIndex = tabLinks.findIndex(link => { if (!link) return false; const onclickAttr = link.getAttribute('onclick'); return onclickAttr && onclickAttr.includes(`'${tabName}'`); }); if (clickedIndex !== -1 && tabLinks[clickedIndex]) { tabLinks[clickedIndex].classList.add('active'); } else { if (tabLinks.length > 0 && tabLinks[0]) tabLinks[0].classList.add('active'); clickedIndex = 0; } } currentTabIndex = (clickedIndex !== -1 && clickedIndex < tabs.length) ? clickedIndex : 0; cbat_updateNavButtons(); if (tabName === 'cbat-tab2') { // When going to allocation tab cbat_updateTotalIncome(); // Ensure total income is fresh cbat_renderAllocationTable(); // Re-render table based on current categories } if (tabName === 'cbat-tab3') { // When going to summary tab cbat_calculateAndUpdateAllocations(false); // Ensure all allocations are calculated first cbat_updateFinalSummaryTab(); } } window.cbat_navigateTab = function(direction) { let newIndex = currentTabIndex; if (direction === 'next' && currentTabIndex < tabs.length - 1) newIndex++; else if (direction === 'prev' && currentTabIndex > 0) newIndex--; if (tabLinks[newIndex] && newIndex !== currentTabIndex) tabLinks[newIndex].click(); } function cbat_updateNavButtons() { if(prevButton) prevButton.disabled = currentTabIndex === 0; if(nextButton) nextButton.disabled = currentTabIndex >= tabs.length - 1; } // --- Initialization --- function initializeTool() { loadData(); cbat_renderIncomeSources(); cbat_renderExpenseCategories(); cbat_updateTotalIncome(); // Allocation table will be rendered when tab 2 is opened based on current categories cbat_openTab(null, 'cbat-tab1'); } let cbat_attempts = 0; function checkLibrariesAndInit_cbat() { if (typeof Chart !== 'undefined' && typeof html2pdf !== 'undefined') { initializeTool(); } else if (cbat_attempts < 20) { cbat_attempts++; setTimeout(checkLibrariesAndInit_cbat, 100); } else { alert("Error: Chart.js or html2pdf.js library could not be loaded. Some features may not work."); initializeTool(); // Initialize anyway } } checkLibrariesAndInit_cbat(); })();
Scroll to Top