diff options
| -rw-r--r-- | app/views/questionnaire/evaluate.php | 2 | ||||
| -rw-r--r-- | resources/assets/javascripts/lib/questionnaire.js | 37 |
2 files changed, 31 insertions, 8 deletions
diff --git a/app/views/questionnaire/evaluate.php b/app/views/questionnaire/evaluate.php index ed25ba8..f45d90f 100644 --- a/app/views/questionnaire/evaluate.php +++ b/app/views/questionnaire/evaluate.php @@ -76,7 +76,7 @@ if (isset($filtered[$questionnaire->getId()]) && $filtered[$questionnaire->getId <?= \Studip\LinkButton::create(_("Starten"), URLHelper::getURL("dispatch.php/questionnaire/start/".$questionnaire->getId())) ?> <? endif ?> <? if ($questionnaire->resultsVisible()) : ?> - <?= \Studip\LinkButton::create(_('PDF exportieren'), '#', ['onclick' => "STUDIP.Questionnaire.exportEvaluationAsPDF(this.closest('.questionnaire_results')); return false;"]) ?> + <?= \Studip\LinkButton::create(_('PDF exportieren'), '#', ['onclick' => "STUDIP.Questionnaire.exportEvaluationAsPDF(this.closest('.questionnaire_results'), this); return false;"]) ?> <? endif ?> <? if ($questionnaire->isEditable() && $questionnaire->isRunning()) : ?> <?= \Studip\LinkButton::create(_("Beenden"), URLHelper::getURL("dispatch.php/questionnaire/stop/".$questionnaire->getId())) ?> diff --git a/resources/assets/javascripts/lib/questionnaire.js b/resources/assets/javascripts/lib/questionnaire.js index 243d26c..7fc5a4c 100644 --- a/resources/assets/javascripts/lib/questionnaire.js +++ b/resources/assets/javascripts/lib/questionnaire.js @@ -226,7 +226,14 @@ const Questionnaire = { } }, - async exportEvaluationAsPDF(results) { + async exportEvaluationAsPDF(results, button = null) { + let initialButtonText = null; + if (button) { + button.setAttribute('disabled', 'disabled'); + initialButtonText = button.innerText; + button.innerText = $gettext('Export läuft...'); + } + const [html2canvas, jsPDF] = await Promise.all([ import('html2canvas').then(m => m.default), import('jspdf').then(m => m.default), @@ -250,10 +257,16 @@ const Questionnaire = { minute: 'numeric' }).format(new Date()); - const questions = results.querySelectorAll('.question'); + const canvasses = []; + // This may seem awkward but since we cannot use parallel processing via + // Promise.all, we need to wait for each render to finish before + // continuing with the next one. + // Since eslint doesn't like await in a loop, we need to use + // Array.reduce(). + await Array.from(results.querySelectorAll('.question')).reduce( + async (prev, element) => { + await prev; - const canvasses = await Promise.all( - Array.from(questions).map(element => { element.querySelectorAll('svg.ct-chart-bar').forEach(svg => { // Remove xmlns attribute from all children of the svg svg.querySelectorAll('[xmlns]').forEach(node => { @@ -267,13 +280,16 @@ const Questionnaire = { svg.style.height = null; }); - return html2canvas(element, { + const canvas = await html2canvas(element, { allowTaint: false, foreignObjectRendering: false, useCORS: true, logging: false - }) - }) + }); + + canvasses.push(canvas); + }, + Promise.resolve() ); //then all renders are finished: @@ -320,6 +336,13 @@ const Questionnaire = { pdf.save(title + '.pdf'); results.classList.remove('print-view'); + + if (button) { + button.removeAttribute('disabled'); + button.innerText = initialButtonText; + } + + return Promise.resolve(); }, addDelayedInit(el, data, isAjax, isMultiple) { |
