diff --git a/addons/survey/controllers/main.py b/addons/survey/controllers/main.py index 94ced8b83f8230f72c8c3400e4b309ae31960bc8..7b9491d3ed2c18bdf232b3fff3343a029d944f9d 100644 --- a/addons/survey/controllers/main.py +++ b/addons/survey/controllers/main.py @@ -15,6 +15,8 @@ from odoo.http import request, content_disposition from odoo.osv import expression from odoo.tools import format_datetime, format_date +from odoo.addons.web.controllers.main import Binary + _logger = logging.getLogger(__name__) @@ -283,6 +285,24 @@ class Survey(http.Controller): return request.render('survey.survey_page_fill', self._prepare_survey_data(access_data['survey_sudo'], access_data['answer_sudo'], **post)) + @http.route('/survey/get_background_image/<string:survey_token>/<string:answer_token>', type='http', auth="public", website=True, sitemap=False) + def survey_get_background(self, survey_token, answer_token): + access_data = self._get_access_data(survey_token, answer_token, ensure_token=True) + if access_data['validity_code'] is not True: + return werkzeug.exceptions.Forbidden() + + survey_sudo, answer_sudo = access_data['survey_sudo'], access_data['answer_sudo'] + + status, headers, image_base64 = request.env['ir.http'].sudo().binary_content( + model='survey.survey', id=survey_sudo.id, field='background_image', + default_mimetype='image/png') + + return Binary._content_image_get_response(status, headers, image_base64) + + # ---------------------------------------------------------------- + # JSON ROUTES to begin / continue survey (ajax navigation) + Tools + # ---------------------------------------------------------------- + @http.route('/survey/begin/<string:survey_token>/<string:answer_token>', type='json', auth='public', website=True) def survey_begin(self, survey_token, answer_token, **post): """ Route used to start the survey user input and display the first survey page. """ @@ -427,6 +447,7 @@ class Survey(http.Controller): 'review': review, 'survey': survey_sudo, 'answer': answer_sudo, + 'scoring_display_correction': survey_sudo.scoring_type == 'scoring_with_answers' and answer_sudo, 'format_datetime': lambda dt: format_datetime(request.env, dt, dt_format=False), 'format_date': lambda date: format_date(request.env, date) }) @@ -464,23 +485,8 @@ class Survey(http.Controller): return self._generate_report(succeeded_attempt, download=True) - def _generate_report(self, user_input, download=True): - report = request.env.ref('survey.certification_report').sudo().render_qweb_pdf([user_input.id], data={'report_type': 'pdf'})[0] - - report_content_disposition = content_disposition('Certification.pdf') - if not download: - content_split = report_content_disposition.split(';') - content_split[0] = 'inline' - report_content_disposition = ';'.join(content_split) - - return request.make_response(report, headers=[ - ('Content-Type', 'application/pdf'), - ('Content-Length', len(report)), - ('Content-Disposition', report_content_disposition), - ]) - # ------------------------------------------------------------ - # REPORTING SURVEY ROUTES + # REPORTING SURVEY ROUTES AND TOOLS # ------------------------------------------------------------ @http.route('/survey/results/<model("survey.survey"):survey>', type='http', auth='user', website=True) @@ -509,6 +515,21 @@ class Survey(http.Controller): 'search_finished': post.get('finished') == 'true', }) + def _generate_report(self, user_input, download=True): + report = request.env.ref('survey.certification_report').sudo().render_qweb_pdf([user_input.id], data={'report_type': 'pdf'})[0] + + report_content_disposition = content_disposition('Certification.pdf') + if not download: + content_split = report_content_disposition.split(';') + content_split[0] = 'inline' + report_content_disposition = ';'.join(content_split) + + return request.make_response(report, headers=[ + ('Content-Type', 'application/pdf'), + ('Content-Length', len(report)), + ('Content-Disposition', report_content_disposition), + ]) + def _extract_filters_data(self, survey, post): search_filters = [] line_filter_domain, line_choices = [], [] diff --git a/addons/survey/data/survey_demo_certification.xml b/addons/survey/data/survey_demo_certification.xml index 5ea4351605a040f1d3660e6b08f50e41271e2770..e2f438b3c9227eeae4d7c4664dd42ba74d880e0d 100644 --- a/addons/survey/data/survey_demo_certification.xml +++ b/addons/survey/data/survey_demo_certification.xml @@ -26,6 +26,7 @@ <field name="description" type="html"><p>Test your vendor skills!</p></field> <field name="certification_give_badge">True</field> <field name="certification_badge_id" ref="vendor_certification_badge"/> + <field name="background_image" type="base64" file="survey/static/src/img/survey_background_2.jpg"/> </record> <!-- Page 1 --> <record model="survey.question" id="vendor_certification_page_1"> diff --git a/addons/survey/data/survey_demo_quiz.xml b/addons/survey/data/survey_demo_quiz.xml index c4202ef081a8614a7e5584bb377076bc041b5448..7a6f5347d7a688da97bb35c11f6e76eab27cca81 100644 --- a/addons/survey/data/survey_demo_quiz.xml +++ b/addons/survey/data/survey_demo_quiz.xml @@ -12,6 +12,7 @@ <field name="questions_layout">page_per_section</field> <field name="description" type="html"> <p>This small quiz will test your knowledge about our Company. Be prepared !</p></field> + <field name="background_image" type="base64" file="survey/static/src/img/survey_background.jpg"/> </record> <!-- Page 1: general informations --> @@ -279,4 +280,45 @@ <field name="sequence">4</field> <field name="value">Winter</field> </record> + + <!-- Page 4: Feedback - non scored question --> + <record id="survey_demo_quiz_p4" model="survey.question"> + <field name="title">Your feeling</field> + <field name="survey_id" ref="survey_demo_quiz"/> + <field name="sequence">26</field> + <field name="question_type" eval="False"/> + <field name="is_page" eval="True"/> + <field name="description" type="html"> + <p>We may be interested by your input.</p></field> + </record> + <record id="survey_demo_quiz_p4_q1" model="survey.question"> + <field name="survey_id" ref="survey_demo_quiz"/> + <field name="sequence">27</field> + <field name="title">What do you think about this survey ?</field> + <field name="description" type="html"><span>If you don't like us, please try to be as objective as possible.</span></field> + <field name="question_type">simple_choice</field> + <field name="comments_allowed" eval="True"/> + <field name="comment_count_as_answer" eval="True"/> + <field name="constr_mandatory" eval="False"/> + </record> + <record id="survey_demo_quiz_p4_q1_sug1" model="survey.question.answer"> + <field name="question_id" ref="survey_demo_quiz_p4_q1"/> + <field name="sequence">1</field> + <field name="value">Good</field> + </record> + <record id="survey_demo_quiz_p4_q1_sug2" model="survey.question.answer"> + <field name="question_id" ref="survey_demo_quiz_p4_q1"/> + <field name="sequence">2</field> + <field name="value">Not Good, Not Bad</field> + </record> + <record id="survey_demo_quiz_p4_q1_sug3" model="survey.question.answer"> + <field name="question_id" ref="survey_demo_quiz_p4_q1"/> + <field name="sequence">3</field> + <field name="value">Iznogoud</field> + </record> + <record id="survey_demo_quiz_p4_q1_sug4" model="survey.question.answer"> + <field name="question_id" ref="survey_demo_quiz_p4_q1"/> + <field name="sequence">4</field> + <field name="value">I have no idea, I'm a dog!</field> + </record> </data></odoo> diff --git a/addons/survey/models/survey_survey.py b/addons/survey/models/survey_survey.py index f12a34ad5fe4ee9c1582b41c1e1f19522caffffa..6c6d36168a8bcc54cf19680c58ce6655a0a1f15d 100644 --- a/addons/survey/models/survey_survey.py +++ b/addons/survey/models/survey_survey.py @@ -30,6 +30,7 @@ class Survey(models.Model): description_done = fields.Html( "End Message", translate=True, help="This message will be displayed when survey is completed") + background_image = fields.Binary("Background Image") active = fields.Boolean("Active", default=True) state = fields.Selection(selection=[ ('draft', 'Draft'), ('open', 'In Progress'), ('closed', 'Closed') @@ -49,6 +50,10 @@ class Survey(models.Model): ('random', 'Randomized per section')], string="Selection", required=True, default='all', help="If randomized is selected, add the number of random questions next to the section.") + progression_mode = fields.Selection([ + ('percent', 'Percentage'), + ('number', 'Number')], string='Progression Mode', default='percent', + help="If Number is selected, it will display the number of questions answered on the total number of question to answer.") # attendees user_input_ids = fields.One2many('survey.user_input', 'survey_id', string='User responses', readonly=True, groups='survey.group_survey_user') # security / access diff --git a/addons/survey/static/src/img/survey_background.jpg b/addons/survey/static/src/img/survey_background.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ba7c4f0263ae24ade38bff63bea1a501543c741e Binary files /dev/null and b/addons/survey/static/src/img/survey_background.jpg differ diff --git a/addons/survey/static/src/img/survey_background_2.jpg b/addons/survey/static/src/img/survey_background_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b2e076ed2ba4771fede171a6f5cba50edaac712f Binary files /dev/null and b/addons/survey/static/src/img/survey_background_2.jpg differ diff --git a/addons/survey/static/src/js/survey_form.js b/addons/survey/static/src/js/survey_form.js index 02f9e567365c492bbfc61f53a6f2fddc9428c3b5..eb8ac3a95bec696b2e7b4a95c7eb5c42140fb37e 100644 --- a/addons/survey/static/src/js/survey_form.js +++ b/addons/survey/static/src/js/survey_form.js @@ -6,11 +6,13 @@ var publicWidget = require('web.public.widget'); var time = require('web.time'); var core = require('web.core'); var _t = core._t; +var dom = require('web.dom'); publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ selector: '.o_survey_form', events: { 'change .o_survey_form_choice_item': '_onChangeChoiceItem', + 'click .o_survey_matrix_btn': '_onMatrixBtnClick', 'click button[type="submit"]': '_onSubmit', }, custom_events: { @@ -29,6 +31,7 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ this.fadeInOutDelay = 400; return this._super.apply(this, arguments).then(function () { self.options = self.$target.find('form').data(); + // Init fields if (!self.options.isStartScreen) { self._initTimer(); self._initBreadcrumb(); @@ -36,6 +39,13 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ self.$('div.o_survey_form_date').each(function () { self._initDateTimePicker($(this)); }); + self._initChoiceItems(); + self._initTextArea(); + self._focusOnFirstInput(); + // Init event listener + if (!self.options.readonly) { + $(document).on('keypress', self._onKeyPress.bind(self)); + } }); }, @@ -46,6 +56,35 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ // Handlers // ------------------------------------------------------------------------- + _onKeyPress: function (event) { + // If user is answering a textarea, do not handle keyPress + if (this.$("textarea").is(":focus")) { + return; + } + + var self = this; + var keyCode = event.keyCode; + var letter = String.fromCharCode(keyCode).toUpperCase(); + + // Handle Start / Next / Submit + if (keyCode === 13) { // Enter : go Next + event.preventDefault(); + this._submitForm({}); + } else if (self.options.questionsLayout === 'page_per_question' + && letter.match(/[a-z]/i)) { + var $choiceInput = this.$(`input[data-selection-key=${letter}]`); + if ($choiceInput.length === 1) { + if ($choiceInput.attr('type') === 'radio') { + $choiceInput.prop("checked", true).trigger('change'); + } else { + $choiceInput.prop("checked", !$choiceInput.prop("checked")).trigger('change'); + } + // Avoid selection key to be typed into the textbox if 'other' is selected by key + event.preventDefault(); + } + } + }, + /** * Checks, if the 'other' choice is checked. Applies only if the comment count as answer. * If not checked : Clear the comment textarea and disable it @@ -55,7 +94,8 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ * @param {Event} event */ _onChangeChoiceItem: function (event) { - var $choiceItemGroup = $(event.currentTarget).parents('.o_survey_form_choice'); + var $target = $(event.currentTarget); + var $choiceItemGroup = $target.closest('.o_survey_form_choice'); var $otherItem = $choiceItemGroup.find('.o_survey_js_form_other_comment'); var $commentInput = $choiceItemGroup.find('textarea[type="text"]'); @@ -68,6 +108,36 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ $commentInput.val(''); $commentInput.enable(false); } + + var $matrixBtn = $target.closest('.o_survey_matrix_btn'); + if ($target.attr('type') === 'radio') { + if ($matrixBtn.length > 0) { + $matrixBtn.closest('tr').find('td').removeClass('o_survey_selected'); + $matrixBtn.addClass('o_survey_selected'); + } else { + $choiceItemGroup.find('label').removeClass('o_survey_selected'); + $target.closest('label').addClass('o_survey_selected'); + } + } else { // $target.attr('type') === 'checkbox' + if ($matrixBtn.length > 0) { + $matrixBtn.toggleClass('o_survey_selected', !$matrixBtn.hasClass('o_survey_selected')); + } else { + var $label = $target.closest('label'); + $label.toggleClass('o_survey_selected', !$label.hasClass('o_survey_selected')); + } + } + }, + + _onMatrixBtnClick: function (event) { + if (!this.options.readonly) { + var $target = $(event.currentTarget); + var $input = $target.find('input'); + if ($input.attr('type') === 'radio') { + $input.prop("checked", true).trigger('change'); + } else { + $input.prop("checked", !$input.prop("checked")).trigger('change'); + } + } }, _onSubmit: function (event) { @@ -177,8 +247,11 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ } else { this._updateBreadcrumb(); } + self._initChoiceItems(); + self._initTextArea(); this.$('.o_survey_form_content').fadeIn(this.fadeInOutDelay); $("html, body").animate({ scrollTop: 0 }, this.fadeInOutDelay); + self._focusOnFirstInput(); } else if (result && result.fields && result.error === 'validation') { this.$('.o_survey_form_content').fadeIn(0); @@ -321,7 +394,7 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ */ _prepareSubmitValues: function (formData, params) { var self = this; - formData.forEach(function (value, key){ + formData.forEach(function (value, key) { switch (key) { case 'csrf_token': case 'token': @@ -463,6 +536,25 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ // INIT FIELDS TOOLS // ------------------------------------------------------------------------- + /** + * Will allow the textarea to resize on carriage return instead of showing scrollbar. + */ + _initTextArea: function () { + this.$('textarea').each(function () { + dom.autoresize($(this)); + }); + }, + + _initChoiceItems: function () { + this.$("input[type='radio'],input[type='checkbox']").each(function () { + var matrixBtn = $(this).parents('.o_survey_matrix_btn'); + if ($(this).prop("checked")) { + var $target = matrixBtn.length > 0 ? matrixBtn : $(this).closest('label'); + $target.addClass('o_survey_selected'); + } + }); + }, + /** * Will initialize the breadcrumb widget that handles navigation to a previously filled in page. * @@ -573,6 +665,17 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ } }, + /** + * Will automatically focus on the first input to allow the user to complete directly the survey, + * without having to manually get the focus (only if the input has the right type - can write something inside -) + */ + _focusOnFirstInput: function () { + var $inputs = this.$("input[type='text'],input[type='number'],textarea").not('.o_survey_comment'); + if ($inputs.length > 0) { + $inputs.first().focus(); + } + }, + // ERRORS TOOLS // ------------------------------------------------------------------------- @@ -591,10 +694,12 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ var scrollLocation = $target.offset().top; var navbarHeight = $('.o_main_navbar').height(); if (navbarHeight) { - scrollLocation -= navbarHeight; + // In overflow auto, scrollLocation of target can be negative if target is out of screen (up side) + scrollLocation = scrollLocation >= 0 ? scrollLocation - navbarHeight : scrollLocation + navbarHeight; } - $('html, body').animate({ - scrollTop: scrollLocation + var scrollinside = $("#wrapwrap").scrollTop(); + $('#wrapwrap').animate({ + scrollTop: scrollinside + scrollLocation }, 500); }, diff --git a/addons/survey/static/src/js/survey_print.js b/addons/survey/static/src/js/survey_print.js new file mode 100644 index 0000000000000000000000000000000000000000..5e4b8118aecab91950b0def30e3b1592c5279060 --- /dev/null +++ b/addons/survey/static/src/js/survey_print.js @@ -0,0 +1,31 @@ +odoo.define('survey.print', function (require) { +'use strict'; + +var publicWidget = require('web.public.widget'); +var dom = require('web.dom'); + +publicWidget.registry.SurveyPrintWidget = publicWidget.Widget.extend({ + selector: '.o_survey_print', + + //-------------------------------------------------------------------------- + // Widget + //-------------------------------------------------------------------------- + + /** + * @override + */ + start: function () { + var self = this; + return this._super.apply(this, arguments).then(function () { + // Will allow the textarea to resize if any carriage return instead of showing scrollbar. + self.$('textarea').each(function () { + dom.autoresize($(this)); + }); + }); + }, + +}); + +return publicWidget.registry.SurveyPrintWidget; + +}); diff --git a/addons/survey/static/src/scss/survey_form.scss b/addons/survey/static/src/scss/survey_form.scss new file mode 100644 index 0000000000000000000000000000000000000000..7c54bed67388af42a2cc4b3e476966b6aa02379d --- /dev/null +++ b/addons/survey/static/src/scss/survey_form.scss @@ -0,0 +1,193 @@ +.o_survey_wrap { + min-height: 100%; +} + +/********************************************************** + Common Style + **********************************************************/ + +.o_survey_form, .o_survey_print { + .o_survey_question_error { + height: 0px; + transition: height .5s ease; + line-height: 4rem; + &.slide_in { + height: 4rem; + } + } + + .o_survey_question_text_box, + .o_survey_question_date, + .o_survey_question_datetime, + .o_survey_question_numerical_box { + border: 0px; + border-bottom: 2px solid $o-brand-primary; + &:disabled { + color: black !important; + border-color: $gray-600; + border-bottom: 2px solid $gray-600; + } + &:focus { + border-color: $o-brand-primary; + } + } + + .o_survey_form_date .input-group-append { + right: 0; + .input-group-text i { + font-size: large; + } + } + + .o_survey_choice_btn { + transition: background-color 0.3s ease; + flex: 1 0 300px; + + span { + line-height: 25px; + } + i { + top: 0px; + font-size: large; + &.fa-check-circle,&.fa-check-square { + display: none; + } + } + + &.o_survey_selected i { + display: none; + &.fa-check-circle,&.fa-check-square { + display: inline; + } + } + } + + .o_survey_question_matrix { + td { + min-width: 100px; + i { + font-size: 22px; + display: none; + &.o_survey_matrix_empty_checkbox { + display: inline; + } + } + .o_survey_choice_key > span > span { + top: 0px; + } + + &.o_survey_selected { + i { + display: inline; + &.o_survey_matrix_empty_checkbox { + display: none; + } + } + } + } + } +} + +/********************************************************** + Form Specific Style + **********************************************************/ + +.o_survey_form { + min-height: 100%; + + .o_survey_choice_btn { + background-color: rgba($o-brand-primary, 0.5); + border: 2px solid $o-brand-primary; + cursor: pointer; + + &.o_survey_selected { + background-color: $o-brand-primary; + } + + &:hover { + background-color: rgba($o-brand-primary, 0.8); + .o_survey_choice_key span.o_survey_key { + opacity: 1; + } + } + } + + .o_survey_choice_key { + width: 25px; + height: 25px; + border: 2px solid $o-brand-primary; + span { + font-size: smaller; + top: -2px; + &.o_survey_key { + width: inherit; + right: 10px; + border: 2px solid $o-brand-primary; + border-right: 0px; + height: 25px; + opacity: 0; + transition: opacity 0.4s ease; + white-space: nowrap; + } + } + } + + .o_survey_question_matrix { + th { + background-color: $o-brand-primary; + } + td { + background-color: rgba($o-brand-primary, 0.2); + + &:hover { + background-color: rgba($o-brand-primary, 0.5); + cursor: pointer; + .o_survey_choice_key span.o_survey_key { + opacity: 1; + } + } + } + } + + .o_survey_progress { + height:0.5em; + } +} + +/********************************************************** + Print Specific Style + **********************************************************/ + +.o_survey_print { + .o_survey_choice_btn { + background-color: $gray-500; + border-color: transparent; + cursor: default; + + &.bg-success, &.bg-danger { + opacity: 0.6; + } + &.o_survey_selected { + background-color: $gray-600; + opacity: 1; + } + i.fa-square, i.fa-circle { + display: none; + } + } + .o_survey_question_matrix { + th { + /* important needed to force override bg-primary set on th in the template */ + background-color: $gray-600 !important; + } + td { + background-color: $gray-200; + &:hover { + cursor: default; + } + } + i.fa-check-square, i.fa-check-circle, i.o_survey_matrix_empty_checkbox { + color: $gray-600; + } + } +} diff --git a/addons/survey/static/src/scss/survey_templates.scss b/addons/survey/static/src/scss/survey_templates.scss deleted file mode 100644 index 4a53c4ac0afd05eb8d87aba1e340effc13dadae2..0000000000000000000000000000000000000000 --- a/addons/survey/static/src/scss/survey_templates.scss +++ /dev/null @@ -1,28 +0,0 @@ -.o_survey_header { - padding-top: 15px; - padding-bottom: 25px; -} - -.o_survey_title { - padding-bottom: 15px; -} - -.js_question-wrapper { - padding-bottom: 25px; -} - -.o_survey_breadcrumb_container { - min-height: 3rem; -} - -.o_survey_question_error { - overflow: hidden; - height: 0px; - border: 0px; - padding: 0rem 0.75rem; - transition: height .5s ease; - line-height: 4rem; - &.slide_in { - height: 4rem; - } -} diff --git a/addons/survey/static/src/xml/survey_breadcrumb_templates.xml b/addons/survey/static/src/xml/survey_breadcrumb_templates.xml index 8893d7118159e537c9ff5ad8204a840516b2614f..1df7f54a88a881fbaba3558cba87b22d235b81c0 100644 --- a/addons/survey/static/src/xml/survey_breadcrumb_templates.xml +++ b/addons/survey/static/src/xml/survey_breadcrumb_templates.xml @@ -2,10 +2,11 @@ <templates id="template" xml:space="preserve"> <t t-name="survey.survey_breadcrumb_template"> - <ol class="breadcrumb justify-content-end"> + <ol class="breadcrumb justify-content-end bg-transparent"> <t t-set="canGoBack" t-value="widget.canGoBack"/> <t t-foreach="widget.pages" t-as="page"> - <li t-att-class="'breadcrumb-item' + (page.id === widget.currentPageId ? ' active' : '')" + <t t-set="isActivePage" t-value="page.id === widget.currentPageId"/> + <li t-att-class="'breadcrumb-item' + (isActivePage ? ' active font-weight-bold' : '')" t-att-data-page-id="page.id" t-att-data-page-title="page.title"> <t t-if="widget.currentPageId === page.id"> @@ -14,12 +15,13 @@ <t t-set="canGoBack" t-value="false" /> </t> <t t-if="canGoBack"> - <a href="#"> + <a class="text-primary" href="#"> <span t-esc="page.title" /> </a> </t> <t t-else=""> - <span t-esc="page.title" /> + <span t-att-class="(isActivePage ? 'text-black' : 'text-muted')" + t-esc="page.title" /> </t> </li> </t> diff --git a/addons/survey/static/tests/tours/certification_failure.js b/addons/survey/static/tests/tours/certification_failure.js index fa6849e63e976d50a41baaafa87664d119afab56..2094ee1925fd67da82226783e876253e1db88fc1 100644 --- a/addons/survey/static/tests/tours/certification_failure.js +++ b/addons/survey/static/tests/tours/certification_failure.js @@ -24,43 +24,43 @@ var failSteps = [{ // Page-1 trigger: 'button.btn.btn-primary.btn-lg:contains("Start Certification")', }, { // Question: Do we sell Acoustic Bloc Screens? content: "Selecting answer 'No'", - trigger: 'div.js_question-wrapper:contains("Do we sell Acoustic Bloc Screens") label:contains("No") input', + trigger: 'div.js_question-wrapper:contains("Do we sell Acoustic Bloc Screens") label:contains("No")', }, { // Question: Select all the existing products content: "Ticking answer 'Fanta'", - trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Fanta") input' + trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Fanta")' }, { content: "Ticking answer 'Drawer'", - trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Drawer") input' + trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Drawer")' }, { content: "Ticking answer 'Conference chair'", - trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Conference chair") input' + trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Conference chair")' }, { // Question: Select all the available customizations for our Customizable Desk content: "Ticking answer 'Color'", - trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Color") input' + trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Color")' }, { content: "Ticking answer 'Height'", - trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Height") input' + trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Height")' }, { // Question: How many versions of the Corner Desk do we have? content: "Selecting answer '2'", - trigger: 'div.js_question-wrapper:contains("How many versions of the Corner Desk do we have") label:contains("2") input', + trigger: 'div.js_question-wrapper:contains("How many versions of the Corner Desk do we have") label:contains("2")', }, { // Question: Do you think we have missing products in our catalog? (not rated) content: "Missing products", trigger: 'div.js_question-wrapper:contains("Do you think we have missing products in our catalog") textarea', run: "text I don't know products enough to be able to answer that", }, { // Page-2 Question: How much do we sell our Cable Management Box? content: "Selecting answer '80$'", - trigger: 'div.js_question-wrapper:contains("How much do we sell our Cable Management Box") label:contains("80$") input', + trigger: 'div.js_question-wrapper:contains("How much do we sell our Cable Management Box") label:contains("80$")', }, { // Question: Select all the the products that sell for 100$ or more content: "Ticking answer 'Corner Desk Right Sit'", - trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Corner Desk Right Sit") input' + trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Corner Desk Right Sit")' }, { content: "Ticking answer 'Desk Combination'", - trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Desk Combination") input' + trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Desk Combination")' }, { content: "Ticking answer 'Office Chair Black'", - trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Office Chair Black") input' + trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Office Chair Black")' }, { // Question: What do you think about our prices (not rated)? - trigger: 'div.js_question-wrapper:contains("What do you think about our prices") label:contains("Correctly priced") input', + trigger: 'div.js_question-wrapper:contains("What do you think about our prices") label:contains("Correctly priced")', }, { content: "Finish Survey", trigger: 'button[type="submit"]', diff --git a/addons/survey/static/tests/tours/certification_success.js b/addons/survey/static/tests/tours/certification_success.js index 584c357f7ba3400e7f2fb9f4b6d0740ea45f2ea2..360efb1c16b65b8dd82ca73adb345e1d52a48fe5 100644 --- a/addons/survey/static/tests/tours/certification_success.js +++ b/addons/survey/static/tests/tours/certification_success.js @@ -23,44 +23,44 @@ tour.register('test_certification_success', { trigger: 'button.btn.btn-primary.btn-lg:contains("Start Certification")', }, { // Question: Do we sell Acoustic Bloc Screens? content: "Selecting answer 'Yes'", - trigger: 'div.js_question-wrapper:contains("Do we sell Acoustic Bloc Screens") label:contains("Yes") input', + trigger: 'div.js_question-wrapper:contains("Do we sell Acoustic Bloc Screens") label:contains("Yes")', }, { // Question: Select all the existing products content: "Ticking answer 'Chair floor protection'", - trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Chair floor protection") input' + trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Chair floor protection")' }, { content: "Ticking answer 'Drawer'", - trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Drawer") input' + trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Drawer")' }, { content: "Ticking answer 'Conference chair'", - trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Conference chair") input' + trigger: 'div.js_question-wrapper:contains("Select all the existing products") label:contains("Conference chair")' }, { // Question: Select all the available customizations for our Customizable Desk content: "Ticking answer 'Color'", - trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Color") input' + trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Color")' }, { content: "Ticking answer 'Legs'", - trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Legs") input' + trigger: 'div.js_question-wrapper:contains("Select all the available customizations for our Customizable Desk") label:contains("Legs")' }, { // Question: How many versions of the Corner Desk do we have? content: "Selecting answer '2'", - trigger: 'div.js_question-wrapper:contains("How many versions of the Corner Desk do we have") label:contains("2") input', + trigger: 'div.js_question-wrapper:contains("How many versions of the Corner Desk do we have") label:contains("2")', }, { // Question: Do you think we have missing products in our catalog? (not rated) content: "Missing products", trigger: 'div.js_question-wrapper:contains("Do you think we have missing products in our catalog") textarea', run: "text I think we should make more versions of the customizable desk, it's such an amazing product!", }, { // Page-2 Question: How much do we sell our Cable Management Box? content: "Selecting answer '80$' (wrong one)", - trigger: 'div.js_question-wrapper:contains("How much do we sell our Cable Management Box") label:contains("80$") input', + trigger: 'div.js_question-wrapper:contains("How much do we sell our Cable Management Box") label:contains("80$")', }, { // Question: Select all the the products that sell for 100$ or more content: "Ticking answer 'Corner Desk Right Sit'", - trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Corner Desk Right Sit") input' + trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Corner Desk Right Sit")' }, { content: "Ticking answer 'Desk Combination'", - trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Desk Combination") input' + trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Desk Combination")' }, { content: "Ticking answer 'Large Desk'", - trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Large Desk") input' + trigger: 'div.js_question-wrapper:contains("Select all the the products that sell for 100$ or more") label:contains("Large Desk")' }, { // Question: What do you think about our prices (not rated)? content: "Selecting answer 'Underpriced'", - trigger: 'div.js_question-wrapper:contains("What do you think about our prices") label:contains("Underpriced") input', + trigger: 'div.js_question-wrapper:contains("What do you think about our prices") label:contains("Underpriced")', }, { content: "Finish Survey", trigger: 'button[type="submit"]', diff --git a/addons/survey/static/tests/tours/survey.js b/addons/survey/static/tests/tours/survey.js index fce408f9cbeed6613daf1e3f820ed848e7063110..22344bd2d99cce4b63ef05ed2435d37cec03ab7b 100644 --- a/addons/survey/static/tests/tours/survey.js +++ b/addons/survey/static/tests/tours/survey.js @@ -21,7 +21,7 @@ tour.register('test_survey', { run: 'text 05/05/1980', }, { content: 'Answer How frequently do you buy products online', - trigger: 'div.js_question-wrapper:contains("How frequently do you buy products online") label:contains("Once a month") input', + trigger: 'div.js_question-wrapper:contains("How frequently do you buy products online") label:contains("Once a month")', }, { content: 'Answer How many times did you order products on our website', trigger: 'div.js_question-wrapper:contains("How many times did you order products on our website") input', @@ -33,25 +33,25 @@ tour.register('test_survey', { // Page-2 { content: 'Answer Which of the following words would you use to describe our products (High Quality)', - trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("High quality") input', + trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("High quality")', }, { content: 'Answer Which of the following words would you use to describe our products (Good value for money)', - trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("Good value for money") input', + trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("Good value for money")', }, { content: 'Answer What do your think about our new eCommerce (The new layout and design is fresh and up-to-date)', - trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The new layout and design is fresh and up-to-date") input:first', + trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The new layout and design is fresh and up-to-date") td:first', }, { content: 'Answer What do your think about our new eCommerce (It is easy to find the product that I want)', - trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("It is easy to find the product that I want") input:eq(2)', + trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("It is easy to find the product that I want") td:eq(2)', }, { content: 'Answer What do your think about our new eCommerce (The tool to compare the products is useful to make a choice)', - trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The tool to compare the products is useful to make a choice") input:eq(3)', + trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The tool to compare the products is useful to make a choice") td:eq(3)', }, { content: 'Answer What do your think about our new eCommerce (The checkout process is clear and secure)', - trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The checkout process is clear and secure") input:eq(2)', + trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The checkout process is clear and secure") td:eq(2)', }, { content: 'Answer What do your think about our new eCommerce (I have added products to my wishlist)', - trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("I have added products to my wishlist") input:last', + trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("I have added products to my wishlist") td:last', }, { content: 'Answer Do you have any other comments, questions, or concerns', trigger: 'div.js_question-wrapper:contains("Do you have any other comments, questions, or concerns") textarea', diff --git a/addons/survey/static/tests/tours/survey_prefill.js b/addons/survey/static/tests/tours/survey_prefill.js index 89242a0a5d093795a20da583e56e5b7b881040ba..223b824cb1bf69c5c3ef5219a82e4d2fe00e68f5 100644 --- a/addons/survey/static/tests/tours/survey_prefill.js +++ b/addons/survey/static/tests/tours/survey_prefill.js @@ -16,7 +16,7 @@ tour.register('test_survey_prefill', { trigger: 'div.js_question-wrapper:contains("When is your date of birth ?") input', run: 'text 05/05/1980', }, { // Question: How frequently do you buy products online ? - trigger: 'div.js_question-wrapper:contains("How frequently do you buy products online ?") label:contains("Once a week") input', + trigger: 'div.js_question-wrapper:contains("How frequently do you buy products online ?") label:contains("Once a week")', }, { // Question: How many times did you order products on our website ? trigger: 'div.js_question-wrapper:contains("How many times did you order products on our website ?") input', run: 'text 42', @@ -27,25 +27,25 @@ tour.register('test_survey_prefill', { // Page-2 { // Question: Which of the following words would you use to describe our products ? content: 'Answer Which of the following words would you use to describe our products (High Quality)', - trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("High quality") input', + trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("High quality")', }, { content: 'Answer Which of the following words would you use to describe our products (Good value for money)', - trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("Good value for money") input', + trigger: 'div.js_question-wrapper:contains("Which of the following words would you use to describe our products") label:contains("Good value for money")', }, { content: 'Answer What do your think about our new eCommerce (The new layout and design is fresh and up-to-date)', - trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The new layout and design is fresh and up-to-date") input:first', + trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The new layout and design is fresh and up-to-date") td:first', }, { content: 'Answer What do your think about our new eCommerce (It is easy to find the product that I want)', - trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("It is easy to find the product that I want") input:eq(2)', + trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("It is easy to find the product that I want") td:eq(2)', }, { content: 'Answer What do your think about our new eCommerce (The tool to compare the products is useful to make a choice)', - trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The tool to compare the products is useful to make a choice") input:eq(3)', + trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The tool to compare the products is useful to make a choice") td:eq(3)', }, { content: 'Answer What do your think about our new eCommerce (The checkout process is clear and secure)', - trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The checkout process is clear and secure") input:eq(2)', + trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("The checkout process is clear and secure") td:eq(2)', }, { content: 'Answer What do your think about our new eCommerce (I have added products to my wishlist)', - trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("I have added products to my wishlist") input:last', + trigger: 'div.js_question-wrapper:contains("What do your think about our new eCommerce") tr:contains("I have added products to my wishlist") td:last', }, { content: 'Answer Do you have any other comments, questions, or concerns', trigger: 'div.js_question-wrapper:contains("Do you have any other comments, questions, or concerns") textarea', diff --git a/addons/survey/views/assets.xml b/addons/survey/views/assets.xml index 07f2d902d5b13f8ba1e31e5065fc7387353a4161..b1f3df0a00ef8a94e2332a6ddb07b9b5f9828599 100644 --- a/addons/survey/views/assets.xml +++ b/addons/survey/views/assets.xml @@ -10,11 +10,13 @@ <script type="text/javascript" src="/survey/static/src/js/survey_timer.js" /> <script type="text/javascript" src="/survey/static/src/js/survey_breadcrumb.js" /> <script type="text/javascript" src="/survey/static/src/js/survey_form.js" /> + <script type="text/javascript" src="/survey/static/src/js/survey_print.js" /> <script type="text/javascript" src="/survey/static/src/js/survey_result.js" /> + <t t-call="web._assets_helpers"/> <link href="/survey/static/src/css/survey_print.css" rel="stylesheet" type="text/css"/> <link href="/survey/static/src/css/survey_result.css" rel="stylesheet" type="text/css"></link> - <link rel="stylesheet" type="text/scss" href="/survey/static/src/scss/survey_templates.scss"/> + <link rel="stylesheet" type="text/scss" href="/survey/static/src/scss/survey_form.scss"/> </template> <template id="survey_report_assets_pdf" inherit_id="web.report_assets_pdf"> diff --git a/addons/survey/views/survey_survey_views.xml b/addons/survey/views/survey_survey_views.xml index cc63f53627163b0c01e99fbd3868499bdef80228..9dd428ee87f121170061fbfdb5ad32954e35d1e7 100644 --- a/addons/survey/views/survey_survey_views.xml +++ b/addons/survey/views/survey_survey_views.xml @@ -42,6 +42,7 @@ </button> </div> <widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/> + <field name="background_image" widget="image" class="oe_avatar"/> <div class="oe_title" style="width: 100%;"> <label for="title" class="oe_edit_only"/> <h1><field name="title" placeholder="e.g. Satisfaction Survey"/></h1> @@ -75,6 +76,7 @@ <group name="options"> <group string="Questions" name="questions"> <field name="questions_layout" widget="radio" /> + <field name="progression_mode" widget="radio" /> <label for="is_time_limited" string="Time Limit"/> <div> <field name="is_time_limited" nolabel="1"/> diff --git a/addons/survey/views/survey_templates.xml b/addons/survey/views/survey_templates.xml index f80bbdf55f11e86d463afd3ba91a4ff22ab09a1c..f8d1c136fb38891161115c4100f98e59a3dcb0fb 100644 --- a/addons/survey/views/survey_templates.xml +++ b/addons/survey/views/survey_templates.xml @@ -3,6 +3,9 @@ <data> <!-- Main survey layout --> <template id="survey.layout" name="Survey Layout" inherit_id="web.frontend_layout" primary="True"> + <xpath expr="//div[@id='wrapwrap']" position="attributes"> + <attribute name="t-att-style" add="('height: 100%; overflow: auto; background: url(' + '/survey/get_background_image/%s/%s' % (survey.access_token, answer.access_token) + ') no-repeat fixed center; box-shadow: inset 0 0 0 10000px rgba(255,255,255,.7); background-size: cover;') if survey and survey.background_image and answer else 'height: 100%; overflow: auto;'"/> + </xpath> <xpath expr="//head/t[@t-call-assets][last()]" position="after"> <t t-call-assets="survey.survey_assets" lazy_load="True"/> </xpath> @@ -17,8 +20,8 @@ <template id="survey_page_fill" name="Survey: main page (take survey)"> <t t-call="survey.layout"> - <div class="wrap"> - <div class="container o_survey_form"> + <div class="wrap o_survey_wrap mt16 pb16 d-flex"> + <div class="container o_survey_form d-flex flex-column"> <t t-if="answer.test_entry" t-call="survey.survey_button_form_view" /> <t t-call="survey.survey_fill_header" /> @@ -29,7 +32,7 @@ </template> <template id="survey_fill_header" name="Survey: main page header"> - <div class="o_page_header o_survey_header"> + <div class="o_survey_nav pt16 pb24"> <div class="container m-0 p-0"> <div class="row"> <div class="col-lg-8"><h1 t-esc="survey.title"></h1></div> @@ -38,7 +41,7 @@ </div> </div> </div> - <div t-att-class="'o_survey_breadcrumb_container mt8 bg-200' + (' d-none ' if answer.state != 'in_progress' else '')" + <div t-att-class="'o_survey_breadcrumb_container mt8' + (' d-none ' if answer.state != 'in_progress' else '')" t-if="survey.questions_layout == 'page_per_section' and answer.state != 'done'" t-att-data-can-go-back="survey.users_can_go_back" t-att-data-pages="json.dumps(breadcrumb_pages)" /> @@ -48,19 +51,21 @@ <template id="survey_fill_form" name="Survey: main page content"> <t t-set="survey_form_readonly" t-value="false"/> <form role="form" method="post" t-att-name="survey.id" + class="d-flex flex-grow-1 align-items-center" t-att-data-answer-token="answer.access_token" t-att-data-survey-token="survey.access_token" t-att-data-timer="answer.start_datetime.isoformat() if survey.is_time_limited and answer.start_datetime and answer.state != 'done' else False" t-att-data-time-limit-minutes="survey.time_limit" - t-att-data-is-start-screen="answer.state == 'new'"> + t-att-data-is-start-screen="answer.state == 'new'" + t-att-data-questions-layout="survey.questions_layout"> <input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/> <input type="hidden" name="token" t-att-value="answer.access_token" /> <div class="o_survey_error alert alert-danger d-none" role="alert"> <p>There was an error during the validation of the survey.</p> </div> - <div class="o_survey_form_content"> + <div class="o_survey_form_content w-100"> <t t-if="answer.state == 'new'" t-call="survey.survey_fill_form_start"/> <t t-elif="answer.state == 'in_progress'" t-call="survey.survey_fill_form_in_progress" /> <t t-else="" t-call="survey.survey_fill_form_done"/> @@ -83,7 +88,7 @@ </template> <template id="survey_fill_form_start" name="Survey: start form content"> - <div class="wrap o_survey_start"> + <div class="wrap o_survey_start pb256"> <div class='mt32 mb32'> <div t-field='survey.description' class="oe_no_empty"/> <div t-if="survey.is_time_limited"> @@ -99,7 +104,7 @@ <t t-else=""> Start Survey </t> - </button> + </button><span class="font-weight-bold ml-2 text-primary d-none d-md-inline">or press Enter</span> </div> </div> </template> @@ -107,17 +112,18 @@ <template id="survey_fill_form_in_progress" name="Survey: form with questions"> <t t-if="survey.questions_layout == 'one_page'"> <t t-foreach='survey.question_and_page_ids' t-as='question'> - <h2 t-if="question.is_page" t-field='question.title' class="o_survey_title" /> + <h2 t-if="question.is_page" t-field='question.title' class="o_survey_title pb16" /> <t t-if="not question.is_page and question in answer.predefined_question_ids" t-call="survey.question_container"/> </t> <div class="text-center mt16 mb256"> - <button type="submit" value="finish" class="btn btn-primary">Submit Survey</button> + <button type="submit" value="finish" class="btn btn-primary"> + Submit</button><span class="font-weight-bold ml-2 text-primary d-none d-md-inline">or press Enter</span> </div> </t> <t t-if="survey.questions_layout == 'page_per_section'"> - <h2 t-field='page.title' class="o_survey_title" /> + <h2 t-field='page.title' class="o_survey_title pb16" /> <div t-field='page.description' class="oe_no_empty"/> <input type="hidden" name="page_id" t-att-value="page.id" /> @@ -125,12 +131,19 @@ <t t-if="question in answer.predefined_question_ids" t-call="survey.question_container"/> </t> - <div class="text-center mt16 mb256"> - <button t-if="survey.users_can_go_back and page != survey.page_ids[0]" type="submit" class="btn btn-secondary" - name="button_submit" value="previous" t-att-data-previous-page-id="previous_page_id">Previous page</button> - <button type="submit" t-att-value="'next' if not last else 'finish'" class="btn btn-primary"> - <t t-esc="'Next Page' if not last else 'Submit Survey'"/> - </button> + <div class="row"> + <div class="offset-3 col-6 text-center mt16 mb128"> + <button t-if="survey.users_can_go_back and page != survey.page_ids[0]" type="submit" class="btn btn-secondary" + name="button_submit" value="previous" t-att-data-previous-page-id="previous_page_id">Back</button> + <button type="submit" t-att-value="'next' if not last else 'finish'" class="btn btn-primary"> + Continue</button><span class="font-weight-bold ml-2 text-primary d-none d-md-inline"> or press Enter</span> + </div> + <div class="col-3"> + <t t-call="survey.survey_progression"> + <t t-set="page_ids" t-value="survey.page_ids.ids"/> + <t t-set="page_number" t-value="page_ids.index(page.id) + (1 if survey.progression_mode == 'number' else 0)"/> + </t> + </div> </div> </t> @@ -138,12 +151,19 @@ <input type="hidden" name="question_id" t-att-value="question.id" /> <t t-call="survey.question_container"/> - <div class="text-center mt16 mb256"> - <button t-if="survey.users_can_go_back and question != answer.predefined_question_ids[0]" type="submit" class="btn btn-secondary" - name="button_submit" value="previous" t-att-data-previous-page-id="previous_page_id">Previous page</button> - <button type="submit" t-att-value="'next' if not last else 'finish'" class="btn btn-primary"> - <t t-esc="'Next Page' if not last else 'Submit Survey'"/> - </button> + <div class="row"> + <div class="offset-3 col-6 text-center mt16 mb128"> + <button t-if="survey.users_can_go_back and question != answer.predefined_question_ids[0]" type="submit" class="btn btn-secondary" + name="button_submit" value="previous" t-att-data-previous-page-id="previous_page_id">Back</button> + <button type="submit" t-att-value="'next' if not last else 'finish'" class="btn btn-primary"> + Continue</button><span class="font-weight-bold ml-2 text-primary d-none d-md-inline">or press Enter</span> + </div> + <div class="col-3"> + <t t-call="survey.survey_progression"> + <t t-set="page_ids" t-value="survey.question_ids.ids"/> + <t t-set="page_number" t-value="page_ids.index(question.id)"/> + </t> + </div> </div> </t> </template> @@ -151,7 +171,7 @@ <!-- Finished (taken and finished) survey page --> <template id="survey_fill_form_done" name="Survey: finished"> <div class="wrap"> - <div class="o_survey_finished mt32 mb32"> + <div class="o_survey_finished mt32 mb32 pb256"> <h1>Thank you!</h1> <div t-field="survey.description_done" class="oe_no_empty" /> <div class="row"> @@ -204,7 +224,10 @@ <!-- Question widgets --> <template id="question_container" name="Survey: question container"> <t t-set="answer_lines" t-value="answer.user_input_line_ids.filtered(lambda line: line.question_id == question)"/> - <div class="js_question-wrapper" t-att-id="question.id" t-att-data-required="question.constr_mandatory" + <!--Use Key selection if number of choices is < 26 to keep Z for other choice if any--> + <t t-set="letters" t-value="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> + <t t-set="useKeySelection" t-value="len(question.suggested_answer_ids) < len(letters) and survey.questions_layout == 'page_per_question'"/> + <div class="js_question-wrapper pb-4" t-att-id="question.id" t-att-data-required="question.constr_mandatory" t-att-data-constr-error-msg="question.constr_error_msg" t-att-data-validation-error-msg="question.validation_error_msg"> <h4> @@ -220,26 +243,30 @@ <t t-if="question.question_type == 'simple_choice'"><t t-call="survey.question_simple_choice"/></t> <t t-if="question.question_type == 'multiple_choice'"><t t-call="survey.question_multiple_choice"/></t> <t t-if="question.question_type == 'matrix'"><t t-call="survey.question_matrix"/></t> - <div class="o_survey_question_error alert alert-danger" role="alert"></div> + <div class="o_survey_question_error overflow-hidden border-0 py-0 px-3 alert alert-danger" role="alert"></div> </div> </template> <template id="question_text_box" name="Question: free text box"> - <textarea class="form-control o_survey_question_text_box" rows="3" t-att-name="question.id" - t-att-data-question-type="question.question_type"><t t-if="answer_lines" t-esc="answer_lines[0].value_text_box or None"/></textarea> + <div class="o_survey_comment_container py-0 px-1"> + <textarea class="form-control o_survey_question_text_box font-weight-bold bg-transparent text-primary rounded-0" rows="3" t-att-name="question.id" + t-att-data-question-type="question.question_type"><t t-if="answer_lines" t-esc="answer_lines[0].value_text_box or None"/></textarea> + </div> </template> <template id="question_char_box" name="Question: text box"> - <input t-att-type="'email' if question.validation_email else 'text'" - class="form-control o_survey_question_text_box" t-att-name="question.id" + <div class="o_survey_comment_container py-0 px-1"> + <input t-att-type="'email' if question.validation_email else 'text'" + class="form-control o_survey_question_text_box font-weight-bold bg-transparent text-primary rounded-0" t-att-name="question.id" t-att-value="answer_lines[0].value_char_box if answer_lines else None" t-att-data-question-type="question.question_type" t-att-data-validation-length-min="question.validation_length_min if question.validation_required else False" t-att-data-validation-length-max="question.validation_length_max if question.validation_required else False"/> + </div> </template> <template id="question_numerical_box" name="Question: numerical box"> - <input type="number" step="any" class="form-control o_survey_question_numerical_box" t-att-name="question.id" t-att-value="answer_lines[0].value_numerical_box if answer_lines else None" + <input type="number" step="any" class="form-control o_survey_question_numerical_box font-weight-bold bg-transparent text-primary rounded-0" t-att-name="question.id" t-att-value="answer_lines[0].value_numerical_box if answer_lines else None" t-att-data-question-type="question.question_type" t-att-data-validation-float-min="question.validation_min_float_value if question.validation_required else False" t-att-data-validation-float-max="question.validation_max_float_value if question.validation_required else False"/> @@ -249,12 +276,12 @@ <div class="input-group o_survey_form_date" t-attf-id="datetimepicker_#{question.id}" data-target-input="nearest" t-att-data-mindate="question.validation_min_date" t-att-data-maxdate="question.validation_max_date"> - <input type="text" class="form-control datetimepicker-input o_survey_question_date" + <input type="text" class="form-control datetimepicker-input o_survey_question_date font-weight-bold bg-transparent text-primary rounded-0" t-attf-data-target="#datetimepicker_#{question.id}" t-att-name="question.id" t-att-value="format_date(answer_lines[0].value_date) if answer_lines else None" t-att-data-question-type="question.question_type"/> - <div t-if="not survey_form_readonly" class="input-group-append" t-attf-data-target="#datetimepicker_#{question.id}" data-toggle="datetimepicker"> - <div class="input-group-text"><i class="fa fa-calendar"></i></div> + <div t-if="not survey_form_readonly" class="input-group-append position-absolute" t-attf-data-target="#datetimepicker_#{question.id}" data-toggle="datetimepicker"> + <div class="input-group-text text-primary border-0 bg-transparent"><i class="fa fa-calendar"></i></div> </div> </div> </template> @@ -263,12 +290,12 @@ <div class="input-group o_survey_form_date" t-attf-id="datetimepicker_#{question.id}" data-target-input="nearest" t-att-data-mindate="question.validation_min_datetime" t-att-data-maxdate="question.validation_max_datetime"> - <input type="text" class="form-control datetimepicker-input o_survey_question_datetime" + <input type="text" class="form-control datetimepicker-input o_survey_question_datetime font-weight-bold bg-transparent text-primary rounded-0" t-attf-data-target="#datetimepicker_#{question.id}" t-att-name="question.id" t-att-value="format_datetime(answer_lines[0].value_datetime) if answer_lines else None" t-att-data-question-type="question.question_type"/> - <div t-if="not survey_form_readonly" class="input-group-append" t-attf-data-target="#datetimepicker_#{question.id}" data-toggle="datetimepicker"> - <div class="input-group-text"><i class="fa fa-calendar"></i></div> + <div t-if="not survey_form_readonly" class="input-group-append position-absolute" t-attf-data-target="#datetimepicker_#{question.id}" data-toggle="datetimepicker"> + <div class="input-group-text text-primary border-0 bg-transparent"><i class="fa fa-calendar"></i></div> </div> </div> </template> @@ -279,27 +306,58 @@ <div class="row o_survey_form_choice" t-att-data-name="question.id" data-question-type="simple_choice_radio"> - <div t-foreach='question.suggested_answer_ids' t-as='label' t-attf-class="col-lg-#{question.column_nb}"> - <label t-att-class="' bg-success ' if quizz_correction and label.answer_score > 0.0 else None"> - <input type="radio" t-att-value='label.id' class="o_survey_form_choice_item" - t-att-name='question.id' - t-att-checked="answer_line and answer_line.suggested_answer_id.id == label.id and 'checked' or None"/> - <span t-field='label.value'/> - </label> + <t t-set="item_idx" t-value="0"/> + <div class="d-flex flex-wrap font-weight-bold col-lg-12"> + <t t-set="has_correct_answer" t-value="scoring_display_correction and any(label.is_correct for label in question.suggested_answer_ids)"/> + <t t-foreach='question.suggested_answer_ids' t-as='label'> + <t t-set="item_idx" t-value="label_index"/> + <t t-set="answer_selected" t-value="answer_line and answer_line.suggested_answer_id.id == label.id"/> + <t t-set="is_correct" t-value="label.answer_score > 0.0"/> + + <!--Used for print mode with corrections --> + <t t-set="answer_class" t-if="not has_correct_answer" t-value="''" /> + <t t-set="answer_class" t-elif="is_correct" t-value="'bg-success'" /> + <t t-set="answer_class" t-elif="not is_correct" t-value="'bg-danger'" /> + + <label t-att-for="str(question.id) + '_' + str(label.id)" + t-att-class="'o_survey_choice_btn m-1 py-1 px-3 text-white rounded %s %s' % (answer_class, 'o_survey_selected' if answer_selected else '')"> + <t t-call="survey.survey_selection_key"> + <t t-set="selection_key_class" t-value="'o_survey_radio_btn float-left d-flex'"/> + </t> + <span class="ml-2" t-field='label.value'/> + <input t-att-id="str(question.id) + '_' + str(label.id)" type="radio" t-att-value='label.id' class="o_survey_form_choice_item invisible position-absolute" + t-att-name='question.id' + t-att-checked="answer_line and answer_line.suggested_answer_id.id == label.id and 'checked' or None" + t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/> + <i class="fa fa-check-circle float-right mt-1 position-relative"></i> + <i class="fa fa-circle float-right mt-1 position-relative"></i> + </label> + </t> </div> <div t-if='question.comments_allowed and question.comment_count_as_answer' class="js_comments col-lg-12" > - <label> - <input type="radio" class="o_survey_form_choice_item o_survey_js_form_other_comment" value="-1" - t-att-name='question.id' - t-att-checked="comment_line and 'checked' or None"/> - <span t-field="question.comments_message" /> - </label> - <textarea type="text" class="form-control" - t-attf-disabled="#{'' if comment_line else 'disabled'}"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea> + <div class="d-flex flex-wrap font-weight-bold"> + <label t-att-class="'o_survey_choice_btn m-1 py-1 px-3 text-white rounded %s' % ('o_survey_selected' if comment_line else '')"> + <t t-set="item_idx" t-value="item_idx + 1"/> + <t t-call="survey.survey_selection_key"> + <t t-set="selection_key_class" t-value="'o_survey_radio_btn float-left d-flex'"/> + </t> + <input type="radio" class="o_survey_form_choice_item o_survey_js_form_other_comment invisible position-absolute" value="-1" + t-att-name='question.id' + t-att-checked="comment_line and 'checked' or None" + t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/> + <span class="ml-2" t-field="question.comments_message" /> + <i class="fa fa-check-circle float-right mt-1 position-relative"></i> + <i class="fa fa-circle float-right mt-1 position-relative"></i> + </label> + </div> + <div class="o_survey_comment_container py-0 px-1"> + <textarea type="text" class="form-control o_survey_question_text_box font-weight-bold bg-transparent text-primary rounded-0" + t-att-disabled="None if comment_line else 'disabled'"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea> + </div> </div> - <div t-if='question.comments_allowed and not question.comment_count_as_answer' class="col-lg-12"> - <span t-field="question.comments_message"/> - <textarea type="text" class="form-control o_survey_comment"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea> + <div t-if='question.comments_allowed and not question.comment_count_as_answer' class="col-lg-12 o_survey_comment_container mx-1 py-0 pl-3 pr-4"> + <textarea type="text" class="form-control o_survey_comment o_survey_question_text_box font-weight-bold bg-transparent text-primary rounded-0" + t-att-placeholder="question.comments_message"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea> </div> </div> </template> @@ -309,61 +367,132 @@ <div class="row o_survey_form_choice o_survey_question_multiple_choice" t-att-data-name="question.id" t-att-data-question-type="question.question_type"> - <div t-foreach='question.suggested_answer_ids' t-as='label' t-attf-class="col-lg-#{question.column_nb}"> - <t t-set="answer_line" t-value="answer_lines.filtered(lambda line: line.suggested_answer_id == label)"/> - <label t-att-class="' bg-success ' if quizz_correction and label.answer_score > 0.0 else None"> - <input type="checkbox" t-att-value='label.id' class="o_survey_form_choice_item" - t-att-name="question.id" - t-att-checked="'checked' if answer_line else None"/> - <span t-field='label.value'/> - </label> - </div> + <t t-set="item_idx" t-value="0"/> + <div class="d-flex flex-wrap font-weight-bold col-lg-12"> + <t t-set="has_correct_answer" t-value="scoring_display_correction and any(label.is_correct for label in question.suggested_answer_ids)"/> + <t t-foreach='question.suggested_answer_ids' t-as='label'> + <t t-set="item_idx" t-value="label_index"/> + <t t-set="answer_line" t-value="answer_lines.filtered(lambda line: line.suggested_answer_id == label)"/> + <t t-set="answer_selected" t-value="answer_line and answer_line.suggested_answer_id.id == label.id"/> + <t t-set="is_correct" t-value="label.answer_score > 0.0"/> + + <!--Used for print mode with corrections --> + <t t-set="answer_class" t-if="not has_correct_answer" t-value="''" /> + <t t-set="answer_class" t-elif="is_correct" t-value="'bg-success'" /> + <t t-set="answer_class" t-elif="not is_correct" t-value="'bg-danger'" /> + <label t-att-class="'o_survey_choice_btn m-1 py-1 px-3 text-white rounded %s %s' % (answer_class, 'o_survey_selected' if answer_line else '')"> + <t t-call="survey.survey_selection_key"> + <t t-set="selection_key_class" t-value="'float-left d-flex'"/> + </t> + <input type="checkbox" t-att-value='label.id' class="o_survey_form_choice_item invisible position-absolute" + t-att-name="question.id" + t-att-checked="'checked' if answer_line else None" + t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/> + <span class="ml-2" t-field='label.value'/> + <i class="fa fa-check-square float-right mt-1 position-relative"></i> + <i class="fa fa-square float-right mt-1 position-relative"></i> + </label> + </t> + </div> <div t-if='question.comments_allowed and question.comment_count_as_answer' class="js_ck_comments col-lg-12" > - <label> - <input type="checkbox" class="o_survey_form_choice_item o_survey_js_form_other_comment" value="-1" - t-att-name="question.id" - t-att-checked="comment_line and 'checked' or None"/> - <span t-field="question.comments_message" /> - </label> - <textarea type="text" class="form-control" - t-attf-disabled="#{'' if comment_line else 'disabled'}"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea> + <div class="d-flex flex-wrap font-weight-bold"> + <label t-att-class="'o_survey_choice_btn m-1 py-1 px-3 text-white rounded %s' % ('o_survey_selected' if comment_line else '')"> + <t t-set="item_idx" t-value="item_idx + 1"/> + <t t-call="survey.survey_selection_key"> + <t t-set="selection_key_class" t-value="'float-left d-flex'"/> + </t> + <input type="checkbox" class="o_survey_form_choice_item o_survey_js_form_other_comment invisible position-absolute" value="-1" + t-att-name="question.id" + t-att-checked="comment_line and 'checked' or None" + t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/> + <span class="ml-2" t-field="question.comments_message" /> + <i class="fa fa-check-square float-right mt-1 position-relative"></i> + <i class="fa fa-square float-right mt-1 position-relative"></i> + </label> + </div> + <div class="o_survey_comment_container py-0 px-1"> + <textarea type="text" class="form-control o_survey_question_text_box font-weight-bold bg-transparent text-primary rounded-0" + t-att-disabled="None if comment_line else 'disabled'"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea> + </div> </div> - <div t-if='question.comments_allowed and not question.comment_count_as_answer' class="col-lg-12"> - <span t-field="question.comments_message"/> - <textarea type="text" class="form-control o_survey_comment"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea> + <div t-if='question.comments_allowed and not question.comment_count_as_answer' class="col-lg-12 o_survey_comment_container mx-1 py-0 pl-3 pr-4"> + <textarea type="text" class="form-control o_survey_comment o_survey_question_text_box font-weight-bold bg-transparent text-primary rounded-0" + t-att-placeholder="question.comments_message"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea> </div> </div> </template> <template id="question_matrix" name="Question: matrix"> <t t-set="comment_line" t-value="answer_lines.filtered(lambda line: line.value_char_box)"/> - <table class="table table-hover o_survey_question_matrix" + <table class="table table-hover o_survey_question_matrix text-white text-center mb-0" t-att-data-name="question.id" t-att-data-question-type="question.question_type" t-att-data-sub-questions="question.matrix_row_ids.ids"> <thead> <tr> - <th> </th> - <th t-foreach="question.suggested_answer_ids" t-as="col_label"><span t-field="col_label.value" /></th> + <th class="border-0"> </th> + <th class="border-0" t-foreach="question.suggested_answer_ids" t-as="col_label"><span t-field="col_label.value" /></th> </tr> </thead> <tbody> - <tr t-foreach="question.matrix_row_ids" t-as="row_label"> - <th><span t-field="row_label.value" /></th> - <td t-foreach="question.suggested_answer_ids" t-as="col_label"> + <t t-set="item_idx" t-value="0"/> + <tr class="bg-white text-white" t-foreach="question.matrix_row_ids" t-as="row_label"> + <th class="border-0"><span t-field="row_label.value" /></th> + <t t-foreach="question.suggested_answer_ids" t-as="col_label"> <t t-set="answer" t-value="answer_lines.filtered(lambda line: line.suggested_answer_id == col_label and line.matrix_row_id == row_label)"/> - <input t-att-type="'checkbox' if question.matrix_subtype == 'multiple' else 'radio'" - t-att-name="'%s_%s' % (question.id, row_label.id)" t-att-value='col_label.id' - t-att-checked="'checked' if answer else None" - t-att-data-row-id="row_label.id"/> - </td> + <td t-att-class="'o_survey_matrix_btn text-primary border-0 %s' + % ('o_survey_selected' if answer else '')"> + <input t-att-type="'checkbox' if question.matrix_subtype == 'multiple' else 'radio'" + t-att-name="'%s_%s' % (question.id, row_label.id)" t-att-value='col_label.id' + t-att-checked="'checked' if answer else None" + t-att-data-row-id="row_label.id" + t-att-data-selection-key="letters[item_idx] if useKeySelection else ''" + class="o_survey_form_choice_item d-none"/> + <i t-att-class="'o_survey_matrix_empty_checkbox fa fa-%s position-relative' + % ('square-o' if question.matrix_subtype == 'multiple' else 'circle-thin')"></i> + <i t-att-class="'fa fa-check-%s position-relative' + % ('square' if question.matrix_subtype == 'multiple' else 'circle')"></i> + <t t-call="survey.survey_selection_key"> + <t t-set="selection_key_class" + t-value="'float-right font-weight-bold %s' % ('o_survey_radio_btn' if question.matrix_subtype != 'multiple' else '')"/> + </t> + <t t-set="item_idx" t-value="item_idx + 1"/> + </td> + </t> </tr> </tbody> </table> <div t-if='question.comments_allowed'> - <span t-field="question.comments_message"/> - <textarea type="text" class="form-control" t-att-name="'%s_%s' % (question.id, 'comment')"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea> + <textarea type="text" class="form-control o_survey_question_text_box o_survey_comment font-weight-bold bg-transparent text-primary rounded-0" + t-att-placeholder="question.comments_message" + t-att-name="'%s_%s' % (question.id, 'comment')"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea> + </div> + </template> + + <template id="survey_selection_key"> + <div t-if="useKeySelection" t-att-class="'o_survey_choice_key bg-white position-relative rounded %s' % selection_key_class"> + <span class="o_survey_key text-center position-absolute bg-white rounded-left py-0 pr-4 pl-2"><span class="text-primary text-center text-center w-100 position-relative">Key</span></span> + <span class="text-primary text-center w-100 position-relative" t-esc="letters[item_idx]"/> + </div> + </template> + + <template id="survey_progression" name="Survey: Progression"> + <div class="float-right"> + <t t-if="len(page_ids) > 1"> + <t t-set="percentage" t-value="round(100*(page_number/len(page_ids)))"/> + <t t-if="survey.progression_mode == 'percent'"> + <span class="o_survey_progress_percent" t-esc="percentage"/> % completed + </t> + <t t-else=""> + <span class="o_survey_progress_number" t-esc="page_number"/> of <span t-esc="len(page_ids)"/> + <span t-if="survey.questions_layout == 'page_per_question'">answered</span> + <span t-else="">pages</span> + </t> + <div class="o_survey_progress progress flex-grow-1"> + <div class="progress-bar bg-primary" t-att-style="'width: ' + str(percentage) + '%'"/> + </div> + </t> </div> </template> </data> diff --git a/addons/survey/views/survey_templates_management.xml b/addons/survey/views/survey_templates_management.xml index 7f843717f08c3845dd48ef212524b6c8cf1fd843..0e1dbaaab2ef9e575579de3397a401c4fb290a91 100644 --- a/addons/survey/views/survey_templates_management.xml +++ b/addons/survey/views/survey_templates_management.xml @@ -74,7 +74,7 @@ <!-- ============================================================ --> <template id="survey_button_form_view" name="Survey: back to form view"> - <div groups="survey.group_survey_manager" t-ignore="true" class="alert alert-info alert-dismissible rounded-0 mt16 fade show d-print-none css_editable_mode_hidden"> + <div groups="survey.group_survey_manager" t-ignore="true" class="alert alert-info alert-dismissible rounded-0 fade show d-print-none css_editable_mode_hidden"> <div t-ignore="true" class="text-center"> <a t-attf-href="/web#view_type=form&model=survey.survey&id=#{survey.id}&action=survey.action_survey_form"><i class="fa fa-fw fa-arrow-right"/><span t-if="answer and answer.test_entry">This is a test survey. </span>Edit Survey.</a> </div> diff --git a/addons/survey/views/survey_templates_print.xml b/addons/survey/views/survey_templates_print.xml index 733e0fa995ba81018f132ee0b2cff8847cffac42..d06947c2e20b85e93dab94ab7b46a50f270cb350 100644 --- a/addons/survey/views/survey_templates_print.xml +++ b/addons/survey/views/survey_templates_print.xml @@ -6,7 +6,7 @@ <t t-call="survey.layout"> <t t-set="survey_form_readonly" t-value="true"/> <div class="wrap"> - <div class="container"> + <div class="o_survey_print container"> <t t-if="answer.test_entry" t-call="survey.survey_button_form_view" /> <div class='jumbotron mt32'> <h1><span t-field='survey.title'/></h1> @@ -27,7 +27,7 @@ <h2> <span t-field='question.title'/> <span t-if="question.constr_mandatory" class="text-danger">*</span> - <span t-if="quizz_correction" class="badge badge-pill" t-att-data-score-question="question.id"></span> + <span t-if="scoring_display_correction" class="badge badge-pill" t-att-data-score-question="question.id"></span> </h2> <t t-if="question.description"><div class="text-muted oe_no_empty" t-field='question.description'/></t> <t t-if="question.question_type == 'text_box'"><t t-call="survey.question_text_box"/></t> @@ -38,7 +38,7 @@ <t t-if="question.question_type == 'simple_choice'"><t t-call="survey.question_simple_choice"/></t> <t t-if="question.question_type == 'multiple_choice'"><t t-call="survey.question_multiple_choice"/></t> <t t-if="question.question_type == 'matrix'"><t t-call="survey.question_matrix"/></t> - <div class="o_survey_question_error alert alert-danger" role="alert"></div> + <div class="o_survey_question_error overflow-hidden border-0 py-0 px-3 alert alert-danger" role="alert"></div> </div> </t> </t> diff --git a/addons/test_website_slides_full/tests/tours/slides_certification_member.js b/addons/test_website_slides_full/tests/tours/slides_certification_member.js index c10ec4ac89885a06a1435fe265c441ebbe6dadb8..eec5f0b7aaf55481cdc732ca1034992914c0c8c5 100644 --- a/addons/test_website_slides_full/tests/tours/slides_certification_member.js +++ b/addons/test_website_slides_full/tests/tours/slides_certification_member.js @@ -89,16 +89,16 @@ var failCertificationSteps = [{ trigger: 'button:contains("Start Certification")' }, { // Question: What type of wood is the best for furniture? content: 'Survey: selecting answer "Fir"', - trigger: 'div.js_question-wrapper:contains("What type of wood is the best for furniture") label:contains("Fir") input', + trigger: 'div.js_question-wrapper:contains("What type of wood is the best for furniture") label:contains("Fir")' }, { // Question: Select all the furniture shown in the video content: 'Survey: ticking answer "Table"', - trigger: 'div.js_question-wrapper:contains("Select all the furniture shown in the video") label:contains("Table") input' + trigger: 'div.js_question-wrapper:contains("Select all the furniture shown in the video") label:contains("Table")' }, { content: 'Survey: ticking answer "Bed"', - trigger: 'div.js_question-wrapper:contains("Select all the furniture shown in the video") label:contains("Bed") input' + trigger: 'div.js_question-wrapper:contains("Select all the furniture shown in the video") label:contains("Bed")' }, { content: 'Survey: submitting the certification with wrong answers', - trigger: 'button:contains("Submit Survey")' + trigger: 'button:contains("Submit")' }]; var retrySteps = [{ @@ -111,19 +111,19 @@ var succeedCertificationSteps = [{ trigger: 'button:contains("Start Certification")' }, { // Question: What type of wood is the best for furniture? content: 'Survey: selecting answer "Oak"', - trigger: 'div.js_question-wrapper:contains("What type of wood is the best for furniture") label:contains("Oak") input', + trigger: 'div.js_question-wrapper:contains("What type of wood is the best for furniture") label:contains("Oak")', }, { // Question: Select all the furniture shown in the video content: 'Survey: ticking answer "Chair"', - trigger: 'div.js_question-wrapper:contains("Select all the furniture shown in the video") label:contains("Chair") input' + trigger: 'div.js_question-wrapper:contains("Select all the furniture shown in the video") label:contains("Chair")' }, { content: 'Survey: ticking answer "Shelve"', - trigger: 'div.js_question-wrapper:contains("Select all the furniture shown in the video") label:contains("Shelve") input' + trigger: 'div.js_question-wrapper:contains("Select all the furniture shown in the video") label:contains("Shelve")' }, { content: 'Survey: ticking answer "Desk"', - trigger: 'div.js_question-wrapper:contains("Select all the furniture shown in the video") label:contains("Desk") input' + trigger: 'div.js_question-wrapper:contains("Select all the furniture shown in the video") label:contains("Desk")' }, { content: 'Survey: submitting the certification with correct answers', - trigger: 'button:contains("Submit Survey")' + trigger: 'button:contains("Submit")' }]; var certificationCompletionSteps = [{