From 35aa70ed66b30d14c668c5471b605d24d9224a7a Mon Sep 17 00:00:00 2001 From: Arpan Gupta Date: Mon, 24 Jul 2023 17:27:20 +0530 Subject: [PATCH] Issue #42 feat: body and answer body in the form of HTML --- .../components/question/question.component.ts | 70 ++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/projects/questionset-editor-library/src/lib/components/question/question.component.ts b/projects/questionset-editor-library/src/lib/components/question/question.component.ts index 56103a3c5..145d80e85 100644 --- a/projects/questionset-editor-library/src/lib/components/question/question.component.ts +++ b/projects/questionset-editor-library/src/lib/components/question/question.component.ts @@ -615,6 +615,29 @@ export class QuestionComponent implements OnInit, AfterViewInit, OnDestroy { } } + //to handle when question type is match + if (this.questionInteractionType === 'match') { + const data = _.get(this.treeNodeData, 'data.metadata'); + if (_.get(this.editorState, 'interactionTypes[0]') === 'match' && + _.isEmpty(this.editorState?.responseDeclaration?.response1?.mapping) && + !_.isUndefined(this.editorService?.editorConfig?.config?.renderTaxonomy) && + _.get(data,'allowScoring') === 'Yes') { + this.toasterService.error(_.get(this.configService, 'labelConfig.messages.error.005')); + this.showFormError = true; + return; + } else { + this.showFormError = false; + } + const rightOptionValid = _.find(this.editorState.options, option => (option.rightOption === undefined || option.rightOption === '' || option.rightOption.length > this.setCharacterLimit)); + const leftOptionValid = _.find(this.editorState.options, option => (option.leftOption === undefined || option.leftOption === '' || option.leftOption.length > this.setCharacterLimit)); + if (rightOptionValid || leftOptionValid || (_.isUndefined(this.editorState.answer) && this.sourcingSettings?.enforceCorrectAnswer)) { + this.showFormError = true; + return; + } else { + this.showFormError = false; + } + } + if (this.questionInteractionType === 'slider') { const min = _.get(this.sliderDatas, 'validation.range.min'); const max = _.get(this.sliderDatas, 'validation.range.max'); @@ -800,7 +823,7 @@ export class QuestionComponent implements OnInit, AfterViewInit, OnDestroy { _.get(treeNodeData,'allowScoring') === 'Yes' ? '' : _.set(metadata,'responseDeclaration.response1.mapping',[]); } - if (this.questionInteractionType != 'choice') { + if (this.questionInteractionType != 'choice' && this.questionInteractionType != 'match') { if (!_.isUndefined(metadata.answer)) { const answerHtml = this.getAnswerHtml(metadata.answer); const finalAnswer = this.getAnswerWrapperHtml(answerHtml); @@ -823,10 +846,17 @@ export class QuestionComponent implements OnInit, AfterViewInit, OnDestroy { }) const finalAnswer = this.getAnswerWrapperHtml(concatenatedAnswers); metadata.answer = finalAnswer; - } else if (this.questionInteractionType != 'default' && this.questionInteractionType != 'choice') { + } else if (this.questionInteractionType != 'default' && this.questionInteractionType != 'choice' && this.questionInteractionType != 'match') { metadata.responseDeclaration = this.getResponseDeclaration(this.questionInteractionType); } + if (this.questionInteractionType === 'match') { + metadata.body = this.getMatchQuestionHtmlBody(this.editorState.question); + const leftOptions = metadata.interactions.response1.optionSet.left; + const rightOptions = metadata.interactions.response1.optionSet.right; + metadata.answer = this.getMatchAnswerContainerHtml(leftOptions, rightOptions); + } + if (!_.isUndefined(this.selectedSolutionType) && !_.isEmpty(this.selectedSolutionType)) { const solutionObj = this.getSolutionObj(this.solutionUUID, this.selectedSolutionType, this.editorState.solutions); metadata.editorState.solutions = [solutionObj]; @@ -856,6 +886,33 @@ export class QuestionComponent implements OnInit, AfterViewInit, OnDestroy { return optionHtml; } + + getMatchAnswerContainerHtml(leftOptions, rightOptions) { + const matchContainerTemplate = '
{leftOptions}{rightOptions}
'; + const leftOptionsHtml = this.getOptionWrapperHtml(leftOptions, 'left'); + const rightOptionsHtml = this.getOptionWrapperHtml(rightOptions, 'right'); + const matchContainer = matchContainerTemplate + .replace('{leftOptions}', leftOptionsHtml) + .replace('{rightOptions}', rightOptionsHtml); + return matchContainer; + } + + getOptionWrapperHtml(options, type) { + const wrapperTemplate = `
{options}
`; + let optionsHtml = ''; + options.forEach((option) => { + const optionHtml = this.getMatchAnswerHtml(option.label, option.value); + optionsHtml = optionsHtml.concat(optionHtml); + }); + const wrapper = wrapperTemplate.replace('{options}', optionsHtml); + return wrapper; + } + getMatchAnswerHtml(label, value) { + const answerHtml = '
{label}
'; + const optionHtml = answerHtml.replace('{label}', label).replace('{value}', value); + return optionHtml; + } + getAnswerWrapperHtml(concatenatedAnswers) { const answerTemplate = '
{answers}
'; const answer = answerTemplate.replace('{answers}', concatenatedAnswers); @@ -899,6 +956,15 @@ export class QuestionComponent implements OnInit, AfterViewInit, OnDestroy { return videoSolutionValue; } + getMatchQuestionHtmlBody(question) { + const matchTemplateConfig = { + // tslint:disable-next-line:max-line-length + matchBody: '
{question}
' + }; + const { matchBody } = matchTemplateConfig; + const questionBody = matchBody.replace('{question}', question); + return questionBody; + } getMcqQuestionHtmlBody(question, templateId) { const mcqTemplateConfig = {