diff --git a/public/js/main.js b/public/js/main.js index 30a49de..2a01c9b 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -207,16 +207,22 @@ function generatePDF(event) { const params = []; if (month) params.push(`month=${month}`); if (year) params.push(`year=${year}`); - + if (params.length > 0) { url += params.join('&') + '&'; } - + + // loadPdfLibraries() is awaited here too (not only when the modal opens) so + // the autotable plugin is guaranteed to be attached before we build the doc. + // Without this, opening the modal and submitting before the plugin script + // finished loading would reach generatePdfDocument() with doc.autoTable + // still undefined ("doc.autoTable is not a function"). Promise.all([ + loadPdfLibraries(), fetch('/api/settings').then(res => res.json()), fetch(url).then(res => res.json()) ]) - .then(([settings, applications]) => { + .then(([_loaded, settings, applications]) => { generatePdfDocument(settings, applications, month, year); hideModal(pdfExportModal); }) @@ -603,7 +609,12 @@ function loadPdfLibraries() { // Check if already loading if (document.getElementById('jspdf-script')) { const checkLoaded = setInterval(() => { - if (window.jspdf && window.jspdf.jsPDF) { + // Wait for the autotable plugin too, not just jsPDF: jsPDF loads + // first (script1), the plugin second (script2). Resolving the + // moment jsPDF exists leaves doc.autoTable undefined if script2 + // has not run yet. + if (window.jspdf && window.jspdf.jsPDF + && typeof window.jspdf.jsPDF.API.autoTable === 'function') { clearInterval(checkLoaded); pdfLibrariesLoaded = true; resolve();