Add allow user can answer repeatedly.
Change export feature.
This commit is contained in:
BoHung Chiu 2021-09-12 20:20:03 +08:00
parent f6a8ca43dc
commit 08c904f73c
19 changed files with 414 additions and 60 deletions

View File

@ -7,14 +7,16 @@ function repeat_string(str,num){
} }
function set_dot_for_double_level(){ function set_dot_for_double_level(){
var width = $('div.o-question').width() if($('.double-level .o-question-option').length != 0){
var font_size = parseInt($('.double-level .o-question-option').css('font-size').slice(0,-2)) var width = $('div.o-question').width()
$('.double-level tr').each(function(){ var font_size = parseInt($('.double-level .o-question-option').css('font-size').slice(0,-2))
var tr_w = $(this).find('.o-question-option').width()+$(this).find('.level2-list').width() $('.double-level tr').each(function(){
if (tr_w/width<0.95){ var tr_w = $(this).find('.o-question-option').width()+$(this).find('.level2-list').width()
$('.dot').text(repeat_string('•',(width*0.95-tr_w)/font_size-2)) if (tr_w/width<0.95){
} $('.dot').text(repeat_string('•',(width*0.95-tr_w)/font_size-2))
}) }
})
}
} }
$(function(){ $(function(){
set_dot_for_double_level() set_dot_for_double_level()

View File

@ -27,8 +27,13 @@ class Admin::SurveysController < OrbitAdminController
def answer_sets def answer_sets
if can_edit_or_delete?(@survey) if can_edit_or_delete?(@survey)
@table_fields = ['survey.taken_by', 'survey.taken_date'] @table_fields = ['survey.taken_by', 'survey.taken_date',"survey.records"]
@survey_answers = @survey.survey_answers.desc(:created_at).page(params[:page]).per(15) @survey_answer_groups = @survey.survey_answer_groups.desc(:last_modified).page(params[:page]).per(15)
if params[:search]
match_user_ids = User.where(:id.in=>@survey.survey_answer_groups.pluck(:user),:member_name=>/#{params[:search]}/).pluck(:id) rescue [];
@survey_answer_groups = @survey_answer_groups.where(:user.in=>match_user_ids)
end
@answer_repeat = @survey.get_answer_repeat
else else
render_401 render_401
end end
@ -38,8 +43,36 @@ class Admin::SurveysController < OrbitAdminController
@survey_answer = SurveyAnswer.find(params["id"]) rescue nil @survey_answer = SurveyAnswer.find(params["id"]) rescue nil
@survey = @survey_answer.questionnaire_survey if !@survey_answer.nil? @survey = @survey_answer.questionnaire_survey if !@survey_answer.nil?
@user = @survey_answer.user.nil? ? nil : (User.find(@survey_answer.user) rescue nil) @user = @survey_answer.user.nil? ? nil : (User.find(@survey_answer.user) rescue nil)
#render :html => @survey_answer and return
end
def answer_list
@table_fields = ['survey.taken_by', 'survey.taken_date',"survey.records"]
@survey_answer_group = SurveyAnswerGroup.find(params["id"]) rescue nil
@survey = @survey_answer_group.questionnaire_survey
@survey_answers = @survey_answer_group.survey_answers.desc(:updated_at).page(params[:page]).per(15)
@user = @survey_answer_group.user.nil? ? nil : (User.find(@survey_answer_group.user) rescue nil)
@is_answer_list = true
render "answer_sets"
end
def export_answers
@survey_answer_group = SurveyAnswerGroup.find(params["id"]) rescue nil
@survey = @survey_answer_group.questionnaire_survey
@user = @survey_answer_group.user.nil? ? nil : (User.find(@survey_answer_group.user) rescue nil)
@survey_answers = @survey_answer_group.survey_answers
extra_filename = "_#{@user.member_name rescue nil}"
title = @survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')
f = "public/uploads/survey_export/#{@survey.id}/#{title}#{extra_filename}.xlsx"
File.delete(f) if File.exists?(f)
locale = I18n.locale
Thread.new do
begin
SurveysHelper.generate_xlsx(@survey.id,locale,{:id=>params["id"]},extra_filename)
rescue => e
puts [e,e.backtrace]
end
end
render :json => {"success" => true, "title" => title}.to_json
end end
def new def new
@survey = QuestionnaireSurvey.new @survey = QuestionnaireSurvey.new
@primary_locale = I18n.locale.to_s @primary_locale = I18n.locale.to_s
@ -133,11 +166,10 @@ class Admin::SurveysController < OrbitAdminController
end end
def export def export
I18n.locale = :zh_tw
title = @survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'') title = @survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')
f = "public/uploads/survey_export/#{@survey.id}/#{title}.xlsx" f = "public/uploads/survey_export/#{@survey.id}/#{title}.xlsx"
File.delete(f) if File.exists?(f) File.delete(f) if File.exists?(f)
I18n.locale = locale locale = I18n.locale
Thread.new do Thread.new do
begin begin
SurveysHelper.generate_xlsx(@survey.id,locale) SurveysHelper.generate_xlsx(@survey.id,locale)

View File

@ -36,20 +36,47 @@ class SurveysController < ApplicationController
} }
end end
def my_record
params = OrbitHelper.params
survey = QuestionnaireSurvey.find_by(uid: params[:uid])
current_user = OrbitHelper.current_user
page_no = params[:page_no] ? params[:page_no].to_i : 1
survey_answers = (current_user ? survey.survey_answers.where(:user=>current_user.id).desc(:updated_at).page(page_no).per(10) : [] rescue [])
table_fields = ['survey.taken_by', 'survey.taken_date',"survey.records"]
is_answer_list = true
OrbitHelper.set_page_number(page_no)
{
"survey" => survey,
"user" => current_user,
"survey_answers" => survey_answers,
"table_fields" => table_fields,
"is_answer_list" => is_answer_list
}
end
def show_data def show_data
params = OrbitHelper.params params = OrbitHelper.params
survey = QuestionnaireSurvey.find_by(uid: params[:uid]) survey = QuestionnaireSurvey.find_by(uid: params[:uid])
current_user = OrbitHelper.current_user current_user = OrbitHelper.current_user
answer_present = (current_user.nil? ? false : (survey.survey_answers.where(:user => current_user.id).count > 0 ? true : false)) answer_group = (current_user ? survey.survey_answer_groups.where(:user => current_user.id).first : nil rescue nil)
answer_present = (current_user.nil? ? false : (answer_group ? true : false))
answer_present = (!survey.needs_login ? false : answer_present) answer_present = (!survey.needs_login ? false : answer_present)
link_to_answer_set = (answer_present ? "/admin/surveys/#{survey.survey_answers.where(:user => current_user.id).first.id.to_s}/answer_set" : "") link_to_answer_set = (answer_present ? "/admin/surveys/#{answer_group.survey_answer_ids.last.to_s}/answer_set" : "")
link_to_my_record = nil
answer_repeat = survey.get_answer_repeat
if answer_present && answer_present
show_page = (OrbitHelper.page.nil? rescue true) ? Page.where(:page_id=>params["page_id"]).first : OrbitHelper.page
show_page_url = show_page.get_url rescue show_page.url
params[:url] = show_page_url
link_to_my_record = OrbitHelper.url_to_show(survey.to_param) + "?method=my_record"
end
{ {
'survey' => survey, 'survey' => survey,
'answer_present' => answer_present, 'answer_present' => answer_present,
'answer_repeat' => answer_repeat,
'link_to_answer_set' => link_to_answer_set, 'link_to_answer_set' => link_to_answer_set,
'link_to_my_record' => link_to_my_record,
'time_range' => QuestionnaireSurvey.time_range(survey) 'time_range' => QuestionnaireSurvey.time_range(survey)
} }
@ -82,6 +109,7 @@ class SurveysController < ApplicationController
jumpable_questions = questions.select{ |q| q.jumpable? && q.can_set_jump? } jumpable_questions = questions.select{ |q| q.jumpable? && q.can_set_jump? }
jump_tos_map = jumpable_questions.map(&:get_jump_tos).inject(:merge) jump_tos_map = jumpable_questions.map(&:get_jump_tos).inject(:merge)
end end
show_page = (OrbitHelper.page.nil? rescue true) ? Page.where(:page_id=>params["page_id"]).first : OrbitHelper.page
{ {
'survey' => survey, 'survey' => survey,
'redirect_url' => '', 'redirect_url' => '',
@ -89,7 +117,8 @@ class SurveysController < ApplicationController
'questions' => questions, 'questions' => questions,
'answers' => answers, 'answers' => answers,
'answer_present' => answer_present, 'answer_present' => answer_present,
'jump_tos_map' => jump_tos_map 'jump_tos_map' => jump_tos_map,
"show_page_url" => (show_page.get_url rescue show_page.url)
} }
end end
@ -224,9 +253,11 @@ class SurveysController < ApplicationController
@answer_model.scored_points = total @answer_model.scored_points = total
@answer_model.individual_total = individual_total @answer_model.individual_total = individual_total
@answer_model.save! @answer_model.save!
params[:url] = params[:show_page_url]
OrbitHelper.set_params(params,current_user)
redirect_to OrbitHelper.url_to_show(@survey.to_param) + "?method=answer_success&ans=#{@answer_model.id.to_s}" redirect_to OrbitHelper.url_to_show(@survey.to_param) + "?method=answer_success&ans=#{@answer_model.id.to_s}"
else else
@survey_answer_error = @answer_model.errors.full_messages.join(',') @survey_answer_error = @answer_model.errors.full_messages.join('\n')
render :answer_error render :answer_error
end end
end end

View File

@ -26,7 +26,7 @@ module SurveysHelper
def self.parse_checkbox_value_html(answer,locale=nil) def self.parse_checkbox_value_html(answer,locale=nil)
locale = self.get_locale(locale) locale = self.get_locale(locale)
Array(answer).collect do |v| Array(answer).collect do |v|
self.parse_value(v['value'],locale) self.parse_value(v,locale)
end.join(", ") end.join(", ")
end end
@ -54,7 +54,7 @@ module SurveysHelper
values << answer['other'] values << answer['other']
end end
else else
values = [answer['value'][locale],answer['other']].compact values = [(answer['value'][locale] rescue nil),answer['other']].compact
end end
else else
if options if options
@ -201,7 +201,7 @@ module SurveysHelper
values values
end end
def self.generate_xlsx(id,locale) def self.generate_xlsx(id,locale,match_args={},extra_filename="")
def self.remove_illegal_utf8(str) def self.remove_illegal_utf8(str)
if String.method_defined?(:encode) if String.method_defined?(:encode)
str.encode!('UTF-8', 'UTF-8', :invalid => :replace) str.encode!('UTF-8', 'UTF-8', :invalid => :replace)
@ -214,7 +214,7 @@ module SurveysHelper
I18n.with_locale(locale) do I18n.with_locale(locale) do
survey = QuestionnaireSurvey.find(id) survey = QuestionnaireSurvey.find(id)
puts survey.inspect puts survey.inspect
chart_data, survey_questions, survey_answers = survey.generate_chart_data chart_data, survey_questions, survey_answers = survey.generate_chart_data(match_args)
ac = ActionController::Base.new() ac = ActionController::Base.new()
xlsx = ac.render_to_string handlers: [:axlsx], xlsx = ac.render_to_string handlers: [:axlsx],
formats: [:xlsx], formats: [:xlsx],
@ -225,10 +225,11 @@ module SurveysHelper
} }
dirname = "public/uploads/survey_export/#{id}" dirname = "public/uploads/survey_export/#{id}"
FileUtils.mkdir_p(dirname) unless File.exists?(dirname) FileUtils.mkdir_p(dirname) unless File.exists?(dirname)
f = "#{dirname}/#{survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')}.xlsx" f = "#{dirname}/#{survey.title.gsub(/[ "'*@#$%^&()+=;:.,?>|\\\/<~_!:,、。!?;「」〈〉【】/]/,'')}#{extra_filename}.xlsx"
file = File.open(f, "w") File.open(f, "w+") do |file|
xlsx.force_encoding("utf-8") xlsx.force_encoding("utf-8")
file.write(xlsx) file.write(xlsx)
end
puts 'success' puts 'success'
end end
end end

View File

@ -12,7 +12,7 @@ class QuestionnaireSurvey
include OrbitCategory::Categorizable include OrbitCategory::Categorizable
scope :can_display, ->{where(is_hidden: false)} scope :can_display, ->{where(is_hidden: false)}
field :already_fix_data, :type => Boolean, :default => false
field :copy_id field :copy_id
field :except_clone_relations, :type=>Array, :default => [] field :except_clone_relations, :type=>Array, :default => []
field :title, as: :slug_title, type: String, localize: true field :title, as: :slug_title, type: String, localize: true
@ -26,6 +26,7 @@ class QuestionnaireSurvey
field :is_hidden, :type => Boolean, :default => false field :is_hidden, :type => Boolean, :default => false
field :needs_login, :type => Boolean, :default => false field :needs_login, :type => Boolean, :default => false
field :answer_repeat, :type => Boolean, :default => false
field :total_points, type: Integer, :default => 0 field :total_points, type: Integer, :default => 0
field :result_type, :type => Integer, :default => 0 field :result_type, :type => Integer, :default => 0
@ -43,6 +44,7 @@ class QuestionnaireSurvey
has_many :survey_questions, :autosave => true, :dependent => :destroy has_many :survey_questions, :autosave => true, :dependent => :destroy
has_many :survey_answers, :autosave => true, :dependent => :destroy has_many :survey_answers, :autosave => true, :dependent => :destroy
has_many :survey_answer_groups, :autosave => true, :dependent => :destroy
has_many :survey_sections, :autosave => true, :dependent => :destroy has_many :survey_sections, :autosave => true, :dependent => :destroy
accepts_nested_attributes_for :survey_questions, :allow_destroy => true accepts_nested_attributes_for :survey_questions, :allow_destroy => true
@ -52,12 +54,16 @@ class QuestionnaireSurvey
has_many :survey_paginations, :autosave => true, :dependent => :destroy has_many :survey_paginations, :autosave => true, :dependent => :destroy
accepts_nested_attributes_for :survey_paginations, :allow_destroy => true accepts_nested_attributes_for :survey_paginations, :allow_destroy => true
before_create do before_create do
self.already_fix_data = true
if self.copy_id.present? if self.copy_id.present?
clone_new(true) clone_new(true)
self.created_at = DateTime.now self.created_at = DateTime.now
self.updated_at = DateTime.now self.updated_at = DateTime.now
end end
end end
def get_answer_repeat
self.needs_login && self.answer_repeat
end
def update_user def update_user
User.find(update_user_id) rescue nil User.find(update_user_id) rescue nil
end end
@ -97,13 +103,22 @@ class QuestionnaireSurvey
end end
end end
def generate_chart_data def generate_chart_data(match_args={})
survey_questions = self.survey_questions.all survey_questions = self.survey_questions.all
survey_answers = self.survey_answers.all.order_by(created_at: :desc) tmp_answer_repeat = self.needs_login && self.answer_repeat
survey_answers = []
if tmp_answer_repeat
survey_answers = self.survey_answers.where(match_args).order_by(created_at: :desc)
else
survey_answer_ids = self.survey_answer_groups.where(match_args).pluck(:survey_answer_ids).map{|ids| ids ? ids[-1] : nil}
survey_answers = self.survey_answers.where(:id.in=>survey_answer_ids).order_by(created_at: :desc)
end
survey_answers = survey_answers.to_a
chart_data = {} chart_data = {}
answers =(0...survey_answers.count).map{{}} answers =(0...survey_answers.count).map{{}}
survey_answers.each_with_index do |answer,i|
answers[i]["name"] = User.find(answer.user).member_name rescue ""
end
SurveysHelper.set_locale(I18n.locale) SurveysHelper.set_locale(I18n.locale)
survey_questions.each do |question| survey_questions.each do |question|
qid = question.id.to_s qid = question.id.to_s

View File

@ -8,5 +8,33 @@ class SurveyAnswer
field :individual_total, type: Array, :default => [] field :individual_total, type: Array, :default => []
field :select_question, type: Array, :default => [] field :select_question, type: Array, :default => []
belongs_to :questionnaire_survey belongs_to :questionnaire_survey
after_create do
if self.questionnaire_survey
answer_group = SurveyAnswerGroup.where(:questionnaire_survey_id=>self.questionnaire_survey.id,:user=>user).first
if answer_group.nil?
answer_group = SurveyAnswerGroup.new(:questionnaire_survey_id=>self.questionnaire_survey.id,:user=>user_id)
end
answer_group.last_modified = self.updated_at
answer_group.survey_answer_ids << self.id
answer_group.save
end
end
after_save do
answer_group = SurveyAnswerGroup.where(:questionnaire_survey_id=>self.questionnaire_survey.id,:user=>user).first
if answer_group
answer_group.last_modified = self.updated_at
answer_group.save
end
end
before_destroy do
answer_group = SurveyAnswerGroup.where(:user=>user).first
if answer_group
answer_group.survey_answer_ids.delete(self.id)
if answer_group.survey_answer_ids.count == 0
answer_group.destroy
else
answer_group.save
end
end
end
end end

View File

@ -0,0 +1,10 @@
class SurveyAnswerGroup
include Mongoid::Document
field :user, type: BSON::ObjectId
field :survey_answer_ids, type: Array, default: []
field :last_modified, type: Time, default: Time.now
belongs_to :questionnaire_survey
def survey_answers
SurveyAnswer.where(:id.in=>survey_answer_ids)
end
end

View File

@ -1,7 +1,7 @@
class SurveyQuestionOption class SurveyQuestionOption
include Mongoid::Document include Mongoid::Document
field :name, :localize => true field :name, :localize => true, :type => String
field :jump_to, :default => 0 field :jump_to, :default => 0
field :points, :type => Integer, :default => 0 field :points, :type => Integer, :default => 0
field :question_type, :type => Integer, :default => 0 field :question_type, :type => Integer, :default => 0

View File

@ -96,6 +96,14 @@
</label> </label>
</div> </div>
</div> </div>
<div class="control-group <%='hide' if !(f.object.needs_login)%>" id="answer_repeat_block">
<%= f.label :answer_repeat, t("survey.same_user_can_answer_repeatedly"), :class=>"control-label muted" %>
<div class="controls">
<label class="checkbox">
<%= f.check_box :answer_repeat %>
</label>
</div>
</div>
<!-- redirect mode --> <!-- redirect mode -->
<div class="control-group"> <div class="control-group">
<label class="control-label muted" for="redirectMode"><%= t('survey.redirect_mode') %></label> <label class="control-label muted" for="redirectMode"><%= t('survey.redirect_mode') %></label>
@ -135,4 +143,7 @@
<script type="text/javascript"> <script type="text/javascript">
editQuestion(<%= @sqs.to_json.html_safe %>); editQuestion(<%= @sqs.to_json.html_safe %>);
$("#questionnaire_survey_needs_login").click(function(){
$("#answer_repeat_block").toggleClass("hide");
})
</script> </script>

View File

@ -41,7 +41,7 @@
<td><%= (survey.postdate) ? (format_value survey.postdate) : t(:no_deadline) %></td> <td><%= (survey.postdate) ? (format_value survey.postdate) : t(:no_deadline) %></td>
<td><%= (survey.deadline) ? (format_value survey.deadline) : t(:no_deadline) %></td> <td><%= (survey.deadline) ? (format_value survey.deadline) : t(:no_deadline) %></td>
<td> <td>
<a href="/admin/surveys/<%=survey.id.to_s%>/answer_sets"> <%= survey.survey_answers.count %></a> <a href="/admin/surveys/<%=survey.id.to_s%>/answer_sets"> <%= survey.survey_answer_groups.count %></a>
<%# if survey.needs_login %> <%# if survey.needs_login %>
<!-- <a href="/admin/surveys/<%=survey.id.to_s%>/answer_sets"> <%#= survey.survey_answers.count %></a> --> <!-- <a href="/admin/surveys/<%=survey.id.to_s%>/answer_sets"> <%#= survey.survey_answers.count %></a> -->
<%# else %> <%# else %>

View File

@ -61,9 +61,10 @@
<div class="answer"> <div class="answer">
<span class="init">A</span> <span class="init">A</span>
<% case sq.type %> <% case sq.type %>
<% when SurveyQuestion::Radio, SurveyQuestion::Select %> <% when SurveyQuestion::Radio, SurveyQuestion::Select %>
<%= SurveysHelper.parse_value(@survey_answer[sq.id.to_s]) %> <%= SurveysHelper.parse_value(@survey_answer[sq.id.to_s]) %>
<% when SurveyQuestion::Check %> <% when SurveyQuestion::Check %>
<% puts sq.id %>
<%= SurveysHelper.parse_checkbox_value_html(@survey_answer[sq.id.to_s]) %> <%= SurveysHelper.parse_checkbox_value_html(@survey_answer[sq.id.to_s]) %>
<% when SurveyQuestion::Radiogroup %> <% when SurveyQuestion::Radiogroup %>
<div class="radiogroup"> <div class="radiogroup">

View File

@ -1,30 +1,131 @@
<style type="text/css">
#survey_answer_search label{
float: left;
margin-right: 0.5em;
line-height: 2;
}
#survey_answer_search input{
float: left;
line-height: 2;
}
</style>
<script type="text/javascript" src="/assets/lib/process.manager.js"></script>
<div id="downloadModal" data-backdrop="static" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="downloadModalLabel" aria-hidden="true">
<div class="modal-header">
<h3 id="downloadModalLabel">Download</h3>
</div>
<div class="modal-body">
<p id="wait-zone" style="text-align: center;">
Please wait while we prepare your download. This may take a while.
<br />
<img src="/assets/spin.gif" />
</p>
<p id="link-zone" style="display: none; text-align: center;">
Please click the link below to download.
<br />
<a href="" id="download-link" target="_blank">Download</a>
</p>
</div>
<div class="modal-footer">
<button class="btn" id="modal-close-btn" style="display:none;" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
</div>
<h3><%= @survey.title %></h3> <h3><%= @survey.title %></h3>
<div>
<% if @is_answer_list %>
<h4><%=t('survey.taken_by')%>: <%=@user.member_name%></h4>
<% else %>
<form id="survey_answer_search">
<div>
<label for="search_taken_by"><%=t('survey.taken_by')%>:</label>
<input type="text" id="search_taken_by" name="search" placeholder="<%=t('survey.taken_by')%>" value="<%=params[:search]%>">
<input type="submit" value="<%=t(:search_)%>">
</div>
<div style="clear: both;"></div>
</form>
<% end %>
</div>
<table class="table main-list"> <table class="table main-list">
<thead> <thead>
<tr class="sort-header"> <tr class="sort-header">
<% @table_fields.each do |f| %> <% @table_fields.each do |f| %>
<%= thead(f) %> <%= thead(f) %>
<% end %> <% end %>
<th class="span2"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% @survey_answers.each do |sa| %> <% (@survey_answer_groups || @survey_answers).each do |sa| %>
<tr> <tr>
<% user = sa.user.nil? ? nil : (User.find(sa.user) rescue nil) %> <% user = sa.user.nil? ? nil : (User.find(sa.user) rescue nil) %>
<% if !user.nil? %> <% if !user.nil? %>
<td><%= user.name %></td> <td><%= user.member_name rescue user.name %></td>
<% else %> <% else %>
<td>NA</td> <td>NA</td>
<% end %> <% end %>
<td><%= sa.created_at.strftime("%h %d, %Y - %H:%M") rescue nil %></td> <td><%= (@is_answer_list ? sa.updated_at : sa.last_modified).strftime("%h %d, %Y - %H:%M") rescue nil %></td>
<td><a href="/admin/surveys/<%= sa.id.to_s %>/answer_set"><%= t("survey.view_answers") %></a></td> <td>
<% if @answer_repeat && !@is_answer_list %>
<a class="btn btn-primary" href="/admin/surveys/<%= sa.id.to_s %>/answer_list"><%= t("survey.view") %>(<%=sa.survey_answer_ids.count%>)</a>
<button class="btn btn-primary export-xls" data-href="/admin/surveys/<%= sa.id.to_s %>/export_answers"><%= t("survey.export") %></button>
<% else %>
<a class="btn btn-primary" href="/admin/surveys/<%= @is_answer_list ? sa.id : sa.survey_answer_ids.last.to_s %>/answer_set"><%= t("survey.view_answers") %></a>
<% end %>
</td>
</tr> </tr>
<% end %> <% end %>
</tbody> </tbody>
</table> </table>
<%= <%=
content_tag :div, class: "bottomnav clearfix" do content_tag :div, class: "bottomnav clearfix" do
content_tag :div, paginate(@survey_answers), class: "pagination pagination-centered" content_tag :div, paginate((@survey_answer_groups || @survey_answers)), class: "pagination pagination-centered"
end end
%> %>
<script type="text/javascript">
var downloadModal = $("#downloadModal"),
checkForThread = null,
waitZone = $("#wait-zone"),
linkZone = $("#link-zone"),
downloadLink = $("a#download-link"),
modalBtn = $("#modal-close-btn"),
processManager = new ProcessManager();
$(document).on("click", ".export-xls", function(){
var link = $(this).data("href"),
title = null,
id = "<%=@survey.id%>";
linkZone.hide();
waitZone.show();
modalBtn.hide();
$.ajax({
url : link,
type : "get",
dataType : "json"
}).done(function(data){
title = data.title;
checkForThread = new Process(function(){
$.ajax({
url : "/admin/surveys/checkforthread",
type : "get",
data : {"survey_id" : id, "survey_title" : title},
dataType : "json"
}).done(function(data){
if(!data.status){
downloadLink.attr("href", "/uploads/survey_export/" + id + "/" + title + ".xlsx");
waitZone.hide();
linkZone.show();
modalBtn.show();
checkForThread.kill();
}
})
})
checkForThread.setTimeInterval(1000);
checkForThread.setRepeat(Process.CONSTANTS.REPEAT_INFINITE);
processManager.queue(checkForThread);
})
downloadModal.modal("show");
return false;
})
</script>

View File

@ -1,29 +1,42 @@
# encoding: utf-8 # encoding: utf-8
require 'axlsx'
wb = xlsx_package.workbook wb = xlsx_package.workbook
wb.add_worksheet(name: "WorkSheet1") do |sheet| title = survey.title
title = "WorkSheet1" if title.blank?
row = [] wb.add_worksheet(name: title) do |sheet|
row = [I18n.t("survey.taken_by")]
row2 = [""]
survey_questions.each_with_index do |question, i| survey_questions.each_with_index do |question, i|
qnum = question.title.match(/^\d+./).nil? ? "#{i+1}. " : ""
start_col = row2.count
if question.type == 2 or question.type == 3 or question.type == 4 if question.type == 2 or question.type == 3 or question.type == 4
col_size = question.survey_question_options.count - 1
sheet.merge_cells "#{Axlsx::cell_r(start_col,0)}:#{Axlsx::cell_r(start_col+col_size,0)}"
question.survey_question_options.each do |option| question.survey_question_options.each do |option|
row << "#{i+1}. #{question.title} - #{option.name}" row << "#{qnum}#{question.title}"
row2 << "#{option.name}"
end end
elsif question.type == 5 elsif question.type == 5
col_size = question.survey_question_options.count * question.survey_question_radiogroups.count - 1
sheet.merge_cells "#{Axlsx::cell_r(start_col,0)}:#{Axlsx::cell_r(start_col+col_size,0)}"
question.survey_question_options.each do |option| question.survey_question_options.each do |option|
question.survey_question_radiogroups.each do |radiogroup| question.survey_question_radiogroups.each do |radiogroup|
row << "#{i+1}. #{question.title} - #{option.name} - #{radiogroup.name}" row << "#{qnum}#{question.title}"
row2 << "#{option.name} - #{radiogroup.name}"
end end
end end
else else
row << "#{i+1}. #{question.title}" row << "#{qnum}#{question.title}"
row2 << ""
end end
if question.custom_option_new_option if question.custom_option_new_option
row << "#{i+1}. #{question.title} - #{t('survey_question.use_custom_option')}" row << "#{qnum}#{question.title}"
row2 << "#{t('survey_question.use_custom_option')}"
end end
end end
sheet.add_row row sheet.add_row row
sheet.add_row row2
wrap = wb.styles.add_style alignment: {wrap_text: true} wrap = wb.styles.add_style alignment: {wrap_text: true}
survey_answers.each do |answer| survey_answers.each do |answer|
answer_row = [] answer_row = []

View File

@ -0,0 +1,63 @@
<%
data = action_data
@survey = data["survey"]
@user = data["user"]
@survey_answers = data["survey_answers"]
@table_fields = data["table_fields"]
@is_answer_list = data["is_answer_list"]
%>
<% if @user.nil? %>
<h3><a id="display_login_button" href="#" title="<%=t("survey.please_login_first")%>"><%=t("survey.please_login_first")%></a></h3>
<script>
$("#display_login_button").click(function(){
$('#loginbutton').click();
})
</script>
<% else %>
<style type="text/css">
#survey_answer_search label{
float: left;
margin-right: 0.5em;
line-height: 2;
}
#survey_answer_search input{
float: left;
line-height: 2;
}
</style>
<h3><%= @survey.title %></h3>
<div>
<h4><%=t('survey.taken_by')%>: <%=@user.member_name%></h4>
</div>
<table class="table main-list">
<thead>
<tr class="sort-header">
<% @table_fields.each do |f| %>
<%= thead(f) %>
<% end %>
</tr>
</thead>
<tbody>
<% (@survey_answer_groups || @survey_answers).each do |sa| %>
<tr>
<% user = sa.user.nil? ? nil : (User.find(sa.user) rescue nil) %>
<% if !user.nil? %>
<td><%= user.member_name rescue user.name %></td>
<% else %>
<td>NA</td>
<% end %>
<td><%= (@is_answer_list ? sa.updated_at : sa.last_modified).strftime("%h %d, %Y - %H:%M") rescue nil %></td>
<td>
<% if @answer_repeat && !@is_answer_list %>
<a class="btn btn-primary" href="/admin/surveys/<%= sa.id.to_s %>/answer_list" title="<%= t("survey.view") %>"><%= t("survey.view") %>(<%=sa.survey_answer_ids.count%>)</a>
<button class="btn btn-primary export-xls" data-href="/admin/surveys/<%= sa.id.to_s %>/export_answers" title="<%= t("survey.export") %>"><%= t("survey.export") %></button>
<% else %>
<a class="btn btn-primary" href="/admin/surveys/<%= @is_answer_list ? sa.id : sa.survey_answer_ids.last.to_s %>/answer_set" title="<%= t("survey.view_answers") %>"><%= t("survey.view_answers") %></a>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= create_pagination((@survey_answer_groups || @survey_answers).total_pages).html_safe %>
<% end %>

View File

@ -33,8 +33,12 @@
s = qnums.index(-1) s = qnums.index(-1)
e = @questions.count e = @questions.count
len = e-s len = e-s
qnum_start = qnums[0...s].compact[-1] + 1 qnum_start = qnums[0...s].compact[-1] + 1 rescue nil
qnums[s,len] = (qnum_start...(qnum_start+len)).to_a if qnum_start
qnums[s,len] = (qnum_start...(qnum_start+len)).to_a
else
qnums[s,len] = (s+1..s+len).to_a
end
end end
headers = @survey.survey_sections.pluck(:start_question) headers = @survey.survey_sections.pluck(:start_question)
footers = @survey.survey_sections.pluck(:end_question) footers = @survey.survey_sections.pluck(:end_question)
@ -46,9 +50,9 @@
section_index = "[other]" section_index = "[other]"
pagination_index = 0 pagination_index = 0
qnum = 0 qnum = 0
show_page_url = data["show_page_url"]
%> %>
<% if @survey.needs_login && current_user.nil? %> <% if @survey.needs_login && current_user.nil? %>
<script type="text/javascript"> <script type="text/javascript">
window.location.href = "<%= new_session_path %>"; window.location.href = "<%= new_session_path %>";
@ -292,6 +296,7 @@
<% end %> <% end %>
</ol> </ol>
<div> <div>
<%= f.hidden_field_tag "show_page_url", show_page_url %>
<%= f.submit t('submit'), :class => "survey-submit btn btn-primary#{' hide' if pagination_index>1 }" %> <%= f.submit t('submit'), :class => "survey-submit btn btn-primary#{' hide' if pagination_index>1 }" %>
</div> </div>
<% end %> <% end %>

View File

@ -6,6 +6,8 @@
@time_range = data["time_range"] @time_range = data["time_range"]
answer_present = data["answer_present"] answer_present = data["answer_present"]
link_to_answer_set = data["link_to_answer_set"] link_to_answer_set = data["link_to_answer_set"]
answer_repeat = data["answer_repeat"]
link_to_my_record = data["link_to_my_record"]
%> %>
<article class="show-survey" id="spen-survey"> <article class="show-survey" id="spen-survey">
@ -34,8 +36,11 @@
<%= link_to t('back'), page_for_survey, :class => 'btn btn-primary' %> <%= link_to t('back'), page_for_survey, :class => 'btn btn-primary' %>
<% end %> <% end %>
<% if !answer_present %> <% if !answer_present %>
<%= link_to "Take survey", OrbitHelper.url_to_show(@survey.to_param), :class => 'btn btn-primary' %> <%= link_to t("survey.taken_survey"), OrbitHelper.url_to_show(@survey.to_param), :class => 'btn btn-primary' %>
<% else %> <% else %>
<%= link_to "View answers", link_to_answer_set, :class => "btn btn-primary" %> <%= link_to t("survey.view_answers"), link_to_answer_set, :class => "btn btn-primary" %>
<% if answer_repeat %>
<%= link_to t("survey.my_record"), link_to_my_record, :class => "btn btn-primary" %>
<% end %>
<% end %> <% end %>

View File

@ -1,6 +1,12 @@
en: en:
survey: survey:
taken_survey: "Taken Survey"
please_login_first: "Please login first!"
view: View
export: Export
my_record: My Record
same_user_can_answer_repeatedly: Same user can answer repeatedly
survey: Survey survey: Survey
title: Title title: Title
needs_login: User need to login needs_login: User need to login
@ -22,6 +28,7 @@ en:
add_section: Add Section add_section: Add Section
taken_by: Taken By taken_by: Taken By
taken_date: Taken On taken_date: Taken On
records: Records
view_answers: View Answers view_answers: View Answers
result_type: Result Type (Frontend) result_type: Result Type (Frontend)

View File

@ -4,9 +4,15 @@ zh_tw:
survey: 問卷調查 survey: 問卷調查
survey: survey:
taken_survey: "填寫問卷"
please_login_first: "請先登入網站!"
view: 查看
export: 匯出
my_record: 我的填寫紀錄
same_user_can_answer_repeatedly: 同一使用者可重複填寫
survey: 問卷調查 survey: 問卷調查
title: 問卷標題 title: 問卷標題
needs_login: User need to login needs_login: 限登入會員填寫
time_range: 問卷期間 time_range: 問卷期間
write: 填問卷 write: 填問卷
result: 結果 result: 結果
@ -23,8 +29,9 @@ zh_tw:
is_external: 這份問卷為外部連結 is_external: 這份問卷為外部連結
add: 新增題目 add: 新增題目
add_section: 增加題組 add_section: 增加題組
taken_by: Taken By taken_by: 填寫人
taken_date: Taken On taken_date: 上次填寫時間
records: 填寫紀錄
view_answers: View Answers view_answers: View Answers
set_sections: 設定題組 set_sections: 設定題組
section_title: 題組標題 section_title: 題組標題

View File

@ -1,7 +1,27 @@
Rails.application.routes.draw do Rails.application.routes.draw do
locales = Site.first.in_use_locales rescue I18n.available_locales locales = Site.first.in_use_locales rescue I18n.available_locales
Thread.new do
surveys = QuestionnaireSurvey.where(:already_fix_data.in=>[nil,false]).to_a
surveys.each do |survey|
group_data = survey.survey_answers.asc(:updated_at).group_by(&:user)
group_data.each do |user_id,survey_answers|
answer_group = SurveyAnswerGroup.where(:questionnaire_survey_id=>survey.id,:user=>user_id).first
if answer_group.nil?
answer_group = SurveyAnswerGroup.new(:questionnaire_survey_id=>survey.id,:user=>user_id)
end
answer_group.last_modified = survey_answers.last.updated_at
answer_group.survey_answer_ids = survey_answers.map{|a| a.id}
answer_group.save
end
survey.already_fix_data = true
survey.survey_questions.each do |q|
q.survey_question_options.where("name.zh_tw.zh_tw"=>//).destroy
q.survey_question_options.where("name.en.en"=>//).destroy
end
survey.save
end
end
scope "(:locale)", locale: Regexp.new(locales.join("|")) do scope "(:locale)", locale: Regexp.new(locales.join("|")) do
namespace :admin do namespace :admin do
get "surveys/checkforthread", to: "surveys#checkforthread" get "surveys/checkforthread", to: "surveys#checkforthread"
@ -24,6 +44,8 @@ Rails.application.routes.draw do
get 'duplicate_it' get 'duplicate_it'
get 'answer_sets' get 'answer_sets'
get 'answer_set' get 'answer_set'
get 'answer_list'
get 'export_answers'
end end
resources :answers, :controller => :surveys_answers do resources :answers, :controller => :surveys_answers do
collection do collection do