[FIX] survey: correctly handle "free text sections" in surveys and sessions
We now have a way to display "free text sections" during the survey flow.
(Since 5b74f54396 )
However, the behavior during survey sessions was not optimal:
- Attendees could click on "submit" and it would raise an error
- The section description was not displayed on the host screen
- The section description was never the "current question" of the session of it
was the first item of the question_and_page_ids
This commit fixes all those points to have a nice session flow.
While the host is explaining the section description to the attendees, they get
a waiting message on their screen.
In addition, we fixed the display to avoid showing pages that lack a
description, and we reworked the '_get_pages_or_questions' method to have more
meaningful and readable cases for every layouts.
LINKS
PR #48442
Task 2208574
This commit is contained in:
@@ -13,7 +13,7 @@ from odoo.addons.base.models.ir_ui_view import keep_query
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.http import request, content_disposition
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import format_datetime, format_date
|
||||
from odoo.tools import format_datetime, format_date, is_html_empty
|
||||
|
||||
from odoo.addons.web.controllers.main import Binary
|
||||
|
||||
@@ -266,6 +266,7 @@ class Survey(http.Controller):
|
||||
- previous_page_id : come from the breadcrumb or the back button and force the next questions to load
|
||||
to be the previous ones. """
|
||||
data = {
|
||||
'is_html_empty': is_html_empty,
|
||||
'survey': survey_sudo,
|
||||
'answer': answer_sudo,
|
||||
'breadcrumb_pages': [{
|
||||
|
||||
@@ -10,6 +10,7 @@ from werkzeug.urls import url_join
|
||||
|
||||
from odoo import fields, http
|
||||
from odoo.http import request
|
||||
from odoo.tools import is_html_empty
|
||||
|
||||
|
||||
class UserInputSession(http.Controller):
|
||||
@@ -165,6 +166,7 @@ class UserInputSession(http.Controller):
|
||||
} for line in full_statistics.get('table_data', request.env['survey.user_input.line'])[:100]]
|
||||
|
||||
return {
|
||||
'is_html_empty': is_html_empty,
|
||||
'question_statistics_graph': full_statistics.get('graph_data'),
|
||||
'input_line_values': input_line_values,
|
||||
'answers_validity': json.dumps(answers_validity),
|
||||
|
||||
@@ -9,6 +9,7 @@ import werkzeug
|
||||
from odoo import api, exceptions, fields, models, _
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools import is_html_empty
|
||||
|
||||
|
||||
class Survey(models.Model):
|
||||
@@ -437,12 +438,21 @@ class Survey(models.Model):
|
||||
|
||||
@api.model
|
||||
def _get_pages_or_questions(self, user_input):
|
||||
if self.questions_layout == 'one_page':
|
||||
return self.env['survey.question']
|
||||
elif self.questions_layout == 'page_per_question' and self.questions_selection == 'random':
|
||||
return user_input.predefined_question_ids
|
||||
else:
|
||||
return self.question_and_page_ids if self.questions_layout == 'page_per_question' else self.page_ids
|
||||
""" Returns the pages or questions (depending on the layout) that will be shown
|
||||
to the user taking the survey.
|
||||
In 'page_per_question' layout, we also want to show pages that have a description. """
|
||||
|
||||
result = self.env['survey.question']
|
||||
if self.questions_layout == 'page_per_section':
|
||||
result = self.page_ids
|
||||
elif self.questions_layout == 'page_per_question':
|
||||
if self.questions_selection == 'random':
|
||||
result = user_input.predefined_question_ids
|
||||
else:
|
||||
result = self.question_and_page_ids.filtered(
|
||||
lambda question: not question.is_page or not is_html_empty(question.description))
|
||||
|
||||
return result
|
||||
|
||||
def _get_next_page_or_question(self, user_input, page_or_question_id, go_back=False):
|
||||
"""
|
||||
@@ -580,13 +590,10 @@ class Survey(models.Model):
|
||||
if not self.question_ids or not self.env.user.has_group('survey.group_survey_user'):
|
||||
return
|
||||
|
||||
if not self.session_question_id:
|
||||
next_question = self.question_ids[0]
|
||||
else:
|
||||
most_voted_answers = self._get_session_most_voted_answers()
|
||||
next_question = self._get_next_page_or_question(most_voted_answers, self.session_question_id.id)
|
||||
|
||||
return next_question
|
||||
most_voted_answers = self._get_session_most_voted_answers()
|
||||
return self._get_next_page_or_question(
|
||||
most_voted_answers,
|
||||
self.session_question_id.id if self.session_question_id else 0)
|
||||
|
||||
def _get_session_most_voted_answers(self):
|
||||
""" In sessions of survey that has conditional questions, as the survey is passed at the same time by
|
||||
|
||||
@@ -51,7 +51,7 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({
|
||||
$(document).on('keypress', self._onKeyPress.bind(self));
|
||||
}
|
||||
if (self.options.sessionInProgress &&
|
||||
(self.options.isStartScreen || self.options.hasAnswered)) {
|
||||
(self.options.isStartScreen || self.options.hasAnswered || self.options.isPageDescription)) {
|
||||
self.preventEnterSubmit = true;
|
||||
}
|
||||
self._initSessionManagement();
|
||||
@@ -428,6 +428,12 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({
|
||||
}
|
||||
self._initChoiceItems();
|
||||
self._initTextArea();
|
||||
|
||||
if (this.options.sessionInProgress && this.$('.o_survey_form_content_data').data('isPageDescription')) {
|
||||
// prevent enter submit if we're on a page description (there is nothing to submit)
|
||||
this.preventEnterSubmit = true;
|
||||
}
|
||||
|
||||
this.$('.o_survey_form_content').fadeIn(this.fadeInOutDelay);
|
||||
$("html, body").animate({ scrollTop: 0 }, this.fadeInOutDelay);
|
||||
self._focusOnFirstInput();
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
t-att-data-is-start-screen="answer.state == 'new'"
|
||||
t-att-data-readonly="survey_form_readonly"
|
||||
t-att-data-has-answered="bool(has_answered)"
|
||||
t-att-data-is-page-description="bool(question and question.is_page and not is_html_empty(question.description))"
|
||||
t-att-data-questions-layout="survey.questions_layout"
|
||||
t-att-data-triggered-questions-by-answer="json.dumps(triggered_questions_by_answer)"
|
||||
t-att-data-selected-answers="json.dumps(selected_answers)">
|
||||
@@ -139,6 +140,7 @@
|
||||
<div class="o_survey_form_content_data d-none"
|
||||
t-att-data-question-time-limit-reached="answer.question_time_limit_reached"
|
||||
t-att-data-has-answered="bool(has_answered)"
|
||||
t-att-data-is-page-description="bool(question and question.is_page and not is_html_empty(question.description))"
|
||||
t-att-data-timer="timer_start"
|
||||
t-att-data-time-limit-minutes="time_limit_minutes"/>
|
||||
<t t-if="survey.questions_layout == 'one_page'">
|
||||
@@ -192,6 +194,9 @@
|
||||
<div t-if="answer.question_time_limit_reached and not has_answered" class="font-weight-bold mb128">Sorry, you have not been fast enough.</div>
|
||||
<div t-else="" class="font-weight-bold mb128">We have registered your answer! Please wait for the host to go to the next question.</div>
|
||||
</t>
|
||||
<t t-elif="answer.is_session_answer and question.is_page and not is_html_empty(question.description)">
|
||||
<div class="font-weight-bold mt-5">Pay attention to the host screen until the next question.</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-call="survey.question_container"/>
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@
|
||||
</div>
|
||||
<div t-elif="show_text_answers" class="p-2 pt-4 o_survey_session_text_answers_container">
|
||||
</div>
|
||||
<div t-elif="question.is_page and not is_html_empty(question.description)" class="mb-6 o_survey_manage_fontsize_14" t-field="question.description" />
|
||||
<div t-else="" class="mb-6">
|
||||
<h2 class="font-weight-normal mb-3">
|
||||
<span>Waiting for attendees...</span>
|
||||
|
||||
Reference in New Issue
Block a user