From e42ee496f89a830c938a20389a9fc645dfbf96c8 Mon Sep 17 00:00:00 2001 From: Patrick Hoste <pko@odoo.com> Date: Mon, 2 Dec 2019 13:47:53 +0000 Subject: [PATCH] [IMP] website_slides: add comments on answers showed after answering a quiz PURPOSE : A quiz after a course content is a good way to check if the user gets the previous lesson. Despite, the user/student may not understand why his answer was wrong/correct. In this task we'll allow the teacher to add a comment next to the asnwer of a quiz. SPECIFICATION : The quiz creator will now be able to comment the answers to inform the frontend user why his answer is wrong/correct. He will be able to add the comments both in backend and frontend. Task ID : 2072566 PR : #41188 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com> --- addons/website_slides/controllers/main.py | 15 ++++-- .../website_slides/data/slide_slide_demo.xml | 17 ++++++ .../website_slides/models/slide_question.py | 1 + .../static/src/js/slides_course_quiz.js | 53 +++++++++++-------- .../js/slides_course_quiz_question_form.js | 46 +++++++++++++++- .../static/src/scss/website_slides.scss | 26 +++------ .../static/src/xml/slide_quiz.xml | 4 ++ .../static/src/xml/slide_quiz_create.xml | 36 +++++++++---- .../views/slide_question_views.xml | 1 + .../views/website_slides_templates_lesson.xml | 12 +++-- 10 files changed, 149 insertions(+), 62 deletions(-) diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index fbebb1613be5..05d4b455b06b 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -133,7 +133,8 @@ class WebsiteSlides(WebsiteProfile): 'answer_ids': [{ 'id': answer.id, 'text_value': answer.text_value, - 'is_correct': answer.is_correct if slide_completed or request.website.is_publisher() else None + 'is_correct': answer.is_correct if slide_completed or request.website.is_publisher() else None, + 'comment': answer.comment if request.website.is_publisher else None } for answer in question.sudo().answer_ids], } for question in slide.question_ids] } @@ -753,7 +754,8 @@ class WebsiteSlides(WebsiteProfile): 'answer_ids': [(0, 0, { 'sequence': answer['sequence'], 'text_value': answer['text_value'], - 'is_correct': answer['is_correct'] + 'is_correct': answer['is_correct'], + 'comment': answer['comment'] }) for answer in answer_ids] }) return request.env.ref('website_slides.lesson_content_quiz_question').render({ @@ -798,7 +800,6 @@ class WebsiteSlides(WebsiteProfile): return {'error': 'slide_quiz_incomplete'} user_bad_answers = user_answers.filtered(lambda answer: not answer.is_correct) - user_good_answers = user_answers - user_bad_answers self._set_viewed_slide(slide, quiz_attempts_inc=True) quiz_info = self._get_slide_quiz_partner_info(slide, quiz_done=True) @@ -815,8 +816,12 @@ class WebsiteSlides(WebsiteProfile): 'level_up': rank_progress['previous_rank']['lower_bound'] != rank_progress['new_rank']['lower_bound'] }) return { - 'goodAnswers': user_good_answers.ids, - 'badAnswers': user_bad_answers.ids, + 'answers': { + answer.question_id.id: { + 'is_correct': answer.is_correct, + 'comment': answer.comment + } for answer in user_answers + }, 'completed': slide.user_membership_id.sudo().completed, 'channel_completion': slide.channel_id.completion, 'quizKarmaWon': quiz_info['quiz_karma_won'], diff --git a/addons/website_slides/data/slide_slide_demo.xml b/addons/website_slides/data/slide_slide_demo.xml index 3d6ae6aeec0e..d5925fe69f9c 100644 --- a/addons/website_slides/data/slide_slide_demo.xml +++ b/addons/website_slides/data/slide_slide_demo.xml @@ -83,18 +83,21 @@ <field name="text_value">A fruit</field> <field name="sequence">1</field> <field name="is_correct" eval="True"/> + <field name="comment">Correct ! A strawberry is a fruit because it's the product of a tree.</field> <field name="question_id" ref="slide_slide_demo_0_4_question_0"/> </record> <record id="slide_slide_demo_0_4_question_0_1" model="slide.answer"> <field name="text_value">A vegetable</field> <field name="sequence">2</field> <field name="is_correct" eval="False"/> + <field name="comment">Incorrect ! A strawberry is not a vegetable.</field> <field name="question_id" ref="slide_slide_demo_0_4_question_0"/> </record> <record id="slide_slide_demo_0_4_question_0_2" model="slide.answer"> <field name="text_value">A table</field> <field name="sequence">3</field> <field name="is_correct" eval="False"/> + <field name="comment">Incorrect ! A table is a piece of furniture.</field> <field name="question_id" ref="slide_slide_demo_0_4_question_0"/> </record> <record id="slide_slide_demo_0_4_question_1" model="slide.question"> @@ -106,12 +109,14 @@ <field name="text_value">A shovel</field> <field name="sequence">1</field> <field name="is_correct" eval="True"/> + <field name="comment">Correct ! A shovel is the perfect tool to dig a hole.</field> <field name="question_id" ref="slide_slide_demo_0_4_question_1"/> </record> <record id="slide_slide_demo_0_4_question_1_1" model="slide.answer"> <field name="text_value">A spoon</field> <field name="sequence">2</field> <field name="is_correct" eval="False"/> + <field name="comment">Incorrect ! Good luck digging a hole with a spoon...</field> <field name="question_id" ref="slide_slide_demo_0_4_question_1"/> </record> @@ -270,12 +275,14 @@ <field name="text_value">Yes</field> <field name="sequence">1</field> <field name="is_correct" eval="True"/> + <field name="comment">Correct !</field> <field name="question_id" ref="slide_slide_demo_1_4_question_0"/> </record> <record id="slide_slide_demo_1_4_question_0_1" model="slide.answer"> <field name="text_value">No</field> <field name="sequence">2</field> <field name="is_correct" eval="False"/> + <field name="comment">Incorrect !</field> <field name="question_id" ref="slide_slide_demo_1_4_question_0"/> </record> <record id="slide_slide_demo_1_4_question_1" model="slide.question"> @@ -287,18 +294,21 @@ <field name="text_value">Yes</field> <field name="sequence">1</field> <field name="is_correct" eval="True"/> + <field name="comment">Correct ! Congratulations you have time to loose</field> <field name="question_id" ref="slide_slide_demo_1_4_question_1"/> </record> <record id="slide_slide_demo_1_4_question_1_1" model="slide.answer"> <field name="text_value">No</field> <field name="sequence">2</field> <field name="is_correct" eval="False"/> + <field name="comment">Incorrect ! You really should read it.</field> <field name="question_id" ref="slide_slide_demo_1_4_question_1"/> </record> <record id="slide_slide_demo_1_4_question_1_2" model="slide.answer"> <field name="text_value">What was the question again ?</field> <field name="sequence">3</field> <field name="is_correct" eval="False"/> + <field name="comment">Incorrect ! Seriously ?</field> <field name="question_id" ref="slide_slide_demo_1_4_question_1"/> </record> <record id="slide_slide_demo_1_5" model="slide.slide"> @@ -392,12 +402,14 @@ <field name="text_value">Yes</field> <field name="sequence">1</field> <field name="is_correct" eval="False"/> + <field name="comment">Incorrect !</field> <field name="question_id" ref="slide_slide_demo_2_0_question_0"/> </record> <record id="slide_slide_demo_2_0_question_0_1" model="slide.answer"> <field name="text_value">No</field> <field name="sequence">2</field> <field name="is_correct" eval="True"/> + <field name="comment">Correct !</field> <field name="question_id" ref="slide_slide_demo_2_0_question_0"/> </record> <record id="slide_slide_demo_2_0_question_1" model="slide.question"> @@ -409,18 +421,21 @@ <field name="text_value">Yes</field> <field name="sequence">1</field> <field name="is_correct" eval="False"/> + <field name="comment">Incorrect !</field> <field name="question_id" ref="slide_slide_demo_2_0_question_1"/> </record> <record id="slide_slide_demo_2_0_question_1_1" model="slide.answer"> <field name="text_value">No</field> <field name="sequence">2</field> <field name="is_correct" eval="True"/> + <field name="comment">Correct !</field> <field name="question_id" ref="slide_slide_demo_2_0_question_1"/> </record> <record id="slide_slide_demo_2_0_question_1_2" model="slide.answer"> <field name="text_value">And also bananas</field> <field name="sequence">3</field> <field name="is_correct" eval="False"/> + <field name="comment">Incorrect ! of course not ...</field> <field name="question_id" ref="slide_slide_demo_2_0_question_1"/> </record> <record id="slide_slide_demo_2_1" model="slide.slide"> @@ -666,12 +681,14 @@ <field name="text_value">Yes</field> <field name="sequence">1</field> <field name="is_correct" eval="True"/> + <field name="comment">Correct ! You did it !</field> <field name="question_id" ref="slide_slide_demo_5_3_question_0"/> </record> <record id="slide_slide_demo_5_3_question_0_1" model="slide.answer"> <field name="text_value">No</field> <field name="sequence">2</field> <field name="is_correct" eval="False"/> + <field name="comment">Incorrect ! You better think twice...</field> <field name="question_id" ref="slide_slide_demo_5_3_question_0"/> </record> diff --git a/addons/website_slides/models/slide_question.py b/addons/website_slides/models/slide_question.py index a77d28bbcecb..f14fce6f059c 100644 --- a/addons/website_slides/models/slide_question.py +++ b/addons/website_slides/models/slide_question.py @@ -56,3 +56,4 @@ class SlideAnswer(models.Model): question_id = fields.Many2one('slide.question', string="Question", required=True, ondelete='cascade') text_value = fields.Char("Answer", required=True, translate=True) is_correct = fields.Boolean("Is correct answer") + comment = fields.Text("Comment", translate=True, help='This comment will be displayed to the user if he selects this answer') diff --git a/addons/website_slides/static/src/js/slides_course_quiz.js b/addons/website_slides/static/src/js/slides_course_quiz.js index ae0d6236512b..1d3942986cad 100644 --- a/addons/website_slides/static/src/js/slides_course_quiz.js +++ b/addons/website_slides/static/src/js/slides_course_quiz.js @@ -88,8 +88,6 @@ odoo.define('website_slides.quiz', function (require) { start: function() { var self = this; return this._super.apply(this, arguments).then(function () { - self._renderAnswers(); - self._renderAnswersHighlighting(); self._renderValidationInfo(); self._bindSortable(); self._checkLocationHref(); @@ -207,8 +205,9 @@ odoo.define('website_slides.quiz', function (require) { * @private * Decorate the answers according to state */ - _renderAnswers: function () { + _disableAnswers: function () { var self = this; + this.$('.o_wslides_js_lesson_quiz_question').addClass('completed-disabled'); this.$('input[type=radio]').each(function () { $(this).prop('disabled', self.slide.readonly || self.slide.completed); }); @@ -217,29 +216,37 @@ odoo.define('website_slides.quiz', function (require) { /** * @private * Decorate the answer inputs according to the correction + * and adds the answer comment if any */ - _renderAnswersHighlighting: function () { + _renderAnswersHighlightingAndComments: function () { var self = this; - this.$('a.o_wslides_quiz_answer').each(function () { - var $answer = $(this); - var answerId = $answer.data('answerId'); - if (_.contains(self.quiz.goodAnswers, answerId)) { - $answer.removeClass('list-group-item-danger').addClass('list-group-item-success'); - $answer.find('i.fa').addClass('d-none'); - $answer.find('i.fa-check-circle').removeClass('d-none'); - } - else if (_.contains(self.quiz.badAnswers, answerId)) { - $answer.removeClass('list-group-item-success').addClass('list-group-item-danger'); - $answer.find('i.fa').addClass('d-none'); - $answer.find('i.fa-times-circle').removeClass('d-none'); - $answer.find('label input').prop('checked', false); - } - else { - if (!self.slide.completed) { + this.$('.o_wslides_js_lesson_quiz_question').each(function () { + var $question = $(this); + var questionId = $question.data('questionId'); + var isCorrect = self.quiz.answers[questionId].is_correct; + $question.find('a.o_wslides_quiz_answer ').each(function () { + var $answer = $(this); + if ($answer.find('input[type=radio]')[0].checked) { + if (isCorrect) { + $answer.removeClass('list-group-item-danger').addClass('list-group-item-success'); + $answer.find('i.fa').addClass('d-none'); + $answer.find('i.fa-check-circle').removeClass('d-none'); + } else { + $answer.removeClass('list-group-item-success').addClass('list-group-item-danger'); + $answer.find('i.fa').addClass('d-none'); + $answer.find('i.fa-times-circle').removeClass('d-none'); + $answer.find('label input').prop('checked', false); + } + } else { $answer.removeClass('list-group-item-danger list-group-item-success'); $answer.find('i.fa').addClass('d-none'); $answer.find('i.fa-circle').removeClass('d-none'); } + }); + var comment = self.quiz.answers[questionId].comment; + if (comment) { + $question.find('.o_wslides_quiz_answer_info').removeClass('d-none'); + $question.find('.o_wslides_quiz_answer_comment').text(comment); } }); }, @@ -273,6 +280,7 @@ odoo.define('website_slides.quiz', function (require) { } else { self.quiz = _.extend(self.quiz, data); if (data.completed) { + self._disableAnswers(); new SlideQuizFinishModal(self, { quiz: self.quiz, hasNext: self.slide.hasNext, @@ -282,7 +290,7 @@ odoo.define('website_slides.quiz', function (require) { self.trigger_up('slide_completed', {slide: self.slide, completion: data.channel_completion}); } self._hideEditOptions(); - self._renderAnswersHighlighting(); + self._renderAnswersHighlightingAndComments(); self._renderValidationInfo(); } }); @@ -301,7 +309,8 @@ odoo.define('website_slides.quiz', function (require) { answers.push({ 'id': $(this).data('answerId'), 'text_value': $(this).data('text'), - 'is_correct': $(this).data('isCorrect') + 'is_correct': $(this).data('isCorrect'), + 'comment': $(this).data('comment') }); }); return { diff --git a/addons/website_slides/static/src/js/slides_course_quiz_question_form.js b/addons/website_slides/static/src/js/slides_course_quiz_question_form.js index 04f8532eca95..cfa54ebd7dc0 100644 --- a/addons/website_slides/static/src/js/slides_course_quiz_question_form.js +++ b/addons/website_slides/static/src/js/slides_course_quiz_question_form.js @@ -18,8 +18,11 @@ var QuestionFormWidget = publicWidget.Widget.extend({ events: { 'click .o_wslides_js_quiz_validate_question': '_validateQuestion', 'click .o_wslides_js_quiz_cancel_question': '_cancelValidation', + 'click .o_wslides_js_quiz_comment_answer': '_toggleAnswerLineComment', 'click .o_wslides_js_quiz_add_answer': '_addAnswerLine', 'click .o_wslides_js_quiz_remove_answer': '_removeAnswerLine', + 'click .o_wslides_js_quiz_remove_answer_comment': '_removeAnswerLineComment', + 'change .o_wslides_js_quiz_answer_comment > input[type=text]': '_onCommentChanged' }, /** @@ -51,6 +54,34 @@ var QuestionFormWidget = publicWidget.Widget.extend({ // Handlers //-------------------------------------------------------------------------- + /** + * + * @param commentInput + * @private + */ + _onCommentChanged: function (event) { + var input = event.currentTarget; + var commentIcon = $(input).closest('.o_wslides_js_quiz_answer').find('.o_wslides_js_quiz_comment_answer'); + if (input.value.trim() !== '') { + commentIcon.addClass('text-primary'); + commentIcon.removeClass('text-muted'); + } else { + commentIcon.addClass('text-muted'); + commentIcon.removeClass('text-primary'); + } + }, + + /** + * Toggle the input for commenting the answer line which will be + * seen by the frontend user when submitting the quiz. + * @param ev + * @private + */ + _toggleAnswerLineComment: function (ev) { + var commentLine = $(ev.currentTarget).closest('.o_wslides_js_quiz_answer').find('.o_wslides_js_quiz_answer_comment').toggleClass('d-none'); + commentLine.find('input[type=text]').focus(); + }, + /** * Adds a new answer line after the element the user clicked on * e.g. If there is 3 answer lines and the user click on the add @@ -74,6 +105,16 @@ var QuestionFormWidget = publicWidget.Widget.extend({ } }, + /** + * + * @param ev + * @private + */ + _removeAnswerLineComment: function (ev) { + var commentLine = $(ev.currentTarget).closest('.o_wslides_js_quiz_answer_comment').addClass('d-none'); + commentLine.find('input[type=text]').val('').change(); + }, + /** * Handler when user click on 'Save & New', 'Save & Close' * or 'Update' buttons. @@ -165,12 +206,13 @@ var QuestionFormWidget = publicWidget.Widget.extend({ var answers = []; var sequence = 1; $form.find('.o_wslides_js_quiz_answer').each(function () { - var value = $(this).find('input[type=text]').val(); + var value = $(this).find('.o_wslides_js_quiz_answer_value').val(); if (value.trim() !== "") { var answer = { 'sequence': sequence++, 'text_value': value, - 'is_correct': $(this).find('input[type=radio]').prop('checked') === true + 'is_correct': $(this).find('input[type=radio]').prop('checked') === true, + 'comment': $(this).find('.o_wslides_js_quiz_answer_comment > input[type=text]').val().trim() }; answers.push(answer); } diff --git a/addons/website_slides/static/src/scss/website_slides.scss b/addons/website_slides/static/src/scss/website_slides.scss index 474cb8eeec27..9f393d85124f 100644 --- a/addons/website_slides/static/src/scss/website_slides.scss +++ b/addons/website_slides/static/src/scss/website_slides.scss @@ -83,12 +83,14 @@ $o-wslides-fs-side-width: 300px; } } - .o_wsildes_quiz_question_input { - .o_wslides_js_quiz_is_correct > label, - .o_wslides_js_quiz_add_answer, - .o_wslides_js_quiz_remove_answer { + .o_wslides_js_lesson_quiz { + i.o_wslides_js_quiz_icon { cursor: pointer; } + + i.o_wslides_js_quiz_icon:hover { + color: black !important; + } } .o_wslides_js_lesson_quiz_question { @@ -105,20 +107,6 @@ $o-wslides-fs-side-width: 300px; pointer-events: none; } - .o_wslides_js_quiz_edit_question, - .o_wslides_js_quiz_delete_question { - cursor: pointer; - } - - .o_wslides_js_quiz_sequence_handler { - cursor: pointer; - opacity: 0.4; - } - - .o_wslides_js_quiz_sequence_handler:hover { - opacity: 1; - } - &.completed-disabled{ pointer-events: none; } @@ -127,7 +115,7 @@ $o-wslides-fs-side-width: 300px; a.o_wslides_js_quiz_is_correct { color: black; input:checked + i.fa-check-circle-o { - color: $primary; + color: $primary !important; } } diff --git a/addons/website_slides/static/src/xml/slide_quiz.xml b/addons/website_slides/static/src/xml/slide_quiz.xml index 288aa36f8a10..5b1d6e960be1 100644 --- a/addons/website_slides/static/src/xml/slide_quiz.xml +++ b/addons/website_slides/static/src/xml/slide_quiz.xml @@ -28,6 +28,10 @@ <span t-esc="answer.text_value"/> </a> </t> + <div class="o_wslides_quiz_answer_info list-group-item list-group-item-info d-none"> + <i class="fa fa-info-circle"/> + <span class="o_wslides_quiz_answer_comment"/> + </div> </div> </div> <div t-if="!widget.slide.completed" class="o_wslides_js_lesson_quiz_validation border-top pt-3"/> diff --git a/addons/website_slides/static/src/xml/slide_quiz_create.xml b/addons/website_slides/static/src/xml/slide_quiz_create.xml index 0d19371e0b39..ab159543c8f3 100644 --- a/addons/website_slides/static/src/xml/slide_quiz_create.xml +++ b/addons/website_slides/static/src/xml/slide_quiz_create.xml @@ -34,16 +34,32 @@ <t t-name="slide.quiz.answer.line"> <div class="o_wslides_js_quiz_answer row align-items-center mb-1" t-attf-data-answer-id="#{answer ? answer.id : ''}" > - <a class="o_wslides_js_quiz_is_correct col-1 text-center" title="Select one good answer"> - <label class="my-0"> - <input t-if="answer and answer.is_correct" class="d-none" type="radio" name="radio" checked="true" /> - <input t-else="" class="d-none" type="radio" name="radio" /> - <i class="fa fa-lg fa-check-circle-o" /> - </label> - </a> - <input type="text" class="form-control col-9" placeholder="Enter your answer" t-attf-value="#{answer ? answer.text_value : ''}"/> - <i class="o_wslides_js_quiz_add_answer fa fa-lg fa-plus-circle p-2" title="Add another answer" /> - <i class="o_wslides_js_quiz_remove_answer fa fa-lg fa-trash-o p-2" title="Remove this answer" /> + <div class="col offset-1"> + <div class="row align-items-center"> + <div class="input-group col-9 p-0"> + <input type="text" class="o_wslides_js_quiz_answer_value form-control" placeholder="Enter your answer" t-attf-value="#{answer ? answer.text_value : ''}"/> + <div class="input-group-append"> + <div class="input-group-text"> + <a class="o_wslides_js_quiz_is_correct" title="This is the correct answer"> + <label class="my-0"> + <input t-if="answer and answer.is_correct" class="d-none" type="radio" name="radio" checked="true" /> + <input t-else="" class="d-none" type="radio" name="radio" /> + <i class="o_wslides_js_quiz_icon fa fa-lg fa-check-circle-o text-muted" /> + </label> + </a> + </div> + </div> + </div> + <i t-attf-class="o_wslides_js_quiz_icon o_wslides_js_quiz_comment_answer fa fa-lg fa-info-circle p-2 #{answer && answer.comment ? 'text-primary' : 'text-muted'}" title="Add comment on this answer" /> + <i class="o_wslides_js_quiz_icon o_wslides_js_quiz_add_answer fa fa-lg fa-plus-circle p-2 text-muted" title="Add an answer below this one" /> + <i class="o_wslides_js_quiz_icon o_wslides_js_quiz_remove_answer fa fa-lg fa-trash-o p-2 text-muted" title="Remove this answer" /> + </div> + <div class="o_wslides_js_quiz_answer_comment row align-items-center d-none"> + <input type="text" class="form-control col-8 offset-1 mt-1" placeholder="This is the correct answer, congratulation" + t-attf-value="#{answer ? answer.comment : ''}" /> + <i class="o_wslides_js_quiz_icon o_wslides_js_quiz_remove_answer_comment fa fa-lg fa-trash-o p-2 text-muted" title="Remove the answer comment" /> + </div> + </div> </div> </t> diff --git a/addons/website_slides/views/slide_question_views.xml b/addons/website_slides/views/slide_question_views.xml index 5aa44eab86b0..5d4064255bd6 100644 --- a/addons/website_slides/views/slide_question_views.xml +++ b/addons/website_slides/views/slide_question_views.xml @@ -16,6 +16,7 @@ <tree editable="bottom" create="true" delete="true"> <field name="text_value"/> <field name="is_correct"/> + <field name="comment"/> </tree> </field> </sheet> diff --git a/addons/website_slides/views/website_slides_templates_lesson.xml b/addons/website_slides/views/website_slides_templates_lesson.xml index 22e370837a29..71457ea0bb18 100644 --- a/addons/website_slides/views/website_slides_templates_lesson.xml +++ b/addons/website_slides/views/website_slides_templates_lesson.xml @@ -442,21 +442,21 @@ <div class="row d-flex mb-2 mx-0"> <div class="h4"> <small class="text-muted"> - <i class="o_wslides_js_quiz_sequence_handler fa fa-bars mr-1" t-if="slide.channel_id.can_upload and not slide_completed" /> + <i class="o_wslides_js_quiz_icon o_wslides_js_quiz_sequence_handler fa fa-bars mr-1 text-muted" t-if="slide.channel_id.can_upload and not slide_completed" /> <t t-if="question_index != NoneType"><span class="o_wslides_quiz_question_sequence" t-esc="question_index+1"/>.</t> <t t-else=""><span class="o_wslides_quiz_question_sequence" t-esc="question['sequence']"/>.</t> </small> <span t-esc="question['question']"/> </div> <div class="ml-auto o_wslides_js_quiz_edit_del" t-if="slide.channel_id.can_upload and not slide_completed" > - <i class="o_wslides_js_quiz_edit_question fa fa-pencil-square-o p-1"></i> - <i class="o_wslides_js_quiz_delete_question fa fa-trash p-1"></i> + <i class="o_wslides_js_quiz_icon o_wslides_js_quiz_edit_question fa fa-pencil-square-o p-1 text-muted"></i> + <i class="o_wslides_js_quiz_icon o_wslides_js_quiz_delete_question fa fa-trash p-1 text-muted"></i> </div> </div> <div class="list-group"> <t t-foreach="question['answer_ids']" t-as="answer"> <a t-att-data-answer-id="answer['id']" href="#" - t-att-data-text="answer['text_value']" t-att-data-is-correct="answer['is_correct']" + t-att-data-text="answer['text_value']" t-att-data-is-correct="answer['is_correct']" t-att-data-comment="answer['comment']" t-att-class="'o_wslides_quiz_answer list-group-item list-group-item-action d-flex align-items-center %s' % ('list-group-item-success' if slide_completed and answer['is_correct'] else '')"> <label class="my-0 d-flex align-items-center justify-content-center mr-2"> <input type="radio" @@ -471,6 +471,10 @@ <span t-esc="answer['text_value']"/> </a> </t> + <div class="o_wslides_quiz_answer_info list-group-item list-group-item-info d-none"> + <i class="fa fa-info-circle"/> + <span class="o_wslides_quiz_answer_comment"/> + </div> </div> </div> </template> -- GitLab