Merge branch 'final_questions' of https://github.com/differentreality/osem into differentreality-final_questions

Conflicts:
	app/models/conference.rb
	config/routes.rb
This commit is contained in:
Henne Vogelsang
2014-03-03 10:43:38 +01:00
28 changed files with 342 additions and 16 deletions

View File

@@ -20,4 +20,9 @@
//= require bootstrap
//= require osem
//= require d3.v3
//= require d3.v3.min
//= require d3.v3.min
$(document).ready(function() {
$('a[disabled=disabled]').click(function(event){
return false;
});
});

View File

@@ -0,0 +1,96 @@
class Admin::QuestionsController < ApplicationController
before_filter :verify_organizer
def index
@conference = Conference.find_all_by_short_title(params[:conference_id]).first
@questions = Question.where(:global => true).all | Question.where(:conference_id => @conference.id)
@questions_conference = @conference.questions
@new_question = @conference.questions.new
end
def new
@conference = Conference.find_all_by_short_title(params[:conference_id]).first
@new_question = @conference.questions.new
end
def create
@conference = Conference.find_all_by_short_title(params[:conference_id]).first
@question = @conference.questions.new(params[:question])
@question.conference_id = @conference.id
respond_to do |format|
if @conference.save
format.html { redirect_to admin_conference_questions_path, notice: 'Question was successfully created.' }
else
flash[:error] = "Oops, couldn't save. Question and answer(s) have titles?"
format.html { redirect_to admin_conference_questions_path }
end
end
end
# GET questions/1/edit
def edit
@conference = Conference.find_all_by_short_title(params[:conference_id]).first
@question = Question.find(params[:id])
if @question.global == true && !has_role?(current_user, "Admin")
redirect_to(admin_conference_questions_path(:conference_id => @conference.short_title), :alert => "Sorry, you cannot edit global questions. Create a new one.")
end
end
# PUT questions/1
def update
@conference = Conference.find_all_by_short_title(params[:conference_id]).first
@question = Question.find(params[:id])
if @question.update_attributes(params[:question])
redirect_to(admin_conference_questions_path(:conference_id => @conference.short_title), :notice => "Question '#{@question.title}' for #{@conference.short_title} successfully updated.")
else
redirect_to(admin_conference_questions_path(:conference_id => @conference.short_title), :notice => "Update of questions for #{@conference.short_title} failed.")
end
end
# Update questions used for the conference
def update_conference
@conference = Conference.find_all_by_short_title(params[:conference_id]).first
if @conference.update_attributes(params[:conference])
redirect_to(admin_conference_questions_path(:conference_id => @conference.short_title), :notice => "Questions for #{@conference.short_title} successfully updated.")
else
redirect_to(admin_conference_questions_path(:conference_id => @conference.short_title), :notice => "Update of questions for #{@conference.short_title} failed.")
end
end
# DELETE questions/1
def destroy
if has_role?(current_user, "Admin")
@question = Question.find(params[:id])
# Do not delete global questions
if @question.global == false
# Delete question and its answers
begin
Question.transaction do
@question.delete
@question.answers.each do |a|
a.delete
end
flash[:notice] = "Deleted question: #{@question.title} and its answers: #{@question.answers.map {|a| a.title}.join ','}"
end
rescue ActiveRecord::RecordInvalid
flash[:error] = "Could not delete question."
end
else
flash[:error] = "You cannot delete global questions."
end
else
flash[:error] = "You must be an admin to delete a question."
end
@questions = Question.where(:global => true).all | Question.where(:conference_id => @conference.id)
@questions_conference = @conference.questions
end
end

View File

@@ -6,7 +6,7 @@ class Admin::RegistrationsController < ApplicationController
@pdf_filename = "#{@conference.title}.pdf"
@registrations = @conference.registrations.includes(:person).order("registrations.created_at ASC")
@attended = @conference.registrations.where("attended = ?", true).count
@headers = %w[name email attending_social_events attending_with_partner need_access other_needs arrival departure attended]
@headers = %w[first_name last_name email irc_nickname other_needs arrival departure attended]
end
def change_field
@@ -128,4 +128,4 @@ class Admin::RegistrationsController < ApplicationController
redirect_to(admin_conference_registrations_path(@conference.short_title), :alert => 'You must be an admin to delete a registration.')
end
end
end
end

8
app/models/answer.rb Normal file
View File

@@ -0,0 +1,8 @@
class Answer < ActiveRecord::Base
attr_accessible :title
has_many :qanswers
has_many :questions, :through => :qanswers
validates :title, :presence => true
end

View File

@@ -2,10 +2,12 @@ class Conference < ActiveRecord::Base
attr_accessible :title, :short_title, :social_tag, :contact_email, :timezone, :html_export_path,
:start_date, :end_date, :rooms_attributes, :tracks_attributes, :dietary_choices_attributes,
:use_dietary_choices, :use_supporter_levels, :supporter_levels_attributes, :social_events_attributes,
:event_types_attributes, :difficulty_levels_attributes, :use_difficulty_levels, :registration_start_date, :registration_end_date, :logo
:event_types_attributes, :registration_start_date, :registration_end_date, :logo, :questions_attributes, :question_ids, :answers_attributes, :answer_ids, :difficulty_levels_attributes, :use_difficulty_levels
has_paper_trail
has_and_belongs_to_many :questions
has_one :email_settings, :dependent => :destroy
has_one :call_for_papers, :dependent => :destroy
has_many :social_events, :dependent => :destroy
@@ -30,6 +32,7 @@ class Conference < ActiveRecord::Base
accepts_nested_attributes_for :supporter_levels, :allow_destroy => true
accepts_nested_attributes_for :event_types, :allow_destroy => true
accepts_nested_attributes_for :email_settings
accepts_nested_attributes_for :questions, :allow_destroy => true
has_attached_file :logo,
:styles => {:thumb => "100x100>", :large => "300x300>" }
@@ -119,4 +122,4 @@ class Conference < ActiveRecord::Base
self.guid = guid
end
end
end

8
app/models/qanswer.rb Normal file
View File

@@ -0,0 +1,8 @@
class Qanswer < ActiveRecord::Base
attr_accessible :question_id, :answer_id
belongs_to :question
belongs_to :answer, :dependent => :delete
has_and_belongs_to_many :registrations
end

14
app/models/question.rb Normal file
View File

@@ -0,0 +1,14 @@
class Question < ActiveRecord::Base
attr_accessible :title, :global, :answers_attributes, :answer_ids, :question_type_id
belongs_to :question_type
has_and_belongs_to_many :conferences
has_many :qanswers, :dependent => :delete_all
has_many :answers, :through => :qanswers, :dependent => :delete_all
validates :title, :presence => true
validates :answers, :presence => true
accepts_nested_attributes_for :answers, :allow_destroy => true
end

View File

@@ -0,0 +1,5 @@
class QuestionType < ActiveRecord::Base
attr_accessible :title, :description
has_many :questions
end

View File

@@ -7,15 +7,16 @@ class Registration < ActiveRecord::Base
has_one :supporter_level, :through => :supporter_registration
has_and_belongs_to_many :social_events
has_and_belongs_to_many :events
has_and_belongs_to_many :qanswers
attr_accessible :person_id, :conference_id, :attending_social_events, :attending_with_partner,
:using_affiliated_lodging, :arrival, :departure, :person_attributes, :other_dietary_choice, :dietary_choice_id,
:handicapped_access_required, :supporter_registration_attributes, :social_event_ids, :other_special_needs,
:event_ids, :attended
:handicapped_access_required, :supporter_registration_attributes, :social_event_ids, :other_special_needs, :event_ids, :attended, :qanswer_ids, :qanswers_attributes
accepts_nested_attributes_for :person
accepts_nested_attributes_for :supporter_registration
accepts_nested_attributes_for :social_events
accepts_nested_attributes_for :qanswers
delegate :first_name, :to => :person
delegate :last_name, :to => :person
@@ -24,7 +25,5 @@ class Registration < ActiveRecord::Base
delegate :irc_nickname, :to => :person
delegate :company, :to => :person
alias_attribute :with_partner, :attending_with_partner
alias_attribute :need_access, :handicapped_access_required
alias_attribute :other_needs, :other_special_needs
end

View File

@@ -47,4 +47,7 @@
%li.active= link_to "Dietary Choices", "#"
- else
%li= link_to "Dietary Choices", admin_conference_dietary_list_path(@conference.short_title)
- if activated == "Questions"
%li.active= link_to "Questions", "#"
- else
%li= link_to "Questions", admin_conference_questions_path(@conference.short_title)

View File

@@ -0,0 +1,4 @@
.nested-fields
= f.inputs do
= f.input :title
= remove_association_link :answer, f

View File

@@ -0,0 +1,8 @@
.row-fluid
.span6
%legend Question
= f.input :title, :label => "Your Question"
= f.input :question_type
= f.input :global, :label => "Make Global", :hint => "(Global questions are available for selection to all conferences)"
.span6
= dynamic_association :answers, "Answers", f, :hint => "Insert your answers in the order you want them to appear"

View File

@@ -0,0 +1,20 @@
%h2
Questions for #{@conference.short_title}
- if @questions_conference.count
= "(#{@questions_conference.count})"
%i The questions will appear in the registration page of the conference
%table.table
- @questions.each do |q|
%tr
%td
= hidden_field_tag "conference[question_ids][]", nil
= check_box_tag "conference[question_ids][]", q.id, @conference.question_ids.include?(q.id), id: dom_id(q)
%td
= label_tag dom_id(q), q.title
= label_tag dom_id(q), "Type: #{q.question_type.title}"
= label_tag dom_id(q), "Answers: #{q.answers.map {|a| a.title}.join(', ')}"
%td= link_to "Edit", edit_admin_conference_question_path(@conference.short_title, q), :class => "btn btn-primary", :disabled => q.global == true && !has_role?(current_user, "Admin")
%td= link_to "Delete", admin_conference_question_path(@conference.short_title, q), :method => :delete, :remote => true, :class => "btn btn-danger", :confirm => "Delete question '#{q.title}'?", :disabled => q.global == true && !has_role?(current_user, "Admin")

View File

@@ -0,0 +1 @@
$('#myquestions').html("<%= escape_javascript(render :partial => 'questions') %>");

View File

@@ -0,0 +1,9 @@
%h2
Edit Question
%h3
"#{@question.title}"
= semantic_form_for(@question, :url => admin_conference_question_path(@conference.short_title, @question.id)) do |f|
= render :partial => "form", :locals => {:f => f}
= f.submit "Save", :class => "btn btn-primary", :confirm => "Are you sure you want to make these changes?"

View File

@@ -0,0 +1,31 @@
.container-fluid
.row-fluid
.span3
= render 'admin/conference/sidebar', :activated => "Questions"
.span9
.pull-right
%b= link_to "Create New Question","#", "data-toggle" => "modal", "data-target" => "#new-question", :class => "btn btn-success"
%br
%br
- if @questions.count > 0
= semantic_form_for(@conference, :url => admin_conference_questions_update_conference_path(@conference.short_title), :method => 'put') do |f|
.questions{:id => "myquestions"}
= render :partial => "questions"
= f.submit "Update Questions for #{@conference.short_title}", :class => "btn btn-primary", :confirm => "Are you sure you want to make these changes?"
.modal.hide.fade{:id => "new-question", "role" => "dialog", "aria-hidden" => "true"}
.modal-header
%h3{:id => "new-question-header"}
Add new question
.modal-body
= semantic_form_for(@new_question, :url => admin_conference_questions_path(@conference.short_title), :method => :post) do |f|
= render :partial => "form", :locals => {:f => f}
%button{:class => "btn btn-primary"}
Save
.pull-right
%button{:class=> "btn btn-danger", "data-dismiss"=> "modal", "aria-hidden"=>"true"}
Cancel

View File

@@ -0,0 +1,9 @@
- @conference.questions.each do |q|
%b Q:
= q.title
%b A:
- registration.qanswers.where(:question_id => q.id).each do |qa|
= qa.answer.title
%br

View File

@@ -11,7 +11,7 @@
- if @registrations
= "(#{@registrations.length})"
= " - Attended (#{@attended})"
%table.table.table-striped.table-bordered.table-hover#registrations
%table.table.table-bordered.table-striped.table-hover#registrations
%thead
%th
No
@@ -21,6 +21,7 @@
= h.capitalize
%th
%th
%th
- counter = 0
- @registrations.each do |registration|
%tr
@@ -45,11 +46,17 @@
- else
= registration.send(field.to_sym)
%td
= link_to "Questions", "#", :class => "questions btn btn-success", :id => counter, :onclick => "toggle('row#{counter}')"
%td
= link_to "Edit", admin_conference_registrations_edit_path(@conference.short_title, :id => registration.id), :method => :get, :class => "btn btn-primary"
%td
= link_to "Delete", admin_conference_registrations_path(@conference.short_title, :id => registration.id), :method => :delete, :class => "btn btn-danger", :confirm => "Really delete registration for #{registration.public_name} #{registration.email}?"
%tr{:id => "row#{counter}", :style=>"display:none;"}
%td{:colspan=>13}
= render :partial => "questions", :locals => {:registration => registration}
:javascript
$(document).ready(function() {
@@ -58,3 +65,11 @@
"bLengthChange": false
} );
} );
function toggle(rowid) {
if( document.getElementById(rowid).style.display=='none' ){
document.getElementById(rowid).style.display = '';
}else{
document.getElementById(rowid).style.display = 'none';
}
};

View File

@@ -0,0 +1,13 @@
- @conference.questions.each do |q|
%h5
= "Q: #{q.title}"
- if q.question_type.id == 1 || q.question_type.id == 2 # yes/no or single choice
= f.input :qanswers, :collection => q.qanswers, :as => :select, :input_html => { :multiple => false }, :label => false, :include_blank => "Please make your choice",
:member_label => Proc.new {|a| a.answer.title}
- if q.question_type.id == 3 # multiple choice
= f.input :qanswers, :collection => q.qanswers, :as => :check_boxes, :label => false,
:member_label => Proc.new {|a| a.answer.title}

View File

@@ -17,15 +17,18 @@
%br
= f.fields_for :person do |p|
= p.text_field :public_name, :for => :person
- if @conference.use_supporter_levels?
- if @conference.questions
= render :partial => "questions", :locals => {:f => f}
%br
- if @conference.use_supporter_levels? && @conference.supporter_levels.count > 0
= f.semantic_fields_for :supporter_registration do |reg|
= reg.input :supporter_level, :as => :select, :collection => @conference.supporter_levels
= reg.input :code, :label => "Confirmation or registration code (if applicable)"
%span#supporter-link.help-block
= f.input :attending_with_partner, :label => false
= f.input :using_affiliated_lodging, :label => false
= f.input :handicapped_access_required, :label => false
= f.input :other_special_needs, :label => "Any other special needs?", :input_html => {:rows => 2}
= f.input :other_special_needs, :label => "Any other needs or comments?", :input_html => {:rows => 2, :class => "span6"}
- if @workshops.count > 0
=f.inputs "Register to workshops" do

View File

@@ -37,6 +37,8 @@ Osem::Application.routes.draw do
put "/event_types" => "eventtype#update", :as => "eventtype_update"
put "/difficulty_levels" => "difficulty_levels#update"
resources :difficulty_levels
put "/questions/update_conference" => "questions#update_conference"
resources :questions
resources :events do
member do
post :comment

View File

@@ -0,0 +1,12 @@
class CreateQuestions < ActiveRecord::Migration
def change
create_table :questions do |t|
t.string :title
t.references :question_type
t.integer :conference_id
t.boolean :global
t.timestamps
end
end
end

View File

@@ -0,0 +1,9 @@
class CreateQuestionTypes < ActiveRecord::Migration
def change
create_table :question_types do |t|
t.string :title
t.timestamps
end
end
end

View File

@@ -0,0 +1,9 @@
class CreateAnswers < ActiveRecord::Migration
def change
create_table :answers do |t|
t.string :title
t.timestamps
end
end
end

View File

@@ -0,0 +1,8 @@
class CreateQanswers < ActiveRecord::Migration
def change
create_table :qanswers do |t|
t.references :question
t.references :answer
end
end
end

View File

@@ -0,0 +1,8 @@
class CreateConferencesQuestions < ActiveRecord::Migration
def change
create_table :conferences_questions, :id => false do |t|
t.references :conference
t.references :question
end
end
end

View File

@@ -0,0 +1,8 @@
class CreateQanswersRegistrations < ActiveRecord::Migration
def change
create_table :qanswers_registrations, :id => false do |t|
t.references :registration, :null => false
t.references :qanswer, :null => false
end
end
end

View File

@@ -8,3 +8,19 @@
Role.create(:name => "Participant")
Role.create(:name => "Organizer")
Role.create(:name => "Admin")
qtype_yesno = QuestionType.create(:title => "Yes/No")
qtype_single = QuestionType.create(:title => "Single Choice")
qtype_multiple = QuestionType.create(:title => "Multiple Choice")
answer_yes = Answer.create(:title => "Yes")
answer_no = Answer.create(:title => "No")
questions_yes_no = ["Do you need handicapped access to the venue?", "Are you attending with partner?", "Will you attend the social event(s)?", "Will you stay at suggested hotel?"]
for i in questions_yes_no do
q = Question.create(:title => i, :question_type_id => qtype_yesno.id, :global => true)
Qanswer.create(:question_id => q.id, :answer_id => answer_no.id)
Qanswer.create(:question_id => q.id, :answer_id => answer_yes.id)
end