From 6904ea15bcad4cc9d7318335058e25cff13286fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B1=E5=8D=9A=E4=BA=9E?= Date: Thu, 8 Jul 2021 21:31:27 +0800 Subject: [PATCH] Add some feature and fix RWD bug --- app/assets/javascripts/survey-front-form.js | 24 ++ app/assets/javascripts/survey.js | 143 ++++++- app/assets/javascripts/trigger_option.js | 49 +++ app/assets/stylesheets/questionnaire.css | 86 +++- .../stylesheets/survey-result-chart.css | 12 + app/assets/stylesheets/survey.css.scss | 27 ++ app/controllers/admin/surveys_controller.rb | 53 +-- app/controllers/surveys_controller.rb | 73 +++- app/helpers/surveys_helper.rb | 235 +++++++++++ app/models/questionnaire_survey.rb | 76 ++-- app/models/survey_answer.rb | 5 +- app/models/survey_pagination.rb | 14 + app/models/survey_question.rb | 62 +++ app/models/survey_question_option.rb | 24 +- app/models/survey_question_option_level2.rb | 20 + app/models/survey_question_radiogroup.rb | 5 + app/models/survey_section.rb | 1 + app/views/admin/surveys/_form.html.erb | 12 +- app/views/admin/surveys/_questions.html.erb | 64 ++- .../admin/surveys/_section_form.html.erb | 35 +- .../admin/surveys/_selectable_question.erb | 29 ++ app/views/admin/surveys/answer_set.html.erb | 48 ++- app/views/admin/surveys/export.xlsx.axlsx | 95 ----- .../admin/surveys/pagination_setting.erb | 177 ++++++++ app/views/admin/surveys/set_sections.html.erb | 7 +- app/views/survey_export/export.xlsx.axlsx | 73 +--- app/views/surveys/result.html.erb | 267 ++++++++++-- app/views/surveys/show.html.erb | 394 ++++++++++++------ config/locales/en.yml | 58 ++- config/locales/zh_tw.yml | 53 ++- config/routes.rb | 2 + lib/survey/engine.rb | 8 + lib/tasks/survey_tasks.rake | 26 +- 33 files changed, 1777 insertions(+), 480 deletions(-) create mode 100644 app/assets/javascripts/survey-front-form.js create mode 100644 app/assets/javascripts/trigger_option.js create mode 100644 app/assets/stylesheets/survey-result-chart.css create mode 100644 app/helpers/surveys_helper.rb create mode 100644 app/models/survey_pagination.rb create mode 100644 app/models/survey_question_option_level2.rb create mode 100644 app/views/admin/surveys/_selectable_question.erb delete mode 100644 app/views/admin/surveys/export.xlsx.axlsx create mode 100644 app/views/admin/surveys/pagination_setting.erb diff --git a/app/assets/javascripts/survey-front-form.js b/app/assets/javascripts/survey-front-form.js new file mode 100644 index 0000000..4c79f1c --- /dev/null +++ b/app/assets/javascripts/survey-front-form.js @@ -0,0 +1,24 @@ +function repeat_string(str,num){ + var tmp=""; + for (var i=0;i0 && $level2.length==0){ + $level1.hide() + } } else if( option.data( "question-option" ) == "new"){ option.remove(); + if ($level1.length>0 && $level2.length==0){ + $level1.remove() + } } } @@ -142,11 +167,48 @@ function editQuestion (dataArray){ }) }else if(d.type == 6){ onQuestionTypeChanged( $(".questions .field-type:eq("+ i +")"), d.type ); + }else if(d.type == 7){ + onQuestionTypeChanged( $(".questions .field-type:eq("+ i +")"), d.type ); + var $add_btn = $(".questions .field-type:eq("+ i +") .options .add-btn") + $.each(d.survey_question_options,function ( x, data ){ + var level1 = parse_2_level_options( l, x, data ); + level1.insertBefore($add_btn); + }) } l++; }) } +function parse_2_level_options( l, x, data ){ + var level1 = $('#template-survery-option').tmpl(setEditQuestionAttributes( l, "", data, x, "options" )) + var level2 = $('#template-survery-option-level2-wrapper').tmpl() + var wrapper = $('#template-survery-option-leve11-wrapper').tmpl(setEditQuestionAttributes( l, "", data, x, "options" )); + wrapper.attr('data-index',x) + var level2_controls = level2.find('.controls .add-target') + if (data.level2){ + $.each(data.level2.reverse(),function ( level2_x, level2_data ){ + var level2_child = $('#template-survery-option').tmpl(setEditQuestionAttributes( l, "", level2_data, x+"][level2]["+level2_x, "options" )) + level2_controls.prepend(level2_child) + }) + }else{ + var level2_child = $('#template-survery-option').tmpl(setData(l, "", x+"][level2]["+level2_x, "options" )) + level2_controls.prepend(level2_child); + } + wrapper.find('.level1_wrapper').prepend(level1) + wrapper.append(level2) + return wrapper +} +function add_2_level_options(_index, _i, _className){ + var level1 = $('#template-survery-option').tmpl(setData(_index, "", _i, _className)); + var level2 = $('#template-survery-option-level2-wrapper').tmpl() + var level2_child = $('#template-survery-option').tmpl(setData(_index, "", _i+"][level2][0", _className)) + level2.find('.controls .add-target').prepend(level2_child); + var wrapper = $('#template-survery-option-leve11-wrapper').tmpl(setData(_index, "", _i, _className)); + wrapper.attr('data-index',_i) + wrapper.find('.level1_wrapper').prepend(level1) + wrapper.append(level2) + return wrapper +} function onQuestionTypeChanged ( $fieldType, _val ){ if(_val < 2) { $fieldType.fadeOut(300); @@ -157,7 +219,30 @@ function onQuestionTypeChanged ( $fieldType, _val ){ } else { $fieldType.fadeIn(300); $fieldType.next(".date-format").fadeOut(300); - if(_val < 5) { + if (_val == 7){ + var $input_append = $fieldType.find('.control-group.options .add-target').eq(0).children('.input-append') + if ($input_append.length!=0){ + var children_list = $input_append.eq(0).parent().children() + var _index = $input_append.eq(0).parents('.attributes').eq(0).data('index') + $.each($input_append,function(){ + var _i = children_list.index($(this)) + var wrapper = $('#template-survery-option-leve11-wrapper').tmpl(setData(_index, "", _i, 'options')); + wrapper.find('.level1_wrapper').prepend($(this).clone()) + wrapper.attr('data-index',_i) + var level2 = $('#template-survery-option-level2-wrapper').tmpl() + var level2_child = $('#template-survery-option').tmpl(setData(_index, "", _i+"][level2][0", 'options')) + level2.find('.controls .add-target').prepend(level2_child) + wrapper.append(level2) + $(this).replaceWith(wrapper) + }) + } + $fieldType.find('.level2').removeClass('hide') + $fieldType.find('.question_type_wrapper').removeClass('hide') + }else{ + $fieldType.find('.level2').addClass('hide') + $fieldType.find('.question_type_wrapper').addClass('hide') + } + if(_val < 5 || _val == 7) { $fieldType.find('.rgl, hr').addClass('hide').siblings('.allow').removeClass('hide'); } else { $fieldType.find('.rgl, hr').removeClass('hide').siblings('.allow').removeClass('hide'); @@ -198,6 +283,7 @@ $(function() { checkQuestionsLength(); textareaResizable(); // from textarea-lang-btn.js l += 1; + $(document).trigger('ready') }); $('.questions').on('change', '.type-selector', function(event) { @@ -273,8 +359,23 @@ $(function() { var _i = $(this).closest('.control-group').data('index') || 0, _className = $(this).closest('.control-group').attr('class').match(/options|rgl/g)[0], _index = $(this).closest('.attributes').data().index, - _length = $(this).closest('.add-btn').siblings('.input-append').length; - $('#template-survery-option').tmpl(setData(_index, "", _i, _className)).insertBefore($(this).closest('.add-btn')); + $add_btn = $(this).closest('.add-btn'), + _length = $add_btn.siblings('.input-append').length, + _form_type = parseInt($(this).parents('.attributes-body').eq(0).find('.type-selector').val()); + var option_html; + if (_form_type == 7){ + if (!$add_btn.hasClass('level2')){ + _i = $(this).parents('.add-target').eq(0).find('.level1').length + option_html = add_2_level_options(_index, _i, _className) + }else{ + _i = $(this).parents('.level1').data('index') + var level2_index = $add_btn.parents('.add-target').eq(0).children('.input-append').length + option_html = $('#template-survery-option').tmpl(setData(_index, "", _i+"][level2]["+level2_index, _className)); + } + }else{ + option_html = $('#template-survery-option').tmpl(setData(_index, "", _i, _className)); + } + option_html.insertBefore($(this).closest('.add-btn')); $(this).closest('.add-target').find('.input-append').find('.remove-input').removeClass('hide').prev().removeClass('last'); _i += 1 $(this).closest('.control-group').data('index', _i); diff --git a/app/assets/javascripts/trigger_option.js b/app/assets/javascripts/trigger_option.js new file mode 100644 index 0000000..59a1f2d --- /dev/null +++ b/app/assets/javascripts/trigger_option.js @@ -0,0 +1,49 @@ +function get_uniq(arr){ + return arr.filter(function (value, index, self) { + return self.indexOf(value) === index; + }) +} +$(document).on('ready',function() { + var $target + $target = $('.select_trigger') + var change_eles = [] + $.each($target,function(){ + var e = $(this).attr('data-trigger'), + p = $(this).attr('data-parent'), + ele = $(this).parents(p).eq(0).find(e), + trigger_keys = $(this).attr('for').split('|'), + $this = $(this); + if (!change_eles.includes(ele[0])){ + change_eles.push(ele[0]) + ele.off('change') + } + ele.change(function(){ + var value = null; + if ($(this).prop("tagName").toUpperCase()=='INPUT'){ + value = $(this).filter(":checked").val() + }else{ + value = $(this).val() + } + if (trigger_keys.includes(value)){ + $this.removeClass('hide') + }else{ + $this.addClass('hide') + } + }).trigger('change') + }) + $target = $('input[data-div]'); + $target.off('change') + $target.change(function(){ + var $child = $(this).parents('div.attributes-body').eq(0).find('.'+$(this).data('div')) + if ($(this).prop('checked')){ + $child.removeClass('hide') + }else{ + $child.addClass('hide') + } + }) + $target.trigger('change') + $target.parents('label.float-right').css('float','right') +}) +$(function(){ + $(document).trigger('ready') +}) \ No newline at end of file diff --git a/app/assets/stylesheets/questionnaire.css b/app/assets/stylesheets/questionnaire.css index a61dc5c..0bda975 100644 --- a/app/assets/stylesheets/questionnaire.css +++ b/app/assets/stylesheets/questionnaire.css @@ -1,5 +1,5 @@ .o-question { - font-size: 15px; + font-size: 1em; } .o-question input[type=checkbox], .o-question input[type=radio] { margin: 0; @@ -25,7 +25,7 @@ } .o-question-list > li { margin: 0 0 0 40px; - padding: 16px 0; + padding-bottom: 1em; border-top: solid 1px #eee; position: relative; } @@ -148,3 +148,85 @@ padding: 20px; background-color: #f6f6f6; } +ul.float-left.o-question-group.view-list > li{ + display: inline-block; + margin: 0.2em 0; + padding-left: 0.5em; +} +ul.float-left.o-question-group.view-list > li label { + margin: 0; +} +li.question-item{ + position: relative; +} +input.question-checkbox{ + position: absolute; + left: -2.5em; + top: 0.55em; +} +.o-question-title textarea{ + min-width: 76%; + min-height: 10em; + margin-left: 1em; + margin-top: 1.1em; +} +.double-level td{ + vertical-align: top; +} +.double-level .o-question-option{ + white-space: nowrap; +} +.section-header{ + border: 0.1px dashed #cecece; + padding-bottom: 1.2em; + margin-bottom: 1.2em; +} +.section-header .header-wrapper{ + background-color: #cecece; + color: #5c5c5c; + min-height: 80px; + padding: 0.7em; + margin-bottom: 1em; +} + +.section-header .header-wrapper .section-title{ + margin-bottom: 0.3em; + font-size: 1.2em; +} +ol.o-question-list li.question-item{ + margin-left: 3em; +} +.question-number{ + margin-left: -1em; +} +@media (max-width: 767px){ + ol.o-question-list li.question-item{ + margin-left: 1em; + list-style-position: inside; + } + input.question-checkbox{ + left: -1em; + } + li > .o-question-title{ + vertical-align: middle; + max-width: calc(100% - 1em); + margin-bottom: 0.25em; + } + .question-number{ + margin-left: 0em; + } +} +label.custom_option{ + padding-right: 0.5em; +} +.level2-list>*:not(:last-child) { + margin-right: 1em; +} +.question-item{ + list-style: none; +} +.error_field { + -webkit-box-shadow: 0px 0px 0px 0.2em #e339a1; + -moz-box-shadow: 0px 0px 0px 0.2em #e339a1; + box-shadow: 0px 0px 0px 0.2em #e339a1; +} diff --git a/app/assets/stylesheets/survey-result-chart.css b/app/assets/stylesheets/survey-result-chart.css new file mode 100644 index 0000000..11750f5 --- /dev/null +++ b/app/assets/stylesheets/survey-result-chart.css @@ -0,0 +1,12 @@ +g[class^="raphael-group"] g[pointer-events="bounding-box"] { + display: none; +} +.o-question ol{ + padding: 0; +} +.o-question li{ + list-style: none; +} +.o-question dt, .o-question dd{ + text-align: center; +} \ No newline at end of file diff --git a/app/assets/stylesheets/survey.css.scss b/app/assets/stylesheets/survey.css.scss index ea98885..c70cf8e 100644 --- a/app/assets/stylesheets/survey.css.scss +++ b/app/assets/stylesheets/survey.css.scss @@ -1,3 +1,30 @@ // Place all the styles related to the survey controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ +.select_trigger,.question_type_wrapper,.custom_option_div{ + display: inline-flex; + align-items: center; + padding-left: 1em; + flex-wrap: wrap; + label.radio { + margin: 0 0.2em; + } +} +.level1_wrapper{ + display: flex; + flex-wrap: wrap; + align-items: center; +} +.type-selector{ + padding-right: 1em; +} +label.checkbox{ + margin: 0; +} +.custom_option_div { + padding-left: 0px; + margin-top: 2em; + label.checkbox { + padding-right: 1em; + } +} \ No newline at end of file diff --git a/app/controllers/admin/surveys_controller.rb b/app/controllers/admin/surveys_controller.rb index 364c999..2d95401 100644 --- a/app/controllers/admin/surveys_controller.rb +++ b/app/controllers/admin/surveys_controller.rb @@ -10,12 +10,13 @@ class Admin::SurveysController < OrbitAdminController end def index - @filter_fields = {} + @categories = current_user.approved_categories.select{|c| c.module_app_id == @module_app.id} rescue [] + @filter_fields = filter_fields(@categories,[]) @table_fields = [:title, 'survey.postdate', 'survey.deadline', 'survey.results_count', 'survey.update_user'] !params[:sort].blank? ? sort = {params[:sort].to_sym=>params[:order]} : sort = {:postdate=>"desc"} - @surveys = QuestionnaireSurvey.all.order_by(sort) + @surveys = QuestionnaireSurvey.all.order_by(sort).with_categories(filters("category")) @surveys = search_data(@surveys,[:title]).page(params[:page]).per(10) @@ -73,26 +74,7 @@ class Admin::SurveysController < OrbitAdminController @primary_locale = I18n.locale.to_s @secondary_locale = (I18n.locale == :zh_tw) ? "en" : "zh_tw" - @sqs = [] - @survey.survey_questions.each do |sq| - sq['title_translations'] = sq.title_translations - sq['description_translations'] = sq.description_translations - sq['qid'] = sq.id.to_s - temp = [] - sq.survey_question_options.each do |sqo| - sqo['name_translations'] = sqo.name_translations - sqo['qid'] = sqo.id.to_s - temp << sqo - end - temp = [] - sq.survey_question_radiogroups.each do |sqr| - sqr['name_translations'] = sqr.name_translations - sqr['qid'] = sqr.id.to_s - temp << sqr - end - sq.survey_question_radiogroups = temp - @sqs << sq - end + @sqs = @survey.survey_questions.as_json end def update @@ -155,9 +137,14 @@ class Admin::SurveysController < OrbitAdminController title = @survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'') f = "public/uploads/survey_export/#{@survey.id}/#{title}.xlsx" File.delete(f) if File.exists?(f) - + I18n.locale = locale Thread.new do - system "rake survey_tasks:prepare_download[#{@survey.id}] >> #{Rails.root}/log/rake.log &" + begin + SurveysHelper.generate_xlsx(@survey.id,locale) + rescue => e + puts [e,e.backtrace] + end + #system "rake survey_tasks:prepare_download[#{@survey.id}] >> #{Rails.root}/log/rake.log &" end render :json => {"success" => true, "title" => title}.to_json @@ -183,6 +170,24 @@ class Admin::SurveysController < OrbitAdminController @survey = QuestionnaireSurvey.find(params[:id]) end + def pagination_setting + @survey = QuestionnaireSurvey.find(params[:id]) + @min_section = 1 + @survey_sections_len = @survey.survey_sections.count + @max_section = @survey_sections_len + if @max_section<@min_section + @max_section = @min_section + end + @pagination_settings = @survey.survey_paginations + end + + def save_pagination_setting + @survey = QuestionnaireSurvey.find(params[:id]) + survey_params = params.require(:survey).permit! + @survey.update_attributes(survey_params) + redirect_to set_sections_admin_survey_path(params[:id]) + end + def edit_section @section = SurveySection.find(params[:id]) @survey = @section.questionnaire_survey diff --git a/app/controllers/surveys_controller.rb b/app/controllers/surveys_controller.rb index 0405762..d2b12ef 100644 --- a/app/controllers/surveys_controller.rb +++ b/app/controllers/surveys_controller.rb @@ -106,19 +106,29 @@ class SurveysController < ApplicationController answer = params[:answer] @answer_model = @survey.survey_answers.new @answer_model.user = current_user.id if !current_user.nil? + @answer_model.select_question = answer['select_question'].values.flatten unless answer['select_question'].blank? @survey.survey_questions.each do |question| qid = question.id.to_s + if question.selectable_question && @answer_model.select_question.exclude?(qid) + next + end if question.is_required && answer[qid].blank? && !@survey.jump_mode #&& (! @survey.jump_mode || ( @survey.jump_mode && question.jumpable? ) ) @answer_model.errors.add question.title, t('survey_question.required_error') else case question.type when SurveyQuestion::Radio, SurveyQuestion::Select - if question.custom_option && answer[qid] == 'custom_option' + if answer[qid] == 'custom_option' && question.custom_option_new_option @answer_model[qid] = answer[qid + '_custom_option'] else if answer[qid] - opt = question.survey_question_options.find(answer[qid]) - @answer_model[qid] = opt.name + oid = answer[qid] + opt = question.survey_question_options.find(oid) + tmp = {value: opt.name_translations} + tmp['oid'] = oid + if question.custom_option_each_option && !answer["#{qid}_#{answer[qid]}_custom_option"].blank? + tmp['other'] = answer["#{qid}_#{answer[qid]}_custom_option"] + end + @answer_model[qid] = tmp p = (opt.points == nil ? 0 : opt.points) rescue 0 total = total + p individual_total << p @@ -130,28 +140,33 @@ class SurveysController < ApplicationController t = 0 answer[qid].each do |oid, value| if value.to_i != 0 - if question.custom_option && oid == 'custom_option' - @answer_model[qid].push answer[qid + '_custom_option'] + if oid == 'custom_option' && question.custom_option_new_option + @answer_model[qid] << answer[qid + '_custom_option'] else opt = question.survey_question_options.find(oid) - @answer_model[qid].push opt.name + tmp = {'value' => opt.name_translations} + tmp['oid'] = oid + if question.custom_option_each_option && !answer["#{qid}_#{oid}_custom_option"].blank? + tmp['other'] = answer["#{qid}_#{oid}_custom_option"] + end + @answer_model[qid] << tmp p = (opt.points == nil ? 0 : opt.points) rescue 0 total = total + p t = t + p end end end - individual_total << p + individual_total << t end when SurveyQuestion::Radiogroup @answer_model[qid] = {} options = Hash[question.survey_question_options.collect{|o| [ o.id.to_s, (o.points.nil? ? 0 : o.points) ] }] - radiogroups = Hash[question.survey_question_radiogroups.collect{|rg| [ rg.id.to_s, rg.name] }] + radiogroups = Hash[question.survey_question_radiogroups.collect{|rg| [ rg.id.to_s, rg.name_translations] }] if answer[qid] t = 0 answer[qid].each do |oid, value| unless value.blank? - @answer_model[qid][oid] = radiogroups[value] + @answer_model[qid][oid] = {rgid: value, value: radiogroups[value]} total = total + options[oid] t = t + options[oid] else @@ -159,7 +174,7 @@ class SurveysController < ApplicationController @answer_model.errors.add question.title, t('survey_question.required_error') end end - if question.custom_option + if question.custom_option_each_option unless answer[oid]["custom_group_field"].blank? @answer_model[qid]["#{oid}_custom_group_field"] = answer[oid]["custom_group_field"] end @@ -167,9 +182,41 @@ class SurveysController < ApplicationController end individual_total << t end + if question.custom_option_new_option && !answer[qid+ '_custom_option'].blank? + @answer_model[qid]["custom_option"] = answer[qid+ '_custom_option'] + end when SurveyQuestion::Oneline, SurveyQuestion::Multiline, SurveyQuestion::DateTime @answer_model[qid] = answer[qid] individual_total << 0 + when SurveyQuestion::DoubleLevelOption + @answer_model[qid] = [] + if answer[qid] + t = 0 + answer[qid].each do |oid| + if oid == 'custom_option' && question.custom_option_new_option + @answer_model[qid] << answer[qid + '_custom_option'] + else + opt = question.survey_question_options.find(oid) + tmp = {'level1' => opt.name_translations} + tmp['level1_id'] = oid + if question.custom_option_each_option && !answer["#{qid}_#{oid}_custom_option"].blank? + tmp['other'] = answer["#{qid}_#{oid}_custom_option"] + end + p = (opt.points == nil ? 0 : opt.points) rescue 0 + opt2_names = Array(answer["#{qid}_#{oid}"]).collect do |o2id| + opt2 = opt.level2.find(o2id) + p += opt2.points.to_i + opt2.name_translations + end + tmp['level2'] = opt2_names + tmp['level1_ids'] = Array(answer["#{qid}_#{oid}"]) + @answer_model[qid] << tmp + total = total + p + t = t + p + end + end + individual_total << t + end end end end @@ -204,7 +251,11 @@ class SurveysController < ApplicationController # survey.result_type = QuestionnaireSurvey::ResultChart if params[:force_chart] case survey.result_type when QuestionnaireSurvey::ResultChart - chart_data, survey_questions, survey_answers = survey.generate_chart_data + begin + chart_data, survey_questions, survey_answers = survey.generate_chart_data + rescue => e + puts [e,e.backtrace] + end end { diff --git a/app/helpers/surveys_helper.rb b/app/helpers/surveys_helper.rb new file mode 100644 index 0000000..665d895 --- /dev/null +++ b/app/helpers/surveys_helper.rb @@ -0,0 +1,235 @@ +module SurveysHelper + QuestionTypeMap = ['radio','check','title'] + QuestionTypeOptionMap = ['radio','check'] + SelectableQuestionTypeMap = ['check','radio'] + CustomOptionTypeMap = ['for_each_option','new_option'] + OptionLayoutTypeMap = ['list_each_option_for_one_line','continuous_list_arrangement'] + def self.set_locale(locale) + @locale = locale + @use_custom_option_title = I18n.t('survey_question.use_custom_option') + end + + def self.get_locale(locale) + locale = locale || @locale || I18n.locale + if defined?(@locale).nil? + self.set_locale(locale) + end + locale + end + + def self.parse_value(answer,locale=nil) + locale = self.get_locale(locale) + tmp = self.parse_exel_value(answer,locale: locale) + tmp[1].nil? ? tmp[0] : "#{tmp[0]}(#{tmp[1]})" + end + + def self.parse_checkbox_value_html(answer,locale=nil) + locale = self.get_locale(locale) + Array(answer).collect do |v| + self.parse_value(v['value'],locale) + end.join(", ") + end + + def self.convert_bool_to_exel_value(flag) + flag ? '1' : '' + end + + def self.parse_exel_value(answer,xargs) + locale = xargs[:locale] + locale = self.get_locale(locale) + options = xargs[:options] + chart_data = xargs[:chart_data] + use_custom_option = xargs[:use_custom_option] + case answer + when BSON::Document + if options + values = options.collect do |name,id| + flag = (id==answer['oid']) + if flag + chart_data[name] ||= 0 + chart_data[name] += 1 + end + end + if use_custom_option + values << answer['other'] + end + else + values = [answer['value'][locale],answer['other']].compact + end + else + if options + flag = false + if answer.nil? + values = options.map{|name,id| ''} + else + values = options.collect do |name,id| + flag = (name==answer) + if flag + chart_data[name] ||= 0 + chart_data[name] += 1 + end + convert_bool_to_exel_value(flag) + end + end + if !flag + if use_custom_option + values << answer + end + chart_data[@use_custom_option_title] ||= 0 + chart_data[@use_custom_option_title] += 1 + elsif use_custom_option + values << '' + end + else + values = [answer] + end + end + values + end + + def self.parse_exel_checkbox_value(answers,xargs) + locale = xargs[:locale] + locale = self.get_locale(locale) + options = xargs[:options] + chart_data = xargs[:chart_data] + use_custom_option = xargs[:use_custom_option] + answers = Array(answers) + no_value_flag = true + values = options.collect do |name,id| + flag = false + answers.each_with_index do |answer,i| + case answer + when BSON::Document + flag = (id==answer['oid']) + else + flag = (name==answer) + end + if flag + no_value_flag = false + chart_data[name] ||= 0 + chart_data[name] += 1 + answers.delete_at(i) + break + end + end + convert_bool_to_exel_value(flag) + end + if use_custom_option + if no_value_flag + chart_data[@use_custom_option_title] ||= 0 + chart_data[@use_custom_option_title] += 1 + end + values << answers.join(',') + end + values + end + + def self.parse_exel_rg_value(answers,xargs) + locale = xargs[:locale] + locale = self.get_locale(locale) + options = xargs[:options] + chart_data = xargs[:chart_data] + use_custom_option = xargs[:use_custom_option] + radiogroups = xargs[:radiogroups] + + values = [] + options.each do |name,opt_id| + chart_data[opt_id] ||= {} + answer = answers.blank? ? nil : answers[opt_id] + radiogroups.each do |rg_name,rg_id| + flag = (answer.class == BSON::Document && answer['rgid']==rg_id) || (answer == rg_name) + values << self.convert_bool_to_exel_value(flag) + if flag + chart_data[opt_id][rg_name] ||= 0 + chart_data[opt_id][rg_name] += 1 + end + end + end + if use_custom_option + values << answers["custom_option"].to_s + end + values + end + + def self.parse_double_level_value(answer,other_title,locale=nil) + locale = self.get_locale(locale) + case answer + when BSON::Document + level1 = answer['level1'][locale] + level2 = answer['level2'].collect{|v| v[locale]}.join(', ') + other = answer['other'].blank? ? '' : ", #{level1}-#{other_title}: #{answer['other']}" + "#{level1}: #{level2}#{other}" + else + answer + end + end + + def self.parse_exel_double_level_value(answers,xargs) + other_title = xargs[:other_title] + use_custom_option = xargs[:use_custom_option] + locale = xargs[:locale] + chart_data = xargs[:chart_data] + locale = self.get_locale(locale) + values = [] + custom_option_value = nil + answers.each do |answer| + case answer + when BSON::Document + level1 = answer['level1'][locale] + chart_data[level1] ||= {value: 0,children: {}} + chart_data[level1][:value] += 1 + level2 = answer['level2'].collect do |v| + tmp = v[locale] + chart_data[level1][:children][tmp] ||= 0 + chart_data[level1][:children][tmp] += 1 + tmp + end.join(', ') + other = answer['other'].blank? ? '' : ", #{level1}-#{other_title}: #{answer['other']}" + values << "#{level1}: #{level2}#{other}" + else + custom_option_value = answer + end + end + values = [values.join("\r\n")] + if use_custom_option + chart_data[other_title] ||= {value: 0,children: {}} + chart_data[other_title][:value] += 1 + chart_data[other_title][:children][other_title] ||= 0 + chart_data[other_title][:children][other_title] += 1 + values << custom_option_value + end + values + end + + def self.generate_xlsx(id,locale) + def self.remove_illegal_utf8(str) + if String.method_defined?(:encode) + str.encode!('UTF-8', 'UTF-8', :invalid => :replace) + else + ic = Iconv.new('UTF-8', 'UTF-8//IGNORE') + str = ic.iconv(str) + end + str + end + I18n.with_locale(locale) do + survey = QuestionnaireSurvey.find(id) + puts survey.inspect + chart_data, survey_questions, survey_answers = survey.generate_chart_data + ac = ActionController::Base.new() + xlsx = ac.render_to_string handlers: [:axlsx], + formats: [:xlsx], + template: "survey_export/export", + locals: {survey: survey, + survey_questions: survey_questions, + survey_answers: survey_answers, + } + dirname = "public/uploads/survey_export/#{id}" + FileUtils.mkdir_p(dirname) unless File.exists?(dirname) + f = "#{dirname}/#{survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')}.xlsx" + file = File.open(f, "w") + xlsx.force_encoding("utf-8") + file.write(xlsx) + puts 'success' + end + end +end \ No newline at end of file diff --git a/app/models/questionnaire_survey.rb b/app/models/questionnaire_survey.rb index be7e58f..d4a7e4f 100644 --- a/app/models/questionnaire_survey.rb +++ b/app/models/questionnaire_survey.rb @@ -9,6 +9,7 @@ class QuestionnaireSurvey ResultExtern = 1 ResultFile = 2 ResultCriteria = 3 + include OrbitCategory::Categorizable scope :can_display, ->{where(is_hidden: false)} @@ -46,6 +47,9 @@ class QuestionnaireSurvey before_save :check_deadline#, :update_avliable_language + has_many :survey_paginations, :autosave => true, :dependent => :destroy + accepts_nested_attributes_for :survey_paginations, :allow_destroy => true + def update_user User.find(update_user_id) rescue nil end @@ -87,55 +91,59 @@ class QuestionnaireSurvey def generate_chart_data survey_questions = self.survey_questions.all - survey_answers = self.survey_answers.all + survey_answers = self.survey_answers.all.order_by(created_at: :desc) chart_data = {} + answers =(0...survey_answers.count).map{{}} + SurveysHelper.set_locale(I18n.locale) survey_questions.each do |question| qid = question.id.to_s - options = question.survey_question_options.map(&:name) + use_custom_option = question.custom_option_new_option + chart_data[qid] = {} case question.type when SurveyQuestion::Radio, SurveyQuestion::Select - chart_data[qid] = {} - answers = survey_answers.each do |answer| - if answer[qid] - this_answer = answer[qid] - unless options.include? this_answer - this_answer = I18n.t('survey_question.use_custom_option') - end - chart_data[qid][this_answer] ||= 0 - chart_data[qid][this_answer] += 1 - end + options = question.survey_question_options.map{|v| [v.name,v.id.to_s]} + survey_answers.each_with_index do |answer,i| + answers[i][qid] = SurveysHelper.parse_exel_value(answer[qid], + options: options, + chart_data: chart_data[qid], + use_custom_option: use_custom_option) end when SurveyQuestion::Check - chart_data[qid] = {} - answers = survey_answers.each do |answer| - if answer[qid] - answer[qid].each do |option| - this_answer = option - unless options.include? this_answer - this_answer = I18n.t('survey_question.use_custom_option') - end - chart_data[qid][this_answer] ||= 0 - chart_data[qid][this_answer] += 1 - end - end + options = question.survey_question_options.map{|v| [v.name,v.id.to_s]} + survey_answers.each_with_index do |answer,i| + answers[i][qid] = SurveysHelper.parse_exel_checkbox_value(answer[qid], + options: options, + chart_data: chart_data[qid], + use_custom_option: use_custom_option) end when SurveyQuestion::Radiogroup - chart_data[qid] = {} - answers = survey_answers.each do |answer| - if answer[qid] - answer[qid].each do |option, group| - chart_data[qid][option] ||= {} - chart_data[qid][option][group] ||= 0 - chart_data[qid][option][group] += 1 - end - end + options = question.survey_question_options.map{|v| [v.name,v.id.to_s]} + radiogroups = question.survey_question_radiogroups.map{|v| [v.name,v.id.to_s]} + survey_answers.each_with_index do |answer,i| + answers[i][qid] = SurveysHelper.parse_exel_rg_value(answer[qid], + options: options, + radiogroups: radiogroups, + chart_data: chart_data[qid], + use_custom_option: use_custom_option) + end + when SurveyQuestion::DoubleLevelOption + custom_option_title = question.custom_option_title.to_s + survey_answers.each_with_index do |answer,i| + answers[i][qid] = SurveysHelper.parse_exel_double_level_value(answer[qid], + other_title: custom_option_title, + use_custom_option: use_custom_option, + chart_data: chart_data[qid]) + end + else + survey_answers.each_with_index do |answer,i| + answers[i][qid] = answer[qid] end end end - [chart_data, survey_questions, survey_answers] + [chart_data, survey_questions, answers] end def expired? diff --git a/app/models/survey_answer.rb b/app/models/survey_answer.rb index 245a85b..a88d9d7 100644 --- a/app/models/survey_answer.rb +++ b/app/models/survey_answer.rb @@ -1,11 +1,12 @@ class SurveyAnswer include Mongoid::Document include Mongoid::Timestamps - + include Mongoid::Attributes::Dynamic + field :user, type: BSON::ObjectId field :scored_points, type: Integer, :default => 0 field :individual_total, type: Array, :default => [] - + field :select_question, type: Array, :default => [] belongs_to :questionnaire_survey end \ No newline at end of file diff --git a/app/models/survey_pagination.rb b/app/models/survey_pagination.rb new file mode 100644 index 0000000..f02ecbf --- /dev/null +++ b/app/models/survey_pagination.rb @@ -0,0 +1,14 @@ +class SurveyPagination + include Mongoid::Document + include Mongoid::Timestamps + + field :index, type: Integer + field :start_section, type: Integer + field :end_section, type: Integer + + belongs_to :questionnaire_survey + def as_json(**xargs) + res = super({except: :_id}.merge(xargs)) + res.merge({_id: self.id.to_s}) + end +end \ No newline at end of file diff --git a/app/models/survey_question.rb b/app/models/survey_question.rb index b1e592f..0a15376 100644 --- a/app/models/survey_question.rb +++ b/app/models/survey_question.rb @@ -7,6 +7,7 @@ class SurveyQuestion Select = 4 Radiogroup = 5 DateTime = 6 + DoubleLevelOption = 7 include Mongoid::Document @@ -14,13 +15,21 @@ class SurveyQuestion field :description, :localize => true field :is_required, :type => Boolean field :type, :type => Integer + field :selectable_question, :type => Boolean, :default => false + field :selectable_question_type, :type => Integer, :default => 0 + field :datetime_type # allow custom answer option field :custom_option, :type => Boolean + field :custom_option_type, :type => Array, :default => [1] + field :custom_option_title, :type => String, :localize => true + field :option_layout_type, :type => Integer, :default => 0 field :sequence, :type => Integer, :default => 0 + field :question_type, :type => Integer, :default => 0 + belongs_to :questionnaire_survey embeds_many :survey_question_options embeds_many :survey_question_radiogroups @@ -31,6 +40,10 @@ class SurveyQuestion # default_scope asc(:sequence) default_scope ->{ asc(:sequence) } + before_save do + self.custom_option_type = self.custom_option_type.map(&:to_i) + end + def jumpable? case type when SurveyQuestion::Radio, SurveyQuestion::Select @@ -48,4 +61,53 @@ class SurveyQuestion Hash[survey_question_options.select{ |o| !o.jump_to.blank? }.collect{ |o| [o.id.to_s, o.jump_to] }] end + def custom_option_new_option + self.custom_option && self.custom_option_type.include?(1) + end + + def custom_option_each_option + self.custom_option && self.custom_option_type.include?(0) + end + + def custom_option_title + tmp = super() + tmp.blank? ? I18n.t('survey_question.option_title_default') : tmp + end + + def layout_float + self.option_layout_type==1 + end + + def as_json(**xargs) + res = super({:except =>:survey_question_options}.merge(xargs)) + res.merge({title_translations: self.title_translations, + description_translations: self[:description], + qid: self[:_id].to_s, + survey_question_options: self.survey_question_options.as_json, + custom_option_title_translations: self.custom_option_title_translations}) + end + + def is_selectable_radio + self.selectable_question && self.selectable_question_type==1 + end + + def is_selectable_check + self.selectable_question && self.selectable_question_type==0 + end + + def level1_radio + self.question_type==0 + end + + def level1_check + self.question_type==1 + end + + + #def attributes() + # tmp = super() + # tmp.merge({title_translations: tmp[:title], + # description_translations: tmp[:description], + # qid: tmp[:_id].to_s}) + #end end \ No newline at end of file diff --git a/app/models/survey_question_option.rb b/app/models/survey_question_option.rb index 4682fc2..0908bdc 100644 --- a/app/models/survey_question_option.rb +++ b/app/models/survey_question_option.rb @@ -4,6 +4,28 @@ class SurveyQuestionOption field :name, :localize => true field :jump_to, :default => 0 field :points, :type => Integer, :default => 0 - + field :question_type, :type => Integer, :default => 0 + + embeds_many :level2, class_name: "SurveyQuestionOptionLevel2" + accepts_nested_attributes_for :level2, class_name: "SurveyQuestionOptionLevel2", :allow_destroy => true + embedded_in :survey_question + + #def attributes() + # tmp = super() + # tmp.merge({name_translations: tmp[:name], qid: tmp[:_id].to_s}) + #end + def as_json(**xargs) + res = super({:except =>:level2}.merge(xargs)) + res.merge({name_translations: self.name_translations, qid: self[:_id].to_s, level2: self.level2.as_json}) + end + + + def level2_radio + self.question_type==0 + end + + def level2_check + self.question_type==1 + end end \ No newline at end of file diff --git a/app/models/survey_question_option_level2.rb b/app/models/survey_question_option_level2.rb new file mode 100644 index 0000000..00fd21e --- /dev/null +++ b/app/models/survey_question_option_level2.rb @@ -0,0 +1,20 @@ +class SurveyQuestionOptionLevel2 + include Mongoid::Document + + field :name, :localize => true + field :jump_to, :default => 0 + field :points, :type => Integer, :default => 0 + + embedded_in :level1, class_name: "SurveyQuestionOption" + def serializable_hash(options = nil) + tmp = super(options) + tmp.merge({name_translations: self[:name], qid: self[:_id].to_s}) + tmp + end + + def as_json(**xargs) + res = super + res.merge({name_translations: self.name_translations, qid: self[:_id].to_s}) + end + +end \ No newline at end of file diff --git a/app/models/survey_question_radiogroup.rb b/app/models/survey_question_radiogroup.rb index 1c582e9..bc755fc 100644 --- a/app/models/survey_question_radiogroup.rb +++ b/app/models/survey_question_radiogroup.rb @@ -4,4 +4,9 @@ class SurveyQuestionRadiogroup field :name, :localize => true embedded_in :survey_question + + #def attributes() + # tmp = super() + # tmp.merge({name_translations: tmp[:name], qid: tmp[:_id].to_s}) + #end end \ No newline at end of file diff --git a/app/models/survey_section.rb b/app/models/survey_section.rb index 38d39e8..23acfb9 100644 --- a/app/models/survey_section.rb +++ b/app/models/survey_section.rb @@ -7,6 +7,7 @@ class SurveySection field :order, type: Integer field :start_question, type: Integer field :end_question, type: Integer + field :qnum_mode, type: Integer, default: 0 belongs_to :questionnaire_survey end \ No newline at end of file diff --git a/app/views/admin/surveys/_form.html.erb b/app/views/admin/surveys/_form.html.erb index df25b56..0642691 100644 --- a/app/views/admin/surveys/_form.html.erb +++ b/app/views/admin/surveys/_form.html.erb @@ -2,6 +2,7 @@ <%= stylesheet_link_tag "lib/main-forms" %> <%= stylesheet_link_tag "lib/wrap-nav" %> <%= stylesheet_link_tag "lib/main-list" %> + <%= stylesheet_link_tag "survey" %> <% end %> <% content_for :page_specific_javascript do %> <%= javascript_include_tag "jquery-ui-custom.js" %> @@ -10,6 +11,7 @@ <%= javascript_include_tag "lib/member/textarea-lang-btn.js" %> <%= javascript_include_tag "lib/jquery.tmpl.min.js" %> <%= javascript_include_tag "survey.js" %> + <%= javascript_include_tag "trigger_option.js" %> <% end %> <%= f.error_messages %> @@ -20,8 +22,14 @@

Basic

-
- + + +
+ +
+ <%= select_category(f, @module_app) %> +
+
diff --git a/app/views/admin/surveys/_questions.html.erb b/app/views/admin/surveys/_questions.html.erb index 581e67f..977f43f 100644 --- a/app/views/admin/surveys/_questions.html.erb +++ b/app/views/admin/surveys/_questions.html.erb @@ -52,7 +52,7 @@
- @@ -60,7 +60,9 @@ + + <%= render :partial => 'selectable_question' %>
@@ -99,12 +101,40 @@
+
+ <% SurveysHelper::CustomOptionTypeMap.each_with_index do |key,i| %> + + <% end %> +
+
+
+ +
+
+ <% @site_in_use_locales.each_with_index do |locale, i| %> +
" id="${_custom_option_title_translations[2]+'_<%= locale %>'}"> + +
+ <% end %> +
+
+ <% @site_in_use_locales.each_with_index do |locale, i| %> + " href="${'#'+_custom_option_title_translations[2]+'_<%= locale %>'}" data-toggle="tab"><%= t(locale.to_s) %> + <% end %> +
+
+
+
{{/if}} + + + + + \ No newline at end of file diff --git a/app/views/admin/surveys/_section_form.html.erb b/app/views/admin/surveys/_section_form.html.erb index 025fbf1..e1d87cf 100644 --- a/app/views/admin/surveys/_section_form.html.erb +++ b/app/views/admin/surveys/_section_form.html.erb @@ -51,14 +51,14 @@
- <%= f.label :start_question, t("sruvey.start_question"), :class => "control-label muted" %> + <%= f.label :start_question, t("survey.start_question"), :class => "control-label muted" %>
<% if @section.new_record? %> <% if @survey.survey_sections.count == 0 %> <%= f.number_field :start_question, :min => 1, :max => (@survey.survey_questions.count - 1), :value => (@survey.survey_sections.count + 1) %> <% else %> <% min_value = @survey.survey_sections.last.end_question %> - <%= f.number_field :start_question, :min => (min_value + 1), :max => (@survey.survey_questions.count - 1), :value => (min_value + 1) %> + <%= f.number_field :start_question, :max => (min_value + 1), :min => (@survey.survey_questions.count - 1), :value => (min_value + 1) %> <% end %> <% else %> <% if @survey.survey_sections.count == 0 %> @@ -76,29 +76,34 @@
- <%= f.label :end_question, t("sruvey.end_question"), :class => "control-label muted" %> + <%= f.label :end_question, t("survey.end_question"), :class => "control-label muted" %>
<% if @section.new_record? %> <% if @survey.survey_sections.count == 0 %> - <%= f.number_field :end_question, :min => (@survey.survey_sections.count + 1), :max => @survey.survey_questions.count, :value => (@survey.survey_sections.count + 2) %> + <%= f.number_field :end_question, :min => (@survey.survey_sections.count+1), :max => (@survey.survey_questions.count+2), :value => (@survey.survey_sections.count + 2) %> <% else %> <% min_value = @survey.survey_sections.last.end_question %> - <%= f.number_field :end_question, :min => (min_value + 1), :max => @survey.survey_questions.count, :value => (min_value + 2) %> + <%= f.number_field :end_question, :min => (min_value+1), :max => (min_value + 2), :value => (min_value + 2) %> <% end %> <% else %> <% if @survey.survey_sections.count == 0 %> - <%= f.number_field :end_question, :min => (@survey.survey_sections.count + 1), :max => @survey.survey_questions.count %> + <%= f.number_field :end_question, :min => (@survey.survey_sections.count), :max => @survey.survey_questions.count %> <% else %> <% if @section.order > 0 %> <% min_value = @survey.survey_sections.where(:order => @section.order - 1).first.end_question %> - <%= f.number_field :end_question, :min => (min_value + 2), :max => @survey.survey_questions.count %> + <%= f.number_field :end_question, :min => (min_value + 1), :max => (@survey.survey_questions.count) %> <% else %> - <%= f.number_field :end_question, :min => (@survey.survey_sections.count + 1), :max => @survey.survey_questions.count %> + <%= f.number_field :end_question, :min => 1, :max => (@survey.survey_questions.count) %> <% end %> <% end %> <% end %>
+
+ <%= f.label :qnum_mode, t("survey.question_number_setting"), :class => "control-label muted" %> +
+ <%= f.select :qnum_mode, ['show','disable','restart',].map.with_index{|v,i| [t("survey.#{v}_question_number"),i]} %> +
<%= f.hidden_field :questionnaire_survey_id, :value => @survey.id %> @@ -118,18 +123,18 @@ }) $("#survey_section_end_question").on("change",function(){ var number = parseInt($(this).val()); - if(number > parseInt($(this).attr("max"))){ - $(this).val(current_end_value); - return false; - } + if(number > parseInt($(this).attr("max")) || number < parseInt($(this).attr("min"))){ + $(this).val(current_end_value); + return false; + } }) $("#survey_section_start_question").on("change",function(){ - var number = parseInt($(this).val()) + 1; - if((number - 1) > parseInt($(this).attr("max"))){ + var number = parseInt($(this).val()); + if(number > parseInt($(this).attr("max")) || number < parseInt($(this).attr("min"))){ $(this).val(current_start_value); return false; } - $("#survey_section_end_question").attr("min", number); + $("#survey_section_end_question").attr("min", number+1); if(parseInt($("#survey_section_end_question").val()) < number){ $("#survey_section_end_question").val(number); } diff --git a/app/views/admin/surveys/_selectable_question.erb b/app/views/admin/surveys/_selectable_question.erb new file mode 100644 index 0000000..17ee68a --- /dev/null +++ b/app/views/admin/surveys/_selectable_question.erb @@ -0,0 +1,29 @@ +
+ <% SurveysHelper::QuestionTypeMap.each_with_index do |key,i| %> + + <% end %> +
+
+ <% SurveysHelper::OptionLayoutTypeMap.each_with_index do |key,i| %> + + <% end %> +
+<%= label_tag :selectable_question, :for => nil, :class => 'float-right' do %> + + <%= t('survey_question.selectable_question') %> +<% end %> +
+ +
\ No newline at end of file diff --git a/app/views/admin/surveys/answer_set.html.erb b/app/views/admin/surveys/answer_set.html.erb index d27b871..f894bf2 100644 --- a/app/views/admin/surveys/answer_set.html.erb +++ b/app/views/admin/surveys/answer_set.html.erb @@ -44,7 +44,7 @@ } <% end %> - +<% SurveysHelper.set_locale(I18n.locale) %>

<%= @survey.title %>

@@ -60,25 +60,33 @@
A - <% case sq.type %> - <% when SurveyQuestion::Radio, SurveyQuestion::Select %> - <%= @survey_answer[sq.id.to_s] rescue "" %> - <% when SurveyQuestion::Check %> - <%= @survey_answer[sq.id.to_s].join(", ") rescue "" %> - <% when SurveyQuestion::Radiogroup %> -
- <% sq.survey_question_options.each do |sqo| %> - <% if !@survey_answer[sq.id.to_s].nil? %> - <% if sq.custom_option %> - <%= @survey_answer[sq.id.to_s]["#{sqo.id}_custom_group_field"].blank? ? sqo.name : @survey_answer[sq.id.to_s]["#{sqo.id}_custom_group_field"] %> : <%= @survey_answer[sq.id.to_s][sqo.id.to_s] %>
- <% else %> - <%= sqo.name %> : <%= @survey_answer[sq.id.to_s][sqo.id.to_s] %>
- <% end %> - <% end %> - <% end %> -
- <% when SurveyQuestion::Oneline, SurveyQuestion::Multiline %> - <%= @survey_answer[sq.id.to_s] rescue "" %> + <% case sq.type %> + <% when SurveyQuestion::Radio, SurveyQuestion::Select %> + <%= SurveysHelper.parse_value(@survey_answer[sq.id.to_s]) %> + <% when SurveyQuestion::Check %> + <%= SurveysHelper.parse_checkbox_value_html(@survey_answer[sq.id.to_s]) %> + <% when SurveyQuestion::Radiogroup %> +
+ <% sq.survey_question_options.each do |sqo| %> + <% if !@survey_answer[sq.id.to_s].nil? %> + <% if sq.custom_option_each_option %> + <%= @survey_answer[sq.id.to_s]["#{sqo.id}_custom_group_field"].blank? ? sqo.name : @survey_answer[sq.id.to_s]["#{sqo.id}_custom_group_field"] %> : + <% else %> + <%= sqo.name %> : + <% end %> + <%= SurveysHelper.parse_value(@survey_answer[sq.id.to_s][sqo.id.to_s]) %>
+ <% end %> + <% end %> + <% if sq.custom_option_new_option %> + <%= sq.custom_option_title %> <%= @survey_answer[sq.id.to_s]['custom_option'] %> + <% end %> +
+ <% when SurveyQuestion::Oneline, SurveyQuestion::Multiline %> + <%= @survey_answer[sq.id.to_s] rescue "" %> + <% when SurveyQuestion::DoubleLevelOption %> + + <%= @survey_answer[sq.id.to_s].collect{|v| SurveysHelper.parse_double_level_value(v,sq.custom_option_title.to_s)}.join('
').html_safe %> +
<% end %>
diff --git a/app/views/admin/surveys/export.xlsx.axlsx b/app/views/admin/surveys/export.xlsx.axlsx deleted file mode 100644 index f557e67..0000000 --- a/app/views/admin/surveys/export.xlsx.axlsx +++ /dev/null @@ -1,95 +0,0 @@ -# encoding: utf-8 - -wb = xlsx_package.workbook -wb.add_worksheet(name: remove_illegal_utf8(@survey.title[0..15])) do |sheet| - - row = [] - @survey_questions.each_with_index do |question, i| - if question.type == 2 or question.type == 3 or question.type == 4 - question.survey_question_options.each do |option| - row << "#{i+1}. #{remove_illegal_utf8 question.title} - #{remove_illegal_utf8 option.name}" - end - elsif question.type == 5 - question.survey_question_options.each do |option| - question.survey_question_radiogroups.each do |radiogroup| - row << "#{i+1}. #{remove_illegal_utf8 question.title} - #{remove_illegal_utf8 option.name} - #{remove_illegal_utf8 radiogroup.name}" - end - end - else - row << "#{i+1}. #{remove_illegal_utf8 question.title}" - end - if question.custom_option - row << "#{i+1}. #{remove_illegal_utf8 question.title} - #{t('survey_question.use_custom_option')}" - end - end - - sheet.add_row row - - @survey_answers.each do |answer| - answer_row = [] - @survey_questions.each do |question| - - options = question.survey_question_options.collect{|o| o.name } - - if question.type == 2 or question.type == 4 - - options.collect do |o| - - if !answer[question.id.to_s].blank? && answer[question.id.to_s].include?(o) - answer_row << '1' - else - answer_row << '' - end - - end - - elsif question.type == 3 - - options.collect do |o| - - if !answer[question.id.to_s].blank? && answer[question.id.to_s].include?(o) - answer_row << '1' - else - answer_row << '' - end - end - - elsif question.type == 5 - - question.survey_question_options.each do |option| - question.survey_question_radiogroups.each do |radiogroup| - if !answer[question.id.to_s].blank? && answer[question.id.to_s][option.id.to_s] == radiogroup.name - answer_row << '1' - else - answer_row << '' - end - end - end - - else - if answer[question.id.to_s] - answer_row << remove_illegal_utf8(answer[question.id.to_s]) - else - answer_row << '' - end - end - - if question.custom_option - if !answer[question.id.to_s].blank? - if answer[question.id.to_s].class == Array - answer_row << remove_illegal_utf8((answer[question.id.to_s] - options).join) - elsif answer[question.id.to_s].class == String - answer_row << remove_illegal_utf8(([answer[question.id.to_s]] - options).join) - end - else - answer_row << '' - end - end - end - - sheet.add_row answer_row - - end - -end - diff --git a/app/views/admin/surveys/pagination_setting.erb b/app/views/admin/surveys/pagination_setting.erb new file mode 100644 index 0000000..6c58600 --- /dev/null +++ b/app/views/admin/surveys/pagination_setting.erb @@ -0,0 +1,177 @@ +<% if @survey_sections_len>0 %> +<%= javascript_include_tag "lib/jquery.tmpl.min.js" %> +<%= form_for @survey, :url => {:action => "save_pagination_setting"}, :html => {:class => "form-horizontal main-forms", :id => 'pagination_form',data: {"min-section" => @min_section,"max-section" => @max_section}} do |f| %> +
+ + + + + + + + + +
<%= t('survey.pagination') %><%= t('survey.start_section') %><%= t('survey.end_section') %>
+ + + <%= f.button t('survey.add_pagination'),type: 'button',class: 'btn btn-success add-pagination' %> + <%= f.submit t('submit'), class: 'btn btn-primary' %> +
+<% end %> +<% else %> +

+ <%= t('survey.no_section_hint') %> +

+<% end %> \ No newline at end of file diff --git a/app/views/admin/surveys/set_sections.html.erb b/app/views/admin/surveys/set_sections.html.erb index 9e613eb..a79264a 100644 --- a/app/views/admin/surveys/set_sections.html.erb +++ b/app/views/admin/surveys/set_sections.html.erb @@ -2,8 +2,8 @@ - - + + @@ -27,6 +27,7 @@ \ No newline at end of file diff --git a/app/views/survey_export/export.xlsx.axlsx b/app/views/survey_export/export.xlsx.axlsx index 2cf4b65..cd7e2f3 100644 --- a/app/views/survey_export/export.xlsx.axlsx +++ b/app/views/survey_export/export.xlsx.axlsx @@ -7,87 +7,28 @@ wb.add_worksheet(name: "WorkSheet1") do |sheet| survey_questions.each_with_index do |question, i| if question.type == 2 or question.type == 3 or question.type == 4 question.survey_question_options.each do |option| - row << "#{i+1}. #{remove_illegal_utf8 question.title} - #{remove_illegal_utf8 option.name}" + row << "#{i+1}. #{question.title} - #{option.name}" end elsif question.type == 5 question.survey_question_options.each do |option| question.survey_question_radiogroups.each do |radiogroup| - row << "#{i+1}. #{remove_illegal_utf8 question.title} - #{remove_illegal_utf8 option.name} - #{remove_illegal_utf8 radiogroup.name}" + row << "#{i+1}. #{question.title} - #{option.name} - #{radiogroup.name}" end end else - row << "#{i+1}. #{remove_illegal_utf8 question.title}" + row << "#{i+1}. #{question.title}" end - if question.custom_option - row << "#{i+1}. #{remove_illegal_utf8 question.title} - #{t('survey_question.use_custom_option')}" + if question.custom_option_new_option + row << "#{i+1}. #{question.title} - #{t('survey_question.use_custom_option')}" end end sheet.add_row row - + wrap = wb.styles.add_style alignment: {wrap_text: true} survey_answers.each do |answer| answer_row = [] - survey_questions.each do |question| - options = question.survey_question_options.collect{|o| o.name } - - if question.type == 2 or question.type == 4 - - options.collect do |o| - - if !answer[question.id.to_s].blank? && answer[question.id.to_s].include?(o) - answer_row << '1' - else - answer_row << '' - end - - end - - elsif question.type == 3 - - options.collect do |o| - - if !answer[question.id.to_s].blank? && answer[question.id.to_s].include?(o) - answer_row << '1' - else - answer_row << '' - end - end - - elsif question.type == 5 - - question.survey_question_options.each do |option| - question.survey_question_radiogroups.each do |radiogroup| - if !answer[question.id.to_s].blank? && answer[question.id.to_s][option.id.to_s] == radiogroup.name - answer_row << '1' - else - answer_row << '' - end - end - end - - else - if answer[question.id.to_s] - answer_row << remove_illegal_utf8(answer[question.id.to_s]) - else - answer_row << '' - end - end - - if question.custom_option - if !answer[question.id.to_s].blank? - if answer[question.id.to_s].class == Array - answer_row << remove_illegal_utf8((answer[question.id.to_s] - options).join) - elsif answer[question.id.to_s].class == String - answer_row << remove_illegal_utf8(([answer[question.id.to_s]] - options).join) - end - else - answer_row << '' - end - end - end - - sheet.add_row answer_row + sheet.add_row answer.values.flatten, style: wrap end diff --git a/app/views/surveys/result.html.erb b/app/views/surveys/result.html.erb index 9efe5c4..df525cf 100644 --- a/app/views/surveys/result.html.erb +++ b/app/views/surveys/result.html.erb @@ -1,4 +1,3 @@ - <% data = action_data @survey = data["survey"] @@ -18,18 +17,35 @@ <%= t 'survey.results_count' %>: <%= @survey.survey_answers.count %>
    + <% index = 1 %> <% @survey_questions.each do |question| %> <% case question.type %> <% when SurveyQuestion::Radio, SurveyQuestion::Check, ::SurveyQuestion::Select %>
  1. -
    +
    <%= "#{index}. #{question.title}" %>
    +
    +
    +
  2. + <% index += 1%> <% when SurveyQuestion::Radiogroup %> - <% question.survey_question_options.each_with_index do |option,index| %> -
  3. -
    -
  4. + <% question.survey_question_options.each_with_index do |option,i| %> +
  5. +
    <%= "#{index}. #{question.title} - #{option.name}" %>
    +
    +
    +
    +
  6. + <% index += 1%> <% end %> + <% when SurveyQuestion::DoubleLevelOption %> +
  7. +
    <%= "#{index}. #{question.title}" %>
    +
    +
    +
    +
  8. + <% index += 1%> <% end %> <% end %> @@ -37,44 +53,241 @@ - - + + + <%= stylesheet_link_tag "survey-result-chart.css" %> + <% when QuestionnaireSurvey::ResultExtern %> <% elsif answer_present %> <% end %> @@ -66,16 +79,25 @@
      <% @questions.each_with_index do |question, i| %> - <% header_count = i + 1 %> - <% if headers.include?(header_count) %> -
      - <% section = @sections.where(:start_question => header_count).first %> -
      -
      <%= section.section_title %>
      -
      <%= section.section_description %>
      -
      - <% end %> -
    1. + <% header_count = i + 1 %> + <% if headers.include?(header_count) %> + <% section_index_tmp += 1 + section_index = [section_index_tmp] + %> +
      + <% section = @sections.where(:start_question => header_count).first %> +
      +
      <%= section.section_title %>
      +
      <%= section.section_description %>
      +
      + <% end %> +
    2. + <% if question.is_selectable_radio %> + <%= radio_button_tag "answer[select_question]#{section_index}[]", question.id, nil, :class=> 'question-checkbox' %> + <% elsif question.is_selectable_check %> + <%= check_box_tag "answer[select_question]#{section_index}[]", question.id, false, :class=> 'question-checkbox' %> + <% end %> + <%= qnums[i].nil? ? '' : "#{qnums[i]}. " %> <% label = question.title %> <% if question.is_required %> (*) @@ -92,98 +114,185 @@ <% when SurveyQuestion::Multiline %> <%= f.text_area question.id, :rows => 5, :required => question.is_required %> <% when SurveyQuestion::Radio %> -
        - <% question.survey_question_options.each do |option| %> -
      • - <%= f.radio_button question.id, option.id %> - <%= f.label "#{question.id}_#{option.id}", option.name, :class => 'o-question-option' %> -
      • - <% end %> - <% if question.custom_option %> -
      • - <%= f.radio_button question.id, 'custom_option' %> - <%= f.label "#{question.id}_custom_option", t('survey_question.use_custom_option') + ': ', :class => 'o-question-option' %> - <%= f.text_field "#{question.id}_custom_option" %> -
      • - <% end %> -
      + <% class_ul = question.layout_float ? ' float-left' : '' %> + <%= content_tag :ul, :class => "o-question-group view-list#{class_ul}" do %> + <% question.survey_question_options.each do |option| %> +
    3. + <%= f.radio_button question.id, option.id %> + <%= f.label "#{question.id}_#{option.id}", option.name, :class => 'o-question-option' %> + <% if question.custom_option_each_option %> + <%= f.text_field "#{question.id}_#{option.id}_custom_option",placeholder: question.custom_option_title %> + <% end %> +
    4. + <% end %> + <% if question.custom_option_new_option %> +
    5. + <%= f.radio_button question.id, 'custom_option' %> + <%= f.label "#{question.id}_custom_option", question.custom_option_title + ': ', :class => 'o-question-option custom_option' %> + <%= f.text_field "#{question.id}_custom_option", class: 'custom_option_input' %> +
    6. + <% end %> + <% end %> <% when SurveyQuestion::DateTime %> <%= f.datetime_picker question.id, :no_label => true, :new_record => true, :format => question.datetime_type, :placeholder => question.datetime_type.upcase, :required => question.is_required %> <% when SurveyQuestion::Check %> -
        - <%= f.fields_for "#{question.id}" do |cf| %> - <% question.survey_question_options.each do |option| %> -
      • - <%= cf.check_box option.id %> - <%= cf.label option.id, option.name, :class => 'o-question-option' %> -
      • - <% end %> - <% if question.custom_option %> -
      • - <%= cf.check_box 'custom_option' %> - <%= f.label "#{question.id}_custom_option", t('survey_question.use_custom_option') + ': ', :class => 'o-question-option' %> - <%= f.text_field "#{question.id}_custom_option" %> -
      • - <% end %> - <% end %> -
      - <% when SurveyQuestion::Select %> - <% options = question.survey_question_options.collect {|o| [ o.name, o.id ] } %> - <% if question.custom_option %> - <% options.push [t('survey_question.use_custom_option'), 'custom_option'] %> - <% end %> - <%= f.select question.id, options, {}, :class => 'o-question-group view-dropdown' %> - <% if question.custom_option %> - <%= f.text_field "#{question.id}_custom_option", :class => 'custom_option' %> - <% end %> - <% when SurveyQuestion::Radiogroup %> - <%= f.fields_for "#{question.id}" do |rgf| %> -
Section TitleSection Description<%= t('survey.section_title') %><%= t('survey.section_description') %>
- - - - <% if question.custom_option %> - - <% end %> - <% question.survey_question_radiogroups.each do |radiogroup| %> - - <% end %> - - - - <% question.survey_question_options.each_with_index do |option, j| %> - > - - <% if question.custom_option %> - <%= f.fields_for "#{option.id}" do |oid| %> - - <% end %> - <% end %> - <% question.survey_question_radiogroups.each do |radiogroup| %> - + <% class_ul = question.layout_float ? ' float-left' : '' %> + <%= content_tag :ul, :class => "o-question-group view-list#{class_ul}" do %> + <%= f.fields_for "#{question.id}" do |cf| %> + <% question.survey_question_options.each do |option| %> +
  • + <%= cf.check_box option.id %> + <%= cf.label option.id, option.name, :class => 'o-question-option' %> + <% if question.custom_option_each_option %> + <%= f.text_field "#{question.id}_#{option.id}_custom_option",placeholder: question.custom_option_title %> + <% end %> +
  • <% end %> - - <% end %> - -
    - <%= radiogroup.name %> -
    - <%= option.name %> - - <%= oid.text_field "custom_group_field" %> - - <%= rgf.radio_button option.id, radiogroup.id %> -
    - <% end %> + <% if question.custom_option_new_option %> +
  • + <%= cf.check_box 'custom_option' %> + <%= f.label "#{question.id}_custom_option", question.custom_option_title + ': ', :class => 'o-question-option custom_option' %> + <%= f.text_field "#{question.id}_custom_option", class: 'custom_option_input' %> +
  • + <% end %> + <% end %> + <% end %> + <% when SurveyQuestion::Select %> + <% options = question.survey_question_options.collect {|o| [ o.name, o.id ] } %> + <% if question.custom_option %> + <% options.push [t('survey_question.use_custom_option'), 'custom_option'] %> + <% end %> + <%= f.select question.id, options, {}, :class => 'o-question-group view-dropdown' %> + <% if question.custom_option %> + <%= f.text_field "#{question.id}_custom_option", :class => 'custom_option' %> + <% end %> + <% when SurveyQuestion::Radiogroup %> + <%= f.fields_for "#{question.id}" do |rgf| %> + + + + + <% if question.custom_option_each_option %> + + <% end %> + <% question.survey_question_radiogroups.each do |radiogroup| %> + + <% end %> + + + + <% colspan = question.survey_question_radiogroups.count + (question.custom_option_each_option ? 1 : 0) + 1 %> + <% question.survey_question_options.each_with_index do |option, j| %> + > + + <% if question.custom_option_each_option %> + <%= f.fields_for "#{option.id}" do |oid| %> + + <% end %> + <% end %> + <% question.survey_question_radiogroups.each do |radiogroup| %> + + <% end %> + + <% end %> + <% if question.custom_option_new_option %> + + + + <% end %> + +
    <%= question.custom_option_title %> + <%= radiogroup.name %> +
    + <%= option.name %> + + <%= oid.text_field "custom_group_field" %> + + <%= rgf.radio_button option.id, radiogroup.id %> +
    +
    + <%= question.custom_option_title %> +
    + <%= f.text_area "#{question.id}_custom_option" %> +
    + <% end %> + <% when SurveyQuestion::DoubleLevelOption %> + <%= content_tag :table, :class => "o-question-group view-list double-level" do %> + + + <% question.survey_question_options.each do |option| %> + + + <%= f.label "#{question.id}_#{option.id}", :class => 'o-question-option' do %> + <% if question.level1_radio %> + <%= f.radio_button question.id, option.id, multiple: true %> + <% elsif question.level1_check %> + <%= f.check_box question.id, {multiple: true}, option.id, nil %> + <% else %> + <%= f.hidden_field question.id, :multiple => true, :value => option.id %> + <% end %> + <%= option.name %> + <% end %> + <% if option.level2.count>0 %> + + + + <% option.level2.each do |level2| %> + + <% end %> + <% if question.custom_option_each_option %> + <%= f.text_field "#{question.id}_#{option.id}_custom_option",placeholder: question.custom_option_title %> + <% end %> + <% end %> + + + <% end %> + <% if question.custom_option_new_option %> + + + <% if question.level1_radio %> + <%= f.radio_button question.id, 'custom_option', multiple: true %> + <% elsif question.level1_check %> + <%= f.check_box question.id, {multiple: true}, 'custom_option', nil %> + <% else %> + <%= f.hidden_field question.id, :multiple => true, :value => 'custom_option' %> + <% end %> + <%= f.label "#{question.id}_custom_option", question.custom_option_title + ': ', :class => 'o-question-option custom_option' %> + <%= f.text_field "#{question.id}_custom_option", class: 'custom_option_input' %> + + + <% end %> + + <% end %> <% end %> - <% if footers.include?(header_count) %> + <% if (footers.include?(header_count) && end_paginations.include?(section_index_tmp+1)) || @questions.count == (i+1) %> +
    + <% pagination_index +=1 %> + <% if pagination_index>1 %> + <%= f.button t('survey.prev_page'), type: 'button', class: 'btn btn-success prev_page', 'data-pagination' => pagination_index-2 %> + <% end %> + <% if @questions.count != i+1 %> + <%= f.button t('survey.next_page'), type: 'button', class: 'btn btn-success next_page', 'data-pagination' => pagination_index %> + <% end %>
    <% end %> + <% if footers.include?(header_count) %> + <% section_index = "[other]" %> +
    + <% end %> + <% end %>
    - <%= f.submit t('submit'), :class => 'survey-submit' %> + <%= f.submit t('submit'), :class => "survey-submit btn btn-primary#{' hide' if pagination_index>1 }" %>
    <% end %>
    @@ -198,7 +307,7 @@ <% if @survey.jump_mode %> var answers = <%= @answers.to_json %>; var jump_tos_map = <%= @jump_tos_map.to_json %>; - var $current_question = $('.question-item').eq(0); + var $current_question = $('.question-item[data-pagination="0"]').eq(0); var current_index = parseInt($current_question.attr('data-index')); $current_question.removeClass('hide'); $('.survey-submit').click(function(){ @@ -234,8 +343,9 @@ return false; }); <% else %> - $('.question-item').removeClass('hide'); + $('.question-item[data-pagination="0"]').removeClass('hide'); <% end %> + $('.pagination_wrapper[data-pagination="0"]').removeClass('hide'); $('.question-item[data-type=<%= SurveyQuestion::Select %>][data-custom=true]').each(function(){ $(this).change(function(){ if ( $(this).find('option:selected').val() == 'custom_option' ) { @@ -246,6 +356,58 @@ }); $(this).trigger('change'); }); + + function check_title_check(check_all){ + var flag = true, ele; + if (check_all){ + ele = $('.question-checkbox') + }else{ + ele = $('.question-checkbox:visible') + } + $(ele).parent('li').parent().each(function(){ + var checkbox_in_gp = $(this).children('li').find('.question-checkbox') + if (checkbox_in_gp.filter(':checked').length==0){ + if (check_all || checkbox_in_gp.not(':visible').length==0){ + flag = false; + checkbox_in_gp.addClass('error_field') + } + }else{ + checkbox_in_gp.removeClass('error_field') + } + }) + ele = $('.error_field') + if (ele.length>0){ + if (!check_all){ + ele = ele.filter(":visible") + } + var page = ele.parents('li[data-pagination]').eq(0).data('pagination') + change_page(page) + ele.eq(0).focus() + } + return flag; + } + function change_page(page){ + $('.pagination_wrapper').addClass('hide'); + $('li[data-pagination]').addClass('hide') + $('li[data-pagination="'+page+'"]').removeClass('hide') + $('.pagination_wrapper[data-pagination="'+page+'"]').removeClass('hide'); + + if ($('li[data-pagination]').eq(-1).data('pagination')==page){ + $('.survey-submit').removeClass('hide') + }else{ + $('.survey-submit').addClass('hide') + } + $(window).scrollTop($('.o-question').offset().top) + } + $('button.prev_page, button.next_page').click(function(){ + if (check_title_check()){ + var page = $(this).data('pagination') + change_page(page) + } + }) + $('.o-question').on('change', '.error_field',function(){ + $('input[name="'+$(this).attr('name')+'"]').removeClass('error_field') + }) <% else %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 7c6875c..2ad12ce 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -19,6 +19,7 @@ en: question: Question is_external: The survey is an external link add: Add Question + add_section: Add Section taken_by: Taken By taken_date: Taken On view_answers: View Answers @@ -39,6 +40,8 @@ en: set_sections: Set Sections section_title: Section Title section_description: Section Description + start_question: Start Question + end_question: End Question duplicate_it: Duplicate It view_result: View Result @@ -64,6 +67,20 @@ en: frontend: survey: Survey Frontend + pagination_setting: Pagination Setting + add_pagination: Add Pagination + delete_pagination: Delete Pagination + no_section_hint: Please set at least one section to use this feature. + start_section: Start Section + end_section: End Section + pagination: Pagination + next_page: Next + prev_page: Previous + show_question_number: Show question number + restart_question_number: Restart question number + disable_question_number: Disable question number + question_number_setting: Question number Setting + survey_question: title: Question description: Description @@ -72,12 +89,16 @@ en: is_required: Is Required required: Required required_error: Can't not be empty - oneline: Oneline - multiline: Multi-line - radio: Radio - check: Check - select: Select - radiogroup: Radio Group + + oneline: One line text + multiline: Multi-line text + radio: Radio button + check: Checkbox + select: Dropdown select + radiogroup: Radio button table + datetime: Date & time + double_level_options: 2 Level options + options_lists: Options List radiogroup_label: Radio Group Label radiogroups_lists: Radio Groups List @@ -86,9 +107,30 @@ en: use_custom_option: Other add: Add delete: Delete - datetime: DateTime datetimeformat: Format have_not_chart: This type of question havn't chart move_up: Move up - move_down: Move down \ No newline at end of file + move_down: Move down + + selectable_question: Selectable question + level_2_options: Level 2 Options List + option_title: Option Title + option_title_default: Other + + survey_question_type: + radio: Radio button + check: Checkbox + title: 1st level as title + + selectable_question_type: + radio: Radio button( Please set section in Survey List, or only this selected question can be answered for the entire survey ) + check: Checkbox + + custom_option_type: + for_each_option: For Each Option + new_option: New Option + + option_layout_type: + list_each_option_for_one_line: List Each Option For One Line + continuous_list_arrangement: Continuous List Arrangement \ No newline at end of file diff --git a/config/locales/zh_tw.yml b/config/locales/zh_tw.yml index e0a1457..e1a6225 100644 --- a/config/locales/zh_tw.yml +++ b/config/locales/zh_tw.yml @@ -22,12 +22,15 @@ zh_tw: question: 問題 is_external: 這份問卷為外部連結 add: 新增題目 + add_section: 增加題組 taken_by: Taken By taken_date: Taken On view_answers: View Answers - set_sections: Set Sections - section_title: Section Title - section_description: Section Description + set_sections: 設定題組 + section_title: 題組標題 + section_description: 題組描述 + start_question: 開始題號 + end_question: 結束題號 criteria: Criteria result_type: 前端結果表示方式 extern_link: 外部連結 @@ -68,6 +71,20 @@ zh_tw: frontend: survey: 問卷調查前台 + pagination_setting: 分頁設定 + add_pagination: 新增分頁 + delete_pagination: 刪除分頁 + no_section_hint: 由於您還沒有建立題組,故無法使用此功能 + start_section: 開始題組 + end_section: 結束題組 + pagination: 頁碼 + next_page: 下一頁 + prev_page: 上一頁 + show_question_number: 顯示題號 + restart_question_number: 題號重新開始編號 + disable_question_number: 不顯示題號 + question_number_setting: 題號設定 + survey_question: title: 題目 description: 說明 @@ -76,12 +93,16 @@ zh_tw: is_required: 設為必填 required: 必填 required_error: 沒有回答 + oneline: 單行文字 multiline: 多行文字 radio: 單選按鈕 check: 多選方塊 select: 下拉選單 - radiogroup: 格狀呈現 + radiogroup: 表格題組 + datetime: 日期時間 + double_level_options: 雙層選項 + options_lists: 選項清單 radiogroup_label: 橫欄 radiogroups_lists: 橫欄清單 @@ -90,9 +111,29 @@ zh_tw: use_custom_option: 其他 add: 新增 delete: 刪除 - datetime: DateTime datetimeformat: Format have_not_chart: 此種類型問題不含結果圖表 move_up: 上移 - move_down: 下移 \ No newline at end of file + move_down: 下移 + selectable_question: 可勾選作答 + level_2_options: 次選單清單 + option_title: 選項名稱 + option_title_default: 其他 + + survey_question_type: + radio: 單選 + check: 多選 + title: 選項清單作為標題 + + selectable_question_type: + radio: 單選(請於問卷列表頁設定題組,否則整份問卷僅被使用者勾選的題目可作答) + check: 多選 + + custom_option_type: + for_each_option: 逐項填寫 + new_option: 獨立填寫欄位 + + option_layout_type: + list_each_option_for_one_line: 每行一個選項 + continuous_list_arrangement: 所有選項連續排列 \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 7915053..16fdf4d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,6 +14,8 @@ Rails.application.routes.draw do get 'set_answers' get 'set_sections' get 'add_section' + get 'pagination_setting' + patch 'save_pagination_setting' post 'create_section' delete 'delete_section' get 'edit_section' diff --git a/lib/survey/engine.rb b/lib/survey/engine.rb index dc7f465..d4eb795 100644 --- a/lib/survey/engine.rb +++ b/lib/survey/engine.rb @@ -6,6 +6,7 @@ module Survey base_url File.expand_path File.dirname(__FILE__) widget_methods ["widget","widget1"] widget_settings [{"data_count"=>10}] + categorizable authorizable frontend_enabled data_count 1..20 @@ -26,6 +27,13 @@ module Survey :priority=>2, :active_for_action=>{'admin/surveys'=>'new'}, :available_for => 'sub_managers' + context_link 'categories', + :link_path=>"admin_module_app_categories_path" , + :link_arg=>"{:module_app_id=>ModuleApp.find_by(:key=>'survey').id}", + :priority=>3, + :active_for_action=>{'admin/surveys'=>'categories'}, + :active_for_category => 'Survey', + :available_for => 'managers' end end diff --git a/lib/tasks/survey_tasks.rake b/lib/tasks/survey_tasks.rake index 703c656..6251a96 100644 --- a/lib/tasks/survey_tasks.rake +++ b/lib/tasks/survey_tasks.rake @@ -6,29 +6,5 @@ namespace :survey_tasks do task :prepare_download,[:surveyid] => :environment do |task,args| puts "Cron initiated with #{args.surveyid}" id = args.surveyid - I18n.locale = :zh_tw - survey = QuestionnaireSurvey.find(id) - chart_data, survey_questions, survey_answers = survey.generate_chart_data - ac = ActionController::Base.new() - xlsx = ac.render_to_string handlers: [:axlsx], formats: [:xlsx], template: "survey_export/export", locals: {survey: survey, survey_questions: survey_questions, survey_answers: survey_answers} - dirname = "public/uploads/survey_export/#{id}" - FileUtils.mkdir_p(dirname) unless File.exists?(dirname) - f = "#{dirname}/#{survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')}.xlsx" - if File.exists?(f) - File.delete(f) - end - file = File.open(f, "w") - xlsx.force_encoding("utf-8") - file.write(xlsx) - end -end - -def remove_illegal_utf8(str) - if String.method_defined?(:encode) - str.encode!('UTF-8', 'UTF-8', :invalid => :replace) - else - ic = Iconv.new('UTF-8', 'UTF-8//IGNORE') - str = ic.iconv(str) - end - str + SurveysHelper.generate_xlsx(id) end \ No newline at end of file