ask 0.3.1 → 0.4.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/README.markdown +5 -1
- data/app/assets/javascripts/ask.js.coffee +150 -46
- data/app/assets/stylesheets/ask.css.scss +58 -0
- data/app/helpers/ask_helper.rb +9 -0
- data/app/views/asker/_choice_fields.html.haml +6 -0
- data/app/views/asker/_choices.html.haml +17 -0
- data/app/views/asker/_form.html.haml +5 -27
- data/app/views/asker/_question_fields.html.haml +33 -0
- data/lib/ask/version.rb +1 -1
- metadata +6 -4
- data/app/assets/stylesheets/ask.css.sass +0 -139
- data/lib/assets/javascripts/jquery.handle-nesting.js.coffee +0 -84
data/README.markdown
CHANGED
@@ -5,6 +5,8 @@ Ask is a Rails engine that provides tools to simplify the process of letting you
|
|
5
5
|
Requirements
|
6
6
|
------------
|
7
7
|
- Rails 3.1 or higher
|
8
|
+
- jQuery
|
9
|
+
- jQuery UI
|
8
10
|
|
9
11
|
Installation
|
10
12
|
------------
|
@@ -48,6 +50,7 @@ In your stylesheet manifest file add:
|
|
48
50
|
*= require ask
|
49
51
|
*/
|
50
52
|
|
53
|
+
If you want your form to start with one question, you can do the following...
|
51
54
|
In your asker controller's `new` and `edit` methods you'll need to build the first question and choice. The best way to do this is create a private method:
|
52
55
|
|
53
56
|
def build_questions
|
@@ -58,8 +61,9 @@ In your asker controller's `new` and `edit` methods you'll need to build the fir
|
|
58
61
|
Then at the top of your asker controller, include:
|
59
62
|
|
60
63
|
before_filter :build_questions, :only => [:new, :edit]
|
64
|
+
# or you can call the build_questions method inside the new or edit controller
|
61
65
|
|
62
|
-
In your answerer controller's `new` and `edit` methods you'll
|
66
|
+
In your answerer controller's `new` and `edit` methods you'll need to call `build_or_create_answers` and pass it in the appropriate questions. Such as:
|
63
67
|
|
64
68
|
@event_registration.build_or_create_answers @event_registration.event.questions
|
65
69
|
|
@@ -1,54 +1,158 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
jQuery ->
|
2
|
+
###
|
3
|
+
Handle adding and removing fields
|
4
|
+
###
|
5
|
+
$('form').on 'click', '.remove_fields', (event) ->
|
6
|
+
$(this).prev('input[type=hidden]').val('1')
|
7
|
+
$(this).closest('fieldset').hide()
|
8
|
+
event.preventDefault()
|
9
|
+
|
10
|
+
$('form').on 'click', '.add_fields', (event) ->
|
11
|
+
time = new Date().getTime()
|
12
|
+
regexp = new RegExp($(this).data('id'), 'g')
|
13
|
+
new_question = $($(this).data('fields').replace(regexp, time))
|
14
|
+
$(this).before(new_question)
|
15
|
+
createQuestionPreview new_question
|
16
|
+
toggleEditMode new_question
|
17
|
+
event.preventDefault()
|
18
|
+
|
19
|
+
###
|
20
|
+
Update the edit preview mode between textQuestion, ChecklistQuestion, etc.
|
21
|
+
###
|
11
22
|
updateChoiceVisibility = (select) ->
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
23
|
+
question = select.parents("fieldset.question")
|
24
|
+
question_choices = question.find(".edit-question-choices")
|
25
|
+
question_choices.find(".question-type").hide() # first hide all the question types
|
26
|
+
current_question_type = question_choices.find(".question-type."+select.val())
|
27
|
+
current_question_type.show() # Then show the current question type
|
28
|
+
question.find('.required-option').show() # show the required-option field, it may be hidden later by certain question types
|
29
|
+
if select.val() == 'ChooseOneQuestion'
|
30
|
+
current_question_type.removeClass('show-checkbox').addClass('show-radio')
|
31
|
+
else if select.val() == 'ChecklistQuestion'
|
32
|
+
current_question_type.removeClass('show-radio').addClass('show-checkbox')
|
33
|
+
else if select.val() == 'FormSection'
|
34
|
+
question.find('.required-option').hide()
|
16
35
|
|
36
|
+
# Update preview type whenever the user changes the type of this question
|
17
37
|
bindTypeChange = (select) ->
|
18
|
-
select.change ->
|
38
|
+
select.live "change", ->
|
19
39
|
updateChoiceVisibility $(this)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
if $(this).children("button.remove").length == 0
|
24
|
-
$("<button type=\"button\" class=\"remove\">Remove</button>").click(->
|
25
|
-
$(this).parents(selector).fadeOut "fast", ->
|
26
|
-
$(this).remove()
|
27
|
-
container.find("button.remove:last").remove() if container.find(selector).length == 1
|
28
|
-
|
29
|
-
false
|
30
|
-
).appendTo $(this)
|
31
|
-
|
32
|
-
makeSortable = ->
|
33
|
-
questions = $("form ul.ask.questions")
|
34
|
-
questions.sortable stop: (event, ui) ->
|
35
|
-
order = 1
|
36
|
-
questions.find(".position-wrapper").each ->
|
37
|
-
$(this).find("input").val order
|
38
|
-
order++
|
39
|
-
|
40
|
-
selects = $("dd.type > select")
|
40
|
+
|
41
|
+
# Update once when the DOM first loads
|
42
|
+
selects = $(".select-question-type select")
|
41
43
|
bindTypeChange selects
|
42
44
|
selects.each ->
|
43
45
|
updateChoiceVisibility $(this)
|
44
|
-
|
46
|
+
|
47
|
+
|
48
|
+
###
|
49
|
+
Make the list sortable
|
50
|
+
###
|
51
|
+
makeSortable = ->
|
52
|
+
questions = $("form .ask.questions")
|
53
|
+
questions.sortable
|
54
|
+
axis: "y"
|
55
|
+
stop: (event, ui) ->
|
56
|
+
order = 1
|
57
|
+
questions.find(".position-wrapper").each ->
|
58
|
+
$(this).find("input").val order
|
59
|
+
order++
|
45
60
|
makeSortable()
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
61
|
+
|
62
|
+
|
63
|
+
###
|
64
|
+
Toggle between 'edit' question and 'preview' question
|
65
|
+
###
|
66
|
+
createQuestionPreview = (question) ->
|
67
|
+
if question.children('preview-question-fields').length == 0 # if we don't have a question preview yet
|
68
|
+
asker = question.serialize().match(/^\w+/)[0] # get asker name
|
69
|
+
question_type = question.find('.select-question-type select').val() # get question type
|
70
|
+
question_details = question.serializeObject(/^.*?\[\d+\]/) # get question details and choices
|
71
|
+
|
72
|
+
preview_section = $("<div class='preview-question-fields'></div>") # create DOM object
|
73
|
+
question.append preview_section
|
74
|
+
q_label = $("<label class='preview-question-name'>"+question_details.name+"</label>")
|
75
|
+
q_label.addClass("required") if question_details.required == "1"
|
76
|
+
q_help_text = if (question_details.instructions != "") then $("<p class='help-block'>"+question_details.instructions+"</p>") else false
|
77
|
+
|
78
|
+
# generate preview based on question type
|
79
|
+
switch question_type
|
80
|
+
when "TextQuestion"
|
81
|
+
preview_section.append(q_label).append("<input type='text'>")
|
82
|
+
preview_section.append(q_help_text) if q_help_text
|
83
|
+
when "EssayQuestion"
|
84
|
+
preview_section.append(q_label).append("<textarea></textarea>")
|
85
|
+
preview_section.append(q_help_text) if q_help_text
|
86
|
+
when "ChooseOneQuestion"
|
87
|
+
preview_section.append(q_label)
|
88
|
+
preview_section.append(q_help_text) if q_help_text
|
89
|
+
$.each question_details.choices_attributes, (k,v) ->
|
90
|
+
unless v._destroy == "1"
|
91
|
+
checkbox_item = $("<div class='checkbox-preview-item'></div>")
|
92
|
+
checkbox_item.append("<input type='radio'>")
|
93
|
+
checkbox_item.append("<span>"+v.name+"</span>")
|
94
|
+
preview_section.append(checkbox_item)
|
95
|
+
when "ChecklistQuestion"
|
96
|
+
preview_section.append(q_label)
|
97
|
+
preview_section.append(q_help_text) if q_help_text
|
98
|
+
$.each question_details.choices_attributes, (k,v) ->
|
99
|
+
unless v._destroy == "1"
|
100
|
+
checkbox_item = $("<div class='checkbox-preview-item'></div>")
|
101
|
+
checkbox_item.append("<input type='checkbox'>")
|
102
|
+
checkbox_item.append("<span>"+v.name+"</span>")
|
103
|
+
preview_section.append(checkbox_item)
|
104
|
+
when "FormSection"
|
105
|
+
preview_section.append("<h3>"+question_details.name+"</h3>")
|
106
|
+
preview_section.append(q_help_text) if q_help_text
|
107
|
+
preview_section.append("<hr/>")
|
108
|
+
|
109
|
+
toggleEditMode = (question) ->
|
110
|
+
if question.hasClass('preview')
|
111
|
+
$('fieldset.question.edit').each -> # first put all other questions into preview mode.
|
112
|
+
toggleEditMode($(this))
|
113
|
+
question.find('.preview-question-fields').remove()
|
114
|
+
question.find('.edit-question-link').html('Done')
|
115
|
+
question.removeClass('preview').addClass('edit')
|
116
|
+
|
117
|
+
else if question.hasClass('edit')
|
118
|
+
createQuestionPreview(question)
|
119
|
+
question.find('.edit-question-link').html('Edit')
|
120
|
+
question.removeClass('edit').addClass('preview')
|
121
|
+
|
122
|
+
|
123
|
+
$('fieldset.question').each ->
|
124
|
+
createQuestionPreview $(this)
|
125
|
+
|
126
|
+
$('a.edit-question-link').live "click", (e) ->
|
127
|
+
toggleEditMode($(this).closest('fieldset.question'))
|
128
|
+
e.preventDefault()
|
129
|
+
|
130
|
+
|
131
|
+
jQuery.fn.serializeObject = (ignore_regex = null) ->
|
132
|
+
arrayData = @serializeArray()
|
133
|
+
objectData = {}
|
134
|
+
|
135
|
+
pushData = (node, hash_tail, value) ->
|
136
|
+
hash = hash_tail.shift()
|
137
|
+
if hash_tail.length == 0
|
138
|
+
node[hash] = value
|
139
|
+
else
|
140
|
+
unless node[hash]?
|
141
|
+
node[hash] = {}
|
142
|
+
pushData(node[hash], hash_tail, value)
|
143
|
+
|
144
|
+
$.each arrayData, ->
|
145
|
+
if @value?
|
146
|
+
value = @value
|
147
|
+
else
|
148
|
+
value = ''
|
149
|
+
|
150
|
+
# splits nested hash into array of keys
|
151
|
+
# @name needs to be in the form of person[attributes][about][name]
|
152
|
+
# It can also ignore a regular expression
|
153
|
+
hash_array = @name.replace(ignore_regex, "").match(/\w+/g)
|
154
|
+
|
155
|
+
# recursive function that builds a nested object based on the name
|
156
|
+
pushData(objectData, hash_array, value)
|
157
|
+
|
158
|
+
return objectData
|
@@ -0,0 +1,58 @@
|
|
1
|
+
.ask.questions { margin: 0; list-style-type: none; background: white; border: solid 1px #ddd;
|
2
|
+
a.add_fields { display: block; padding: 15px;
|
3
|
+
&:hover { background-color: #FFF9DD; }
|
4
|
+
}
|
5
|
+
fieldset { border: none; }
|
6
|
+
|
7
|
+
>fieldset.question { position: relative; margin: 0; padding: 10px 10px 25px 10px; cursor: move;
|
8
|
+
|
9
|
+
input[type=text] { width: 300px; }
|
10
|
+
textarea { height: 3em; width: 60%; font-family: sans-serif; }
|
11
|
+
.question-action-links { float: right; display: none; }
|
12
|
+
|
13
|
+
&:hover { background-color: #FFF9DD;
|
14
|
+
.question-action-links { display: inline-block; }
|
15
|
+
}
|
16
|
+
|
17
|
+
&.preview { // hide edit fields when in preview mode
|
18
|
+
.edit-question-fields { display: none; }
|
19
|
+
input[type="checkbox"], input[type="radio"] { margin: 0 8px 4px; }
|
20
|
+
label.preview-question-name { font-weight: bold; }
|
21
|
+
h3 { margin-bottom: 0; }
|
22
|
+
hr { margin-bottom: 0; border-top: 1px solid #EEE; border-bottom: none; }
|
23
|
+
.help-block { color: #595959; }
|
24
|
+
}
|
25
|
+
&.edit { background-color: #FFF4C2;
|
26
|
+
.question-action-links { display: inline-block; }
|
27
|
+
table {
|
28
|
+
th { text-align: left; }
|
29
|
+
}
|
30
|
+
|
31
|
+
.askwidget-fieldlabel {
|
32
|
+
label { font-weight: bold; display: inline-block; margin-right: 20px; }
|
33
|
+
}
|
34
|
+
|
35
|
+
.required-option { display: inline-block;
|
36
|
+
input[type="checkbox"] { margin: 0 5px 0; }
|
37
|
+
}
|
38
|
+
|
39
|
+
.edit-question-choices { margin: 10px;
|
40
|
+
.start-hidden { display: none; }
|
41
|
+
.question-type {
|
42
|
+
fieldset.choice { margin-bottom: 10px;
|
43
|
+
input[type="radio"], input[type="checkbox"] { display: none; margin-right: 5px; }
|
44
|
+
input[type="text"] { margin: 0; }
|
45
|
+
}
|
46
|
+
&.show-radio {
|
47
|
+
fieldset.choice input[type="radio"] { display: inline-block; }
|
48
|
+
}
|
49
|
+
&.show-checkbox {
|
50
|
+
fieldset.choice input[type="checkbox"] { display: inline-block; }
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
}
|
56
|
+
|
57
|
+
} // End fieldset.question
|
58
|
+
}
|
data/app/helpers/ask_helper.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
module AskHelper
|
2
2
|
|
3
|
+
def link_to_add_fields(name, f, association)
|
4
|
+
new_object = f.object.send(association).klass.new
|
5
|
+
id = new_object.object_id
|
6
|
+
fields = f.fields_for(association, new_object, child_index: id) do |builder|
|
7
|
+
render("asker/"+association.to_s.singularize + "_fields", f: builder)
|
8
|
+
end
|
9
|
+
link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
|
10
|
+
end
|
11
|
+
|
3
12
|
def question_label(question, builder=nil)
|
4
13
|
if question.type.to_sym == :ChecklistQuestion
|
5
14
|
h(question.name)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
.question-type.TextQuestion
|
2
|
+
%input.askwidget-disabledpreview{:disabled => "true", :name => "undefined", :type => "text", :value => "Their answer"}
|
3
|
+
|
4
|
+
.question-type.EssayQuestion.start-hidden
|
5
|
+
%textarea.askwidget-disabledpreview{:disabled => "true", :name => "undefined", :type => "text", :value => "Their answer"}
|
6
|
+
|
7
|
+
.question-type.ChooseOneQuestion.ChecklistQuestion.start-hidden
|
8
|
+
= f.fields_for(:choices) do |choice|
|
9
|
+
= render 'asker/choice_fields', f: choice
|
10
|
+
|
11
|
+
= link_to_add_fields "Add Choice", f, :choices
|
12
|
+
|
13
|
+
.question-type.FormSection.start-hidden
|
14
|
+
%h4 Name of section
|
15
|
+
%p
|
16
|
+
This will provide a divider between form sections
|
17
|
+
|
@@ -1,27 +1,5 @@
|
|
1
|
-
|
2
|
-
=f.fields_for(:questions) do |
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
=question.hidden_field(:position)
|
7
|
-
%dt.name=question.label(:name)
|
8
|
-
%dd.name=question.text_field(:name, :placeholder=>'Title')
|
9
|
-
%dt.instructions=question.label(:instructions)
|
10
|
-
%dd.instructions=question.text_area(:instructions, :placeholder=>'Instructions')
|
11
|
-
%dt.type=question.label(:type)
|
12
|
-
%dd.type=question.collection_select(:type, Question::TYPES, :to_s, :titleize)
|
13
|
-
%dt.required=question.label(:required)
|
14
|
-
%dd.required=question.select(:required, [['Optional', false], ['Required', true]])
|
15
|
-
-unless question.object.new_record?
|
16
|
-
%dt.delete=question.label(:_destroy, 'Delete')
|
17
|
-
%dd.delete=question.check_box(:_destroy)
|
18
|
-
%dt.choices
|
19
|
-
%dd.choices
|
20
|
-
%ul.choices
|
21
|
-
=question.fields_for(:choices) do |choice|
|
22
|
-
%li.choice
|
23
|
-
=choice.label(:name)
|
24
|
-
=choice.text_field(:name, :placeholder=>'Choice')
|
25
|
-
-unless choice.object.new_record?
|
26
|
-
=choice.label(:_destroy, 'Remove')
|
27
|
-
=choice.check_box(:_destroy)
|
1
|
+
.ask.questions
|
2
|
+
=f.fields_for(:questions) do |f|
|
3
|
+
=render 'asker/question_fields', f: f
|
4
|
+
|
5
|
+
= link_to_add_fields "Add Question", f, :questions
|
@@ -0,0 +1,33 @@
|
|
1
|
+
%fieldset.question.preview
|
2
|
+
.question-action-links
|
3
|
+
=link_to 'Edit', '#', class: 'edit-question-link'
|
4
|
+
|
|
5
|
+
= f.hidden_field :_destroy
|
6
|
+
= link_to "Remove", '#', class: "remove_fields"
|
7
|
+
.hidden.position-wrapper
|
8
|
+
=f.hidden_field(:position)
|
9
|
+
.edit-question-fields
|
10
|
+
%table.question-details
|
11
|
+
%tbody
|
12
|
+
%tr
|
13
|
+
%th
|
14
|
+
%span.askwidget-fieldlabel=f.label(:name)
|
15
|
+
%td=f.text_field :name, class: 'askwidget-inputfield'
|
16
|
+
%tr
|
17
|
+
%th
|
18
|
+
%span.askwidget-fieldlabel= f.label(:instructions, 'Help Text')
|
19
|
+
%td=f.text_field :instructions, class: 'askwidget-inputfield'
|
20
|
+
%tr.select-question-type
|
21
|
+
%th
|
22
|
+
%span.askwidget-fieldlabel=f.label(:type)
|
23
|
+
%td=f.collection_select :type, Question::TYPES, :to_s, :titleize, class: 'askwidget-inputfield'
|
24
|
+
|
25
|
+
|
26
|
+
.edit-question-choices
|
27
|
+
=render 'asker/choices', f: f
|
28
|
+
|
29
|
+
.askwidget-buttons
|
30
|
+
=link_to "Done", "#", class: 'edit-question-link btn'
|
31
|
+
.required-option
|
32
|
+
=f.check_box :required, class: 'askwidget-inputfield'
|
33
|
+
%span.askwidget-fieldlabel=f.label(:required, "Make this a required question")
|
data/lib/ask/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ask
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -117,7 +117,7 @@ files:
|
|
117
117
|
- app/assets/images/add.png
|
118
118
|
- app/assets/images/delete.png
|
119
119
|
- app/assets/javascripts/ask.js.coffee
|
120
|
-
- app/assets/stylesheets/ask.css.
|
120
|
+
- app/assets/stylesheets/ask.css.scss
|
121
121
|
- app/helpers/ask_helper.rb
|
122
122
|
- app/models/answer.rb
|
123
123
|
- app/models/checklist_question.rb
|
@@ -129,8 +129,11 @@ files:
|
|
129
129
|
- app/models/text_question.rb
|
130
130
|
- app/views/answerer/_answers.html.haml
|
131
131
|
- app/views/answerer/_form.html.haml
|
132
|
+
- app/views/asker/_choice_fields.html.haml
|
133
|
+
- app/views/asker/_choices.html.haml
|
132
134
|
- app/views/asker/_form.html.haml
|
133
135
|
- app/views/asker/_form_preview.html.haml
|
136
|
+
- app/views/asker/_question_fields.html.haml
|
134
137
|
- db/migrate/20110913214050_create_answers.rb
|
135
138
|
- db/migrate/20110913214255_create_choices.rb
|
136
139
|
- db/migrate/20110913214410_create_questions.rb
|
@@ -139,7 +142,6 @@ files:
|
|
139
142
|
- lib/ask/engine.rb
|
140
143
|
- lib/ask/version.rb
|
141
144
|
- lib/ask.rb
|
142
|
-
- lib/assets/javascripts/jquery.handle-nesting.js.coffee
|
143
145
|
- MIT-LICENSE
|
144
146
|
- Rakefile
|
145
147
|
- README.markdown
|
@@ -1,139 +0,0 @@
|
|
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: ""
|
@@ -1,84 +0,0 @@
|
|
1
|
-
(($) ->
|
2
|
-
$.HandleNesting = (el, options) ->
|
3
|
-
base = this
|
4
|
-
base.$el = $(el)
|
5
|
-
base.el = el
|
6
|
-
base.items = []
|
7
|
-
base.blank = null
|
8
|
-
base.$el.data "HandleNesting", base
|
9
|
-
base.init = ->
|
10
|
-
base.options = $.extend({}, $.HandleNesting.defaultOptions, options)
|
11
|
-
base.items = base.$el.children("li")
|
12
|
-
base.blank = $(base.items[base.items.length - 1]).clone() if base.items.length
|
13
|
-
base.addButtons()
|
14
|
-
|
15
|
-
base.addButtons = ->
|
16
|
-
base.addAddButton()
|
17
|
-
base.items.each (i, item) ->
|
18
|
-
base.addRemoveButton item
|
19
|
-
|
20
|
-
base.addAddButton = ->
|
21
|
-
addButton = $("<button type=\"button\"/>").addClass("add").text("Add")
|
22
|
-
addButton.click ->
|
23
|
-
base.add()
|
24
|
-
|
25
|
-
base.$el.after addButton
|
26
|
-
|
27
|
-
base.addRemoveButton = (item) ->
|
28
|
-
destroys = $(item).find("input[name*=_destroy]")
|
29
|
-
destroys.each (i, destroy) ->
|
30
|
-
if $(item).find("button.remove").length == 0
|
31
|
-
removeButton = $("<button type=\"button\"/>").addClass("remove").text("Remove")
|
32
|
-
removeButton.click ->
|
33
|
-
base.remove this
|
34
|
-
|
35
|
-
$(item).append removeButton
|
36
|
-
$(destroy).hide()
|
37
|
-
$(item).find("label[for=" + $(destroy).attr("id") + "]").hide()
|
38
|
-
|
39
|
-
base.add = ->
|
40
|
-
newId = new Date().getTime()
|
41
|
-
match = base.options.nameMatch
|
42
|
-
replace = base.options.nameReplace.replace(/{NEW_ID}/g, newId)
|
43
|
-
base.options.beforeAdd() if base.options.beforeAdd?
|
44
|
-
added = base.blank.clone().hide()
|
45
|
-
added.find("*").each (i, el) ->
|
46
|
-
$(el).attr "id", null
|
47
|
-
|
48
|
-
added.find("input, select, textarea").each (i, el) ->
|
49
|
-
$(el).val ""
|
50
|
-
el.name = el.name.replace(match, replace)
|
51
|
-
|
52
|
-
base.addRemoveButton added
|
53
|
-
|
54
|
-
base.$el.append added
|
55
|
-
base.options.afterAdd added if base.options.afterAdd?
|
56
|
-
added.fadeIn "fast"
|
57
|
-
|
58
|
-
# Temporary hack to fix the bug where choices don't
|
59
|
-
# display if you go back to edit the form and the
|
60
|
-
# last question was a choose one question.
|
61
|
-
added.find("dd.choices").css "height", "auto"
|
62
|
-
added.find("dd.choices").hide()
|
63
|
-
# Remove any extra choices field and just leave the first one
|
64
|
-
firstchoice = added.find("ul.choices").children().first()
|
65
|
-
added.find("ul.choices").html firstchoice
|
66
|
-
|
67
|
-
base.remove = (item) ->
|
68
|
-
li = $(item).closest("li")
|
69
|
-
li.find("input[name*=_destroy]").val 1
|
70
|
-
li.find("input:checkbox[name*=_destroy]").attr "checked", "checked"
|
71
|
-
li.fadeOut "fast"
|
72
|
-
|
73
|
-
base.init()
|
74
|
-
|
75
|
-
$.HandleNesting.defaultOptions =
|
76
|
-
nameMatch: /\[[0-9]+\]/
|
77
|
-
nameReplace: "[{NEW_ID}]"
|
78
|
-
beforeAdd: null
|
79
|
-
afterAdd: null
|
80
|
-
|
81
|
-
$.fn.handleNesting = (options) ->
|
82
|
-
@each ->
|
83
|
-
new $.HandleNesting(this, options)
|
84
|
-
) jQuery
|