ask 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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