From 8098acd526631c0e69fea0be0ff8ab07240cdec9 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 24 Nov 2020 10:42:37 +0100 Subject: [PATCH] MOBILE-3523 essay: Fix essay text not displayed in review --- src/addon/mod/quiz/pages/player/player.html | 2 +- src/addon/mod/quiz/pages/review/review.html | 2 +- .../essay/component/addon-qtype-essay.html | 81 +++++---- src/addon/qtype/essay/component/essay.ts | 4 +- .../classes/base-question-component.ts | 172 ++++++++++-------- .../question/components/question/question.ts | 4 +- 6 files changed, 144 insertions(+), 121 deletions(-) diff --git a/src/addon/mod/quiz/pages/player/player.html b/src/addon/mod/quiz/pages/player/player.html index 9936714cf..4dfb5fdce 100644 --- a/src/addon/mod/quiz/pages/player/player.html +++ b/src/addon/mod/quiz/pages/player/player.html @@ -58,7 +58,7 @@ - + diff --git a/src/addon/mod/quiz/pages/review/review.html b/src/addon/mod/quiz/pages/review/review.html index e61d8388b..612020eb1 100644 --- a/src/addon/mod/quiz/pages/review/review.html +++ b/src/addon/mod/quiz/pages/review/review.html @@ -77,7 +77,7 @@ - + diff --git a/src/addon/qtype/essay/component/addon-qtype-essay.html b/src/addon/qtype/essay/component/addon-qtype-essay.html index 4876c04e0..0564f70b1 100644 --- a/src/addon/qtype/essay/component/addon-qtype-essay.html +++ b/src/addon/qtype/essay/component/addon-qtype-essay.html @@ -4,49 +4,50 @@

- - - - - - - - - - + + + + + + + + + + + + - - - -

{{ 'core.question.errorembeddedfilesnotsupportedinsite' | translate }}

-
- -

-
+ + + +

{{ 'core.question.errorembeddedfilesnotsupportedinsite' | translate }}

+
+ +

+
+
+ + + + + + + + + +

{{ 'core.question.errorattachmentsnotsupportedinsite' | translate }}

+
+
- - - - - - - - - - -

{{ 'core.question.errorattachmentsnotsupportedinsite' | translate }}

+ + + + +

+ + +
- - - -

-
- - -
- -
-
diff --git a/src/addon/qtype/essay/component/essay.ts b/src/addon/qtype/essay/component/essay.ts index 6fc1dd19c..aee330d49 100644 --- a/src/addon/qtype/essay/component/essay.ts +++ b/src/addon/qtype/essay/component/essay.ts @@ -44,11 +44,11 @@ export class AddonQtypeEssayComponent extends CoreQuestionBaseComponent implemen */ ngOnInit(): void { this.uploadFilesSupported = typeof this.question.responsefileareas != 'undefined'; - this.initEssayComponent(); + this.initEssayComponent(this.review); this.formControl = this.fb.control(this.question.textarea && this.question.textarea.text); - if (this.question.allowsAttachments && this.uploadFilesSupported) { + if (this.question.allowsAttachments && this.uploadFilesSupported && !this.review) { this.loadAttachments(); } } diff --git a/src/core/question/classes/base-question-component.ts b/src/core/question/classes/base-question-component.ts index 92820067c..91a238153 100644 --- a/src/core/question/classes/base-question-component.ts +++ b/src/core/question/classes/base-question-component.ts @@ -32,6 +32,7 @@ export class CoreQuestionBaseComponent { @Input() contextLevel?: string; // The context level. @Input() contextInstanceId?: number; // The instance ID related to the context. @Input() courseId?: number; // The course the question belongs to (if any). + @Input() review?: boolean; // Whether the user is in review mode. @Output() buttonClicked: EventEmitter; // Should emit an event when a behaviour button is clicked. @Output() onAbort: EventEmitter; // Should emit an event if the question should be aborted. @@ -207,99 +208,118 @@ export class CoreQuestionBaseComponent { /** * Initialize a question component of type essay. * + * @param review Whether we're in review mode. * @return Element containing the question HTML, void if the data is not valid. */ - initEssayComponent(): void | HTMLElement { + initEssayComponent(review?: boolean): void | HTMLElement { const questionEl = this.initComponent(); - if (questionEl) { - const textarea = questionEl.querySelector('textarea[name*=_answer]'); - const answerDraftIdInput = questionEl.querySelector('input[name*="_answer:itemid"]'); + if (!questionEl) { + return; + } + + const answerDraftIdInput = questionEl.querySelector('input[name*="_answer:itemid"]'); + + if (this.question.settings) { + this.question.allowsAttachments = this.question.settings.attachments != '0'; + this.question.allowsAnswerFiles = this.question.settings.responseformat == 'editorfilepicker'; + this.question.isMonospaced = this.question.settings.responseformat == 'monospaced'; + this.question.isPlainText = this.question.isMonospaced || this.question.settings.responseformat == 'plain'; + this.question.hasInlineText = this.question.settings.responseformat != 'noinline'; + } else { + this.question.allowsAttachments = !!questionEl.querySelector('div[id*=filemanager]'); + this.question.allowsAnswerFiles = !!answerDraftIdInput; + this.question.isMonospaced = !!questionEl.querySelector('.qtype_essay_monospaced'); + this.question.isPlainText = this.question.isMonospaced || !!questionEl.querySelector('.qtype_essay_plain'); + } + + if (review) { + // Search the answer and the attachments. + this.question.answer = this.domUtils.getContentsOfElement(questionEl, '.qtype_essay_response'); if (this.question.settings) { - this.question.allowsAttachments = this.question.settings.attachments != '0'; - this.question.allowsAnswerFiles = this.question.settings.responseformat == 'editorfilepicker'; - this.question.isMonospaced = this.question.settings.responseformat == 'monospaced'; - this.question.isPlainText = this.question.isMonospaced || this.question.settings.responseformat == 'plain'; + this.question.attachments = Array.from(this.questionHelper.getResponseFileAreaFiles(this.question, 'attachments')); } else { - this.question.allowsAttachments = !!questionEl.querySelector('div[id*=filemanager]'); - this.question.allowsAnswerFiles = !!answerDraftIdInput; - this.question.isMonospaced = !!questionEl.querySelector('.qtype_essay_monospaced'); - this.question.isPlainText = this.question.isMonospaced || !!questionEl.querySelector('.qtype_essay_plain'); - } - - this.question.hasDraftFiles = this.question.allowsAnswerFiles && - this.questionHelper.hasDraftFileUrls(questionEl.innerHTML); - - if (!textarea && !this.question.allowsAttachments) { - // Textarea and filemanager not found, we might be in review. Search the answer and the attachments. - this.question.answer = this.domUtils.getContentsOfElement(questionEl, '.qtype_essay_response'); this.question.attachments = this.questionHelper.getQuestionAttachmentsFromHtml( this.domUtils.getContentsOfElement(questionEl, '.attachments')); - - return questionEl; } - if (textarea) { - const input = questionEl.querySelector('input[type="hidden"][name*=answerformat]'); - let content = this.textUtils.decodeHTML(textarea.innerHTML || ''); + return; + } - if (this.question.hasDraftFiles && this.question.responsefileareas) { - content = this.textUtils.replaceDraftfileUrls(CoreSites.instance.getCurrentSite().getURL(), content, - this.questionHelper.getResponseFileAreaFiles(this.question, 'answer')).text; - } + const textarea = questionEl.querySelector('textarea[name*=_answer]'); - this.question.textarea = { - id: textarea.id, - name: textarea.name, - text: content, - }; + this.question.hasDraftFiles = this.question.allowsAnswerFiles && + this.questionHelper.hasDraftFileUrls(questionEl.innerHTML); - if (input) { - this.question.formatInput = { - name: input.name, - value: input.value - }; - } - } - - if (answerDraftIdInput) { - this.question.answerDraftIdInput = { - name: answerDraftIdInput.name, - value: Number(answerDraftIdInput.value), - }; - } - - if (this.question.allowsAttachments) { - const attachmentsInput = questionEl.querySelector('.attachments input[name*=_attachments]'); - const objectElement = questionEl.querySelector('.attachments object'); - const fileManagerUrl = objectElement && objectElement.data; - - if (attachmentsInput) { - this.question.attachmentsDraftIdInput = { - name: attachmentsInput.name, - value: Number(attachmentsInput.value), - }; - } - - if (this.question.settings) { - this.question.attachmentsMaxFiles = Number(this.question.settings.attachments); - this.question.attachmentsAcceptedTypes = this.question.settings.filetypeslist && - this.question.settings.filetypeslist.join(','); - } - - if (fileManagerUrl) { - const params = CoreUrlUtils.instance.extractUrlParams(fileManagerUrl); - const maxBytes = Number(params.maxbytes); - const areaMaxBytes = Number(params.areamaxbytes); - - this.question.attachmentsMaxBytes = maxBytes === -1 || areaMaxBytes === -1 ? - Math.max(maxBytes, areaMaxBytes) : Math.min(maxBytes, areaMaxBytes); - } - } + if (!textarea && (this.question.hasInlineText || !this.question.allowsAttachments)) { + // Textarea not found, we might be in review. Search the answer and the attachments. + this.question.answer = this.domUtils.getContentsOfElement(questionEl, '.qtype_essay_response'); + this.question.attachments = this.questionHelper.getQuestionAttachmentsFromHtml( + this.domUtils.getContentsOfElement(questionEl, '.attachments')); return questionEl; } + + if (textarea) { + const input = questionEl.querySelector('input[type="hidden"][name*=answerformat]'); + let content = this.textUtils.decodeHTML(textarea.innerHTML || ''); + + if (this.question.hasDraftFiles && this.question.responsefileareas) { + content = this.textUtils.replaceDraftfileUrls(CoreSites.instance.getCurrentSite().getURL(), content, + this.questionHelper.getResponseFileAreaFiles(this.question, 'answer')).text; + } + + this.question.textarea = { + id: textarea.id, + name: textarea.name, + text: content, + }; + + if (input) { + this.question.formatInput = { + name: input.name, + value: input.value + }; + } + } + + if (answerDraftIdInput) { + this.question.answerDraftIdInput = { + name: answerDraftIdInput.name, + value: Number(answerDraftIdInput.value), + }; + } + + if (this.question.allowsAttachments) { + const attachmentsInput = questionEl.querySelector('.attachments input[name*=_attachments]'); + const objectElement = questionEl.querySelector('.attachments object'); + const fileManagerUrl = objectElement && objectElement.data; + + if (attachmentsInput) { + this.question.attachmentsDraftIdInput = { + name: attachmentsInput.name, + value: Number(attachmentsInput.value), + }; + } + + if (this.question.settings) { + this.question.attachmentsMaxFiles = Number(this.question.settings.attachments); + this.question.attachmentsAcceptedTypes = this.question.settings.filetypeslist && + this.question.settings.filetypeslist.join(','); + } + + if (fileManagerUrl) { + const params = CoreUrlUtils.instance.extractUrlParams(fileManagerUrl); + const maxBytes = Number(params.maxbytes); + const areaMaxBytes = Number(params.areamaxbytes); + + this.question.attachmentsMaxBytes = maxBytes === -1 || areaMaxBytes === -1 ? + Math.max(maxBytes, areaMaxBytes) : Math.min(maxBytes, areaMaxBytes); + } + } + + return questionEl; } /** diff --git a/src/core/question/components/question/question.ts b/src/core/question/components/question/question.ts index ce43dbf13..58bea6f95 100644 --- a/src/core/question/components/question/question.ts +++ b/src/core/question/components/question/question.ts @@ -39,6 +39,7 @@ export class CoreQuestionComponent implements OnInit { @Input() contextLevel?: string; // The context level. @Input() contextInstanceId?: number; // The instance ID related to the context. @Input() courseId?: number; // Course ID the question belongs to (if any). It can be used to improve performance with filters. + @Input() review?: boolean; // Whether the user is in review mode. @Output() buttonClicked: EventEmitter; // Will emit an event when a behaviour button is clicked. @Output() onAbort: EventEmitter; // Will emit an event if the question should be aborted. @@ -88,8 +89,9 @@ export class CoreQuestionComponent implements OnInit { contextLevel: this.contextLevel, contextInstanceId: this.contextInstanceId, courseId: this.courseId, + review: this.review, buttonClicked: this.buttonClicked, - onAbort: this.onAbort + onAbort: this.onAbort, }; // Treat the question.