ask 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.markdown +64 -0
  3. data/Rakefile +39 -0
  4. data/app/assets/images/add.png +0 -0
  5. data/app/assets/images/delete.png +0 -0
  6. data/app/assets/javascripts/ask.js +2 -0
  7. data/app/assets/javascripts/ask/forms.js +100 -0
  8. data/app/assets/stylesheets/ask.css +4 -0
  9. data/app/assets/stylesheets/ask/forms.css.sass +139 -0
  10. data/app/assets/stylesheets/ask/submissions.css.sass +60 -0
  11. data/app/helpers/ask_helper.rb +23 -0
  12. data/app/models/answer.rb +20 -0
  13. data/app/models/checklist_question.rb +11 -0
  14. data/app/models/choice.rb +7 -0
  15. data/app/models/choose_one_question.rb +7 -0
  16. data/app/models/essay_question.rb +3 -0
  17. data/app/models/form_section.rb +7 -0
  18. data/app/models/question.rb +43 -0
  19. data/app/models/text_question.rb +3 -0
  20. data/app/views/answerer/_answers.html.haml +9 -0
  21. data/app/views/answerer/_form.html.haml +39 -0
  22. data/app/views/asker/_form.html.haml +27 -0
  23. data/app/views/asker/_form_preview.html.haml +35 -0
  24. data/db/migrate/20110913214050_create_answers.rb +15 -0
  25. data/db/migrate/20110913214255_create_choices.rb +11 -0
  26. data/db/migrate/20110913214410_create_questions.rb +15 -0
  27. data/lib/ask.rb +6 -0
  28. data/lib/ask/acts_as_answerer.rb +84 -0
  29. data/lib/ask/acts_as_asker.rb +8 -0
  30. data/lib/ask/engine.rb +4 -0
  31. data/lib/ask/version.rb +3 -0
  32. data/lib/assets/javascripts/jquery.handle-nesting.js +113 -0
  33. data/test/ask_test.rb +7 -0
  34. data/test/dummy/Rakefile +7 -0
  35. data/test/dummy/app/assets/javascripts/application.js +9 -0
  36. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  37. data/test/dummy/app/controllers/application_controller.rb +3 -0
  38. data/test/dummy/app/helpers/application_helper.rb +2 -0
  39. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  40. data/test/dummy/config.ru +4 -0
  41. data/test/dummy/config/application.rb +45 -0
  42. data/test/dummy/config/boot.rb +10 -0
  43. data/test/dummy/config/database.yml +25 -0
  44. data/test/dummy/config/environment.rb +5 -0
  45. data/test/dummy/config/environments/development.rb +30 -0
  46. data/test/dummy/config/environments/production.rb +60 -0
  47. data/test/dummy/config/environments/test.rb +42 -0
  48. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  49. data/test/dummy/config/initializers/inflections.rb +10 -0
  50. data/test/dummy/config/initializers/mime_types.rb +5 -0
  51. data/test/dummy/config/initializers/secret_token.rb +7 -0
  52. data/test/dummy/config/initializers/session_store.rb +8 -0
  53. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  54. data/test/dummy/config/locales/en.yml +5 -0
  55. data/test/dummy/config/routes.rb +58 -0
  56. data/test/dummy/log/development.log +0 -0
  57. data/test/dummy/public/404.html +26 -0
  58. data/test/dummy/public/422.html +26 -0
  59. data/test/dummy/public/500.html +26 -0
  60. data/test/dummy/public/favicon.ico +0 -0
  61. data/test/dummy/script/rails +6 -0
  62. data/test/fixtures/answers.yml +13 -0
  63. data/test/fixtures/choices.yml +9 -0
  64. data/test/fixtures/questions.yml +17 -0
  65. data/test/fixtures/submissions.yml +9 -0
  66. data/test/functional/answers_controller_test.rb +49 -0
  67. data/test/functional/choices_controller_test.rb +49 -0
  68. data/test/functional/questions_controller_test.rb +49 -0
  69. data/test/integration/navigation_test.rb +10 -0
  70. data/test/test_helper.rb +10 -0
  71. data/test/unit/answer_test.rb +7 -0
  72. data/test/unit/choice_test.rb +7 -0
  73. data/test/unit/helpers/answers_helper_test.rb +4 -0
  74. data/test/unit/helpers/choices_helper_test.rb +4 -0
  75. data/test/unit/helpers/questions_helper_test.rb +4 -0
  76. data/test/unit/question_test.rb +7 -0
  77. metadata +231 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2011 Biola University
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,64 @@
1
+ Ask
2
+ ===
3
+ Ask is a Rails engine that provides tools to simplify the process of letting your app's users build forms for things like questionnaires or surveys.
4
+
5
+ Requirements
6
+ ------------
7
+ - Rails 3.1 or higher
8
+
9
+ Installation
10
+ ------------
11
+ Add to your Gemfile:
12
+
13
+ gem 'ask'
14
+
15
+ In your terminal run:
16
+
17
+ bundle
18
+
19
+ Usage
20
+ -----
21
+ Ask needs to be tied to two models in your application: an "asker" and an "answerer". The asker model should be the model that has questions, such as a Survey or Event. The answerer model should be the model that has answers to the questions such as a SurveySubmission or an EventRegistration.
22
+
23
+ In your asker model add:
24
+
25
+ acts_as_asker
26
+
27
+ In your answerer model add:
28
+
29
+ acts_as_answerer
30
+
31
+ In your asker form views, inside an already defined `form_for` helper add:
32
+
33
+ <%= render(:partial => 'asker/form', :locals => { :f => f }) %>
34
+
35
+ In your answerer form views, inside an already defined `form_for` helper add:
36
+
37
+ <%= render(:partial => 'answerer/form', :locals => { :f => f }) %>
38
+
39
+ In your javascript manifest file add:
40
+
41
+ //= require ask
42
+
43
+ In your stylesheet manifest file add:
44
+
45
+ /*
46
+ *= require ask
47
+ */
48
+
49
+ In your answerer controller's `new` and `edit` methods you'll want to call `build_or_create_answers` and pass it in the appropriate questions. Such as:
50
+
51
+ @event_registration.build_or_create_answers @event_registration.event.questions
52
+
53
+
54
+ Finally you'll need to define an `asker` method on your answerer model, like so:
55
+
56
+ class EventRegistration < ActiveRecord::Base
57
+ def asker
58
+ return event
59
+ end
60
+ end
61
+
62
+ License
63
+ -------
64
+ MIT License
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Ask'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+ Bundler::GemHelper.install_tasks
28
+
29
+ require 'rake/testtask'
30
+
31
+ Rake::TestTask.new(:test) do |t|
32
+ t.libs << 'lib'
33
+ t.libs << 'test'
34
+ t.pattern = 'test/**/*_test.rb'
35
+ t.verbose = false
36
+ end
37
+
38
+
39
+ task :default => :test
Binary file
@@ -0,0 +1,2 @@
1
+ //= require jquery.handle-nesting
2
+ //= require ask/forms
@@ -0,0 +1,100 @@
1
+ $(document).ready(function()
2
+ {
3
+ var handleChoiceNesting = function(container)
4
+ {
5
+ $(container).find('ul.choices').handleNesting({
6
+ nameMatch: /(.*\[)[0-9]+(\].*)/,
7
+ nameReplace: '$1{NEW_ID}$2',
8
+ afterAdd: function(added)
9
+ {
10
+ insertDeleteButtons(added.parent(), ".choice");
11
+ }
12
+ });
13
+ }
14
+
15
+ var updateChoiceVisibility = function(select)
16
+ {
17
+ if (select.val() == "ChooseOneQuestion" || select.val() == "ChecklistQuestion")
18
+ select.parents("dl").find("dd.choices:hidden").slideDown("fast");
19
+ else
20
+ select.parents("dl").find("dd.choices:visible").slideUp("fast");
21
+ }
22
+
23
+ var bindTypeChange = function(select)
24
+ {
25
+ select.change(function()
26
+ {
27
+ updateChoiceVisibility($(this));
28
+ });
29
+ }
30
+
31
+ var insertDeleteButtons = function(container, selector)
32
+ {
33
+ container.find(selector).each(function()
34
+ {
35
+ // Add a delete button if there isn't one already
36
+ if ($(this).children("button.remove").length == 0)
37
+ {
38
+ $("<button type=\"button\" class=\"remove\">Remove</button>").click(function()
39
+ {
40
+ $(this).parents(selector).fadeOut("fast", function()
41
+ {
42
+ $(this).remove();
43
+ // If there's only one option left, remove the delete button
44
+ if (container.find(selector).length == 1)
45
+ container.find("button.remove:last").remove();
46
+ });
47
+
48
+ return false;
49
+ }).appendTo($(this));
50
+ }
51
+ });
52
+ }
53
+
54
+ var makeSortable = function()
55
+ {
56
+ var questions = $("form ul.ask.questions");
57
+ questions.sortable(
58
+ {
59
+ stop: function(event, ui)
60
+ {
61
+ var order = 1;
62
+ questions.find(".position-wrapper").each(function()
63
+ {
64
+ $(this).find("input").val(order);
65
+ order ++;
66
+ });
67
+ }
68
+ });
69
+ }
70
+
71
+ var selects = $("dd.type > select");
72
+
73
+ bindTypeChange(selects);
74
+
75
+ selects.each(function()
76
+ {
77
+ updateChoiceVisibility($(this));
78
+ });
79
+
80
+ makeSortable();
81
+
82
+ if(jQuery.fn.handleNesting)
83
+ {
84
+ $('form ul.ask.questions').handleNesting({
85
+ afterAdd: function(added)
86
+ {
87
+ handleChoiceNesting(added);
88
+ insertDeleteButtons(added.parent(), ".question");
89
+ bindTypeChange(added.find("dd.type > select"));
90
+ makeSortable();
91
+ }
92
+ });
93
+ }
94
+
95
+ $('form ul.ask.questions').children('li').each(function(i,li)
96
+ {
97
+ handleChoiceNesting(li);
98
+ });
99
+
100
+ });
@@ -0,0 +1,4 @@
1
+ /*
2
+ *= require ask/forms
3
+ *= require ask/submissions
4
+ */
@@ -0,0 +1,139 @@
1
+ ul.ask.questions
2
+ margin: 0
3
+ list-style-type: none
4
+
5
+ button.remove:after
6
+ content: " this question"
7
+
8
+ >li
9
+ position: relative
10
+ margin: 10px 0
11
+ padding: 10px 10px 25px 10px
12
+ border: solid 1px #ccc
13
+ background-color: #eee
14
+ cursor: move
15
+
16
+ dt
17
+ display: none
18
+
19
+ dd.type select
20
+ position: absolute
21
+ top: 10px
22
+ right: 120px
23
+ width: 100px
24
+
25
+ dd.choices
26
+ display: none
27
+
28
+ a.delete
29
+ float: none
30
+ text-indent: 400px
31
+ width: 16px
32
+ margin: 0px
33
+
34
+ a.delete:after
35
+ content: ""
36
+
37
+ dd.required select
38
+ position: absolute
39
+ top: 10px
40
+ right: 10px
41
+ width: 100px
42
+
43
+ dd.instructions
44
+ margin-top: 10px
45
+
46
+ textarea
47
+ height: 3em
48
+ font-family: sans-serif
49
+
50
+ input[type=text]
51
+ width: 300px
52
+
53
+ input[type=checkbox]
54
+ display: none
55
+
56
+ button
57
+ float: right
58
+ clear: both
59
+
60
+ button.remove
61
+ padding: 0px
62
+ color: #000
63
+ font-family: sans-serif
64
+ font-size: 9pt
65
+ font-weight: normal
66
+ text-shadow: none
67
+ border: none
68
+ background: image-url("delete.png") no-repeat transparent
69
+ display: inline-block
70
+ vertical-align: 1px
71
+ text-indent: 20px
72
+ margin: 5px
73
+ float: right
74
+ height: 16px
75
+ text-decoration: none
76
+ -moz-box-shadow: none
77
+ -webkit-box-shadow: none
78
+ box-shadow: none
79
+
80
+ button.remove:after
81
+ content: " Question"
82
+
83
+ button.remove:active
84
+ top: 0px
85
+
86
+ button.add
87
+ float: none
88
+ height: 16px
89
+ padding: 0 20px 0 0
90
+ color: #000
91
+ font-family: sans-serif
92
+ font-size: 9pt
93
+ font-weight: normal
94
+ text-shadow: none
95
+ border: none
96
+ background: image-url("add.png") left center no-repeat transparent
97
+ -moz-box-shadow: none
98
+ -webkit-box-shadow: none
99
+ box-shadow: none
100
+ text-indent: 20px
101
+
102
+ button.add:after
103
+ content: " Choice"
104
+
105
+ ul.choices
106
+
107
+ li
108
+ margin: 10px 0
109
+ padding: 0
110
+ border: none
111
+ background: transparent
112
+
113
+ label
114
+ display: none
115
+
116
+ input[type=text]
117
+ width: 200px
118
+
119
+ input[type=checkbox]
120
+ display: none
121
+
122
+ button.remove
123
+ position: relative
124
+ float: none
125
+ margin: 0px
126
+ right: 0
127
+ bottom: 0
128
+ height: 16px
129
+ width: 16px
130
+ padding: 0
131
+ text-indent: -9999px
132
+ border: none
133
+ background: image-url("delete.png") no-repeat transparent
134
+ -moz-box-shadow: none
135
+ -webkit-box-shadow: none
136
+ box-shadow: none
137
+
138
+ button.remove:after
139
+ content: ""
@@ -0,0 +1,60 @@
1
+ #page
2
+
3
+ &.submissions.show
4
+ dd
5
+ padding-left: 10px
6
+
7
+ &.application_forms, &.reference_forms, &.interview_forms
8
+ &.show
9
+ #wrapperContent
10
+ #content
11
+ background-image: url(../images/preview.png)
12
+ background-position: top right
13
+ background-repeat: no-repeat
14
+
15
+ #content
16
+
17
+ h3.section
18
+ margin-top: 40px
19
+ border-bottom: solid 1px #ccc
20
+
21
+ .instructions
22
+ display: block
23
+ font-style: italic
24
+ font-weight: normal
25
+
26
+ dt
27
+
28
+ .instructions
29
+ margin: 5px 0
30
+ color: #333
31
+ font-size: 10pt
32
+
33
+
34
+ input[type=text], textarea
35
+ width: 400px
36
+
37
+ textarea
38
+ height: 100px
39
+
40
+ h2
41
+ border-bottom: solid 1px #ccc
42
+
43
+ dt, dd
44
+ font-size: 11pt
45
+
46
+ dt
47
+ padding-top: 10px
48
+ letter-spacing: -.05em
49
+
50
+ #contentAside
51
+ a
52
+ &.csv, &.table
53
+ padding-left: 24px
54
+ font-size: 10pt
55
+ font-weight: bold
56
+ text-decoration: none
57
+ &.csv
58
+ background: url(../images/csv.png) 5px center no-repeat
59
+ &.table
60
+ background: url(../images/table.png) 5px center no-repeat
@@ -0,0 +1,23 @@
1
+ module AskHelper
2
+
3
+ def question_label(question, builder=nil)
4
+ if question.type.to_sym == :ChecklistQuestion
5
+ h(question.name)
6
+ else
7
+ if builder
8
+ builder.label(:answer, question.name)
9
+ else
10
+ label_tag(:answer, question.name)
11
+ end
12
+ end
13
+ end
14
+
15
+ def question_instructions(question)
16
+ require 'rails_autolink/helpers'
17
+
18
+ unless question.instructions.blank?
19
+ content_tag(:span, auto_link(simple_format(question.instructions), :all, :target=>'_blank'), :class=>'instructions')
20
+ end || ''
21
+ end
22
+
23
+ end