From 695294b95303b33805ace607d9c8b7162e0904aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Warnon?= Date: Tue, 31 Mar 2020 15:30:31 +0000 Subject: [PATCH] [IMP] survey: apply small survey form design changes This commit slightly improves the survey form by adding a few cosmetic changes, notably: - Add/reduce some margins/paddings - Adjust colors/font-weight - Adjust heights - Change some icons by more fitting replacements - Center matrix choices - Move survey progression to bottom-right - Remove ugly jumbotrons - Hide survey title in page_per_question layout - When there are 5 or less option for simple_choice or multiple_choice questions, display the options vertically. - Only show the textarea for the "comment answer" if the user clicks on the related option. One of the biggest design change is the introduction of a "minimized layout" that reduces the width of some question types on bigger screen. This gives a cleaner look to the survey form. Impacted question types: - Numeric - Date - Datetime - Simple / Multiple choices Technical note: As the survey progression is now outside of the survey content, that was re-rendered on every submit, we have to manually refresh the progression with a second template render on the controller side. Small fix addition: We also fix the matrix key selection feature in case the matrix had a total of more than 25 options, which would raise an error. Indeed, they "use key selection" condition only checked the number of rows, and not the rows * columns (total number of options count). LINKS PR #46768 Task 2208574 --- addons/survey/controllers/main.py | 31 ++- .../survey/data/survey_demo_certification.xml | 1 + addons/survey/static/src/js/survey_form.js | 24 ++- .../survey/static/src/scss/survey_form.scss | 95 +++++++-- addons/survey/views/survey_survey_views.xml | 4 +- addons/survey/views/survey_templates.xml | 201 ++++++++++-------- .../views/survey_templates_management.xml | 4 +- .../survey/views/survey_templates_print.xml | 4 +- .../views/survey_templates_statistics.xml | 4 +- 9 files changed, 241 insertions(+), 127 deletions(-) diff --git a/addons/survey/controllers/main.py b/addons/survey/controllers/main.py index 2f556e72192..e8b72629ab0 100644 --- a/addons/survey/controllers/main.py +++ b/addons/survey/controllers/main.py @@ -311,10 +311,35 @@ class Survey(http.Controller): def _prepare_question_html(self, survey_sudo, answer_sudo, **post): """ Survey page navigation is done in AJAX. This function prepare the 'next page' to display in html and send back this html to the survey_form widget that will inject it into the page.""" - data = self._prepare_survey_data(survey_sudo, answer_sudo, **post) + survey_data = self._prepare_survey_data(survey_sudo, answer_sudo, **post) + + survey_content = False if answer_sudo.state == 'done': - return request.env.ref('survey.survey_fill_form_done').render(data) - return request.env.ref('survey.survey_fill_form_in_progress').render(data) + survey_content = request.env.ref('survey.survey_fill_form_done').render(survey_data) + else: + survey_content = request.env.ref('survey.survey_fill_form_in_progress').render(survey_data) + + survey_progress = False + if answer_sudo.state == 'in_progress' and not survey_data.get('question', request.env['survey.question']).is_page: + if survey_sudo.questions_layout == 'page_per_section': + page_ids = survey_sudo.page_ids.ids + survey_progress = request.env.ref('survey.survey_progression').render({ + 'survey': survey_sudo, + 'page_ids': page_ids, + 'page_number': page_ids.index(survey_data['page'].id) + (1 if survey_sudo.progression_mode == 'number' else 0) + }) + elif survey_sudo.questions_layout == 'page_per_question': + page_ids = survey_sudo.question_ids.ids + survey_progress = request.env.ref('survey.survey_progression').render({ + 'survey': survey_sudo, + 'page_ids': page_ids, + 'page_number': page_ids.index(survey_data['question'].id) + }) + + return { + 'survey_content': survey_content, + 'survey_progress': survey_progress + } @http.route('/survey//', type='http', auth='public', website=True) def survey_display_page(self, survey_token, answer_token, **post): diff --git a/addons/survey/data/survey_demo_certification.xml b/addons/survey/data/survey_demo_certification.xml index 6b85585deb7..e2cf3e0938b 100644 --- a/addons/survey/data/survey_demo_certification.xml +++ b/addons/survey/data/survey_demo_certification.xml @@ -14,6 +14,7 @@ 4ead4bc8-b8f2-4760-a682-1fde8ddb95ac open public + page_per_question scoring_with_answers diff --git a/addons/survey/static/src/js/survey_form.js b/addons/survey/static/src/js/survey_form.js index 9d83703610c..723ae3c30ab 100644 --- a/addons/survey/static/src/js/survey_form.js +++ b/addons/survey/static/src/js/survey_form.js @@ -55,6 +55,10 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ self.preventEnterSubmit = true; } self._initSessionManagement(); + + // Needs global selector as the progress is not within the survey form, but needs to be + // updated at the same time + self.$surveyProgress = $('.o_survey_progress_wrapper'); }); }, @@ -99,8 +103,8 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ /** * 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 - * If checked : enable the comment textarea and focus on it + * If not checked : Clear the comment textarea, hide and disable it + * If checked : enable the comment textarea, show and focus on it * * @private * @param {Event} event @@ -114,11 +118,13 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ if ($otherItem.prop('checked') || $commentInput.hasClass('o_survey_comment')) { $commentInput.enable(); + $commentInput.closest('.o_survey_comment_container').removeClass('d-none'); if ($otherItem.prop('checked')) { $commentInput.focus(); } } else { $commentInput.val(''); + $commentInput.closest('.o_survey_comment_container').addClass('d-none'); $commentInput.enable(false); } @@ -283,6 +289,8 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ this.fadeInOutDelay = 400; } + this.$('.o_survey_main_title:visible').fadeOut(400); + this.preventEnterSubmit = false; this.readonly = false; this._nextScreen( @@ -324,6 +332,10 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ if (this.options.isStartScreen) { route = "/survey/begin"; + // Hide survey title in 'page_per_question' layout: it takes too much space + if (this.options.questionsLayout === 'page_per_question') { + this.$('.o_survey_main_title').fadeOut(400); + } } else { var $form = this.$('form'); var formData = new FormData($form[0]); @@ -396,7 +408,13 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ if (result && !result.error) { this.$(".o_survey_form_content").empty(); - this.$(".o_survey_form_content").html(result); + this.$(".o_survey_form_content").html(result.survey_content); + + if (result.survey_progress && this.$surveyProgress.length !== 0) { + this.$surveyProgress.html(result.survey_progress); + } else if (options.isFinish && this.$surveyProgress.length !== 0) { + this.$surveyProgress.remove(); + } // Hide timer if end screen (if page_per_question in case of conditional questions) if (self.options.questionsLayout === 'page_per_question' && this.$('.o_survey_finished').length > 0) { diff --git a/addons/survey/static/src/scss/survey_form.scss b/addons/survey/static/src/scss/survey_form.scss index 9f76f380101..1bc4cc80c70 100644 --- a/addons/survey/static/src/scss/survey_form.scss +++ b/addons/survey/static/src/scss/survey_form.scss @@ -18,6 +18,19 @@ nav#oe_main_menu_navbar { min-height: 100%; } +.o_survey_progress_wrapper { + min-width: 11rem; + max-width: 15rem; + + .o_survey_progress { + height:0.5em; + } +} + +.o_survey_brand_message { + background-color: rgba(255,255,255,0.7); +} + .o_survey_form, .o_survey_print, .o_survey_session_manage, .o_survey_quick_access { .o_survey_question_error { height: 0px; @@ -42,27 +55,27 @@ nav#oe_main_menu_navbar { .o_survey_question_datetime, .o_survey_question_numerical_box { border: 0px; - border-bottom: 2px solid $primary; + border-bottom: 1px solid $primary; &:disabled { color: black !important; border-color: $gray-600; - border-bottom: 2px solid $gray-600; + border-bottom: 1px solid $gray-600; } &:focus { - border-color: $primary; + box-shadow: none; } } .o_survey_form_date .input-group-append { right: 0; - .input-group-text i { - font-size: large; - } + bottom: 5px; + top: auto; } .o_survey_choice_btn { transition: background-color 0.3s ease; flex: 1 0 300px; + color: $primary; span { line-height: 25px; @@ -83,6 +96,24 @@ nav#oe_main_menu_navbar { } } + input::placeholder, textarea::placeholder { + font-weight: 300; + } + + .o_survey_page_per_question.o_survey_simple_choice.o_survey_minimized_display, + .o_survey_page_per_question.o_survey_multiple_choice.o_survey_minimized_display, + .o_survey_page_per_question.o_survey_numerical_box, + .o_survey_page_per_question.o_survey_date, + .o_survey_page_per_question.o_survey_datetime { + // 'pixel perfect' layouting for choice questions having less than 5 choices in page_per_question mode + // we use media queries instead of bootstrap classes because they don't provide everything needed here + @media (min-width: 768px) { + width: 50%; + position: relative; + left: 25%; + } + } + .o_survey_question_matrix { td { min-width: 100px; @@ -93,8 +124,13 @@ nav#oe_main_menu_navbar { display: inline; } } - .o_survey_choice_key > span > span { - top: 0px; + .o_survey_choice_key { + left: 10px; + right: auto; + top: 12px; + > span > span { + top: 0px; + } } &.o_survey_selected { @@ -106,6 +142,22 @@ nav#oe_main_menu_navbar { } } } + thead { + th:first-child { + border-top-left-radius: .25rem; + } + th:last-child { + border-top-right-radius: .25rem; + } + } + tbody tr:last-child { + th { + border-bottom-left-radius: .25rem; + } + td:last-child { + border-bottom-right-radius: .25rem; + } + } } } @@ -125,23 +177,19 @@ nav#oe_main_menu_navbar { **********************************************************/ .o_survey_form { - min-height: 100%; - - .o_survey_progress { - height:0.5em; - } + min-height: 25rem; .o_survey_choice_btn { cursor: pointer; - background-color: rgba($primary, 0.5); - border: 2px solid $primary; + background-color: rgba($primary, 0.1); + box-shadow: $primary 0px 0px 0px 1px; &.o_survey_selected { - background-color: $primary; + box-shadow: $primary 0px 0px 0px 2px; } &:hover { - background-color: rgba($primary, 0.8); + background-color: rgba($primary, 0.3); .o_survey_choice_key span.o_survey_key { opacity: 1; } @@ -151,19 +199,22 @@ nav#oe_main_menu_navbar { .o_survey_choice_key { width: 25px; height: 25px; - border: 2px solid $primary; + border: 1px solid $primary; span { font-size: smaller; - top: -2px; + top: -1px; &.o_survey_key { width: inherit; right: 10px; - border: 2px solid $primary; + border: 1px solid $primary; border-right: 0px; height: 25px; transition: opacity 0.4s ease; white-space: nowrap; opacity: 0; + span { + top: -2px; + } } } } @@ -318,6 +369,8 @@ nav#oe_main_menu_navbar { background-color: $gray-500; border-color: transparent; cursor: default; + color: white; // not bootstrap to customize for survey_print only + font-weight: bold; // not bootstrap to customize for survey_print only &.bg-success, &.bg-danger { opacity: 0.6; @@ -326,7 +379,7 @@ nav#oe_main_menu_navbar { background-color: $gray-600; opacity: 1; } - i.fa-square, i.fa-circle { + i.fa-square-o, i.fa-circle-thin { display: none; } } diff --git a/addons/survey/views/survey_survey_views.xml b/addons/survey/views/survey_survey_views.xml index af42249dd5b..0be4d340b02 100644 --- a/addons/survey/views/survey_survey_views.xml +++ b/addons/survey/views/survey_survey_views.xml @@ -14,11 +14,11 @@