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.
- data/MIT-LICENSE +20 -0
- data/README.markdown +64 -0
- data/Rakefile +39 -0
- data/app/assets/images/add.png +0 -0
- data/app/assets/images/delete.png +0 -0
- data/app/assets/javascripts/ask.js +2 -0
- data/app/assets/javascripts/ask/forms.js +100 -0
- data/app/assets/stylesheets/ask.css +4 -0
- data/app/assets/stylesheets/ask/forms.css.sass +139 -0
- data/app/assets/stylesheets/ask/submissions.css.sass +60 -0
- data/app/helpers/ask_helper.rb +23 -0
- data/app/models/answer.rb +20 -0
- data/app/models/checklist_question.rb +11 -0
- data/app/models/choice.rb +7 -0
- data/app/models/choose_one_question.rb +7 -0
- data/app/models/essay_question.rb +3 -0
- data/app/models/form_section.rb +7 -0
- data/app/models/question.rb +43 -0
- data/app/models/text_question.rb +3 -0
- data/app/views/answerer/_answers.html.haml +9 -0
- data/app/views/answerer/_form.html.haml +39 -0
- data/app/views/asker/_form.html.haml +27 -0
- data/app/views/asker/_form_preview.html.haml +35 -0
- data/db/migrate/20110913214050_create_answers.rb +15 -0
- data/db/migrate/20110913214255_create_choices.rb +11 -0
- data/db/migrate/20110913214410_create_questions.rb +15 -0
- data/lib/ask.rb +6 -0
- data/lib/ask/acts_as_answerer.rb +84 -0
- data/lib/ask/acts_as_asker.rb +8 -0
- data/lib/ask/engine.rb +4 -0
- data/lib/ask/version.rb +3 -0
- data/lib/assets/javascripts/jquery.handle-nesting.js +113 -0
- data/test/ask_test.rb +7 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +9 -0
- data/test/dummy/app/assets/stylesheets/application.css +7 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +45 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +30 -0
- data/test/dummy/config/environments/production.rb +60 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/log/development.log +0 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fixtures/answers.yml +13 -0
- data/test/fixtures/choices.yml +9 -0
- data/test/fixtures/questions.yml +17 -0
- data/test/fixtures/submissions.yml +9 -0
- data/test/functional/answers_controller_test.rb +49 -0
- data/test/functional/choices_controller_test.rb +49 -0
- data/test/functional/questions_controller_test.rb +49 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +10 -0
- data/test/unit/answer_test.rb +7 -0
- data/test/unit/choice_test.rb +7 -0
- data/test/unit/helpers/answers_helper_test.rb +4 -0
- data/test/unit/helpers/choices_helper_test.rb +4 -0
- data/test/unit/helpers/questions_helper_test.rb +4 -0
- data/test/unit/question_test.rb +7 -0
- metadata +231 -0
data/MIT-LICENSE
ADDED
@@ -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.
|
data/README.markdown
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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
|
Binary file
|
@@ -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,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
|