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.