ask 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|