Class: Fe::Element
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
-
#all_elements ⇒ Object
-
#conditional_answers ⇒ Object
-
#conditional_match(answer_sheet) ⇒ Object
-
#content(locale = nil) ⇒ Object
-
#css_classes ⇒ Object
-
#duplicate(page, parent = nil) ⇒ Object
copy an item and all it’s children.
-
#export_hash ⇒ Object
-
#export_to_yaml ⇒ Object
-
#has_response?(answer_sheet = nil) ⇒ Boolean
-
#hidden?(answer_sheet = nil, page = nil) ⇒ Boolean
use page if it’s passed in, otherwise it will revert to the first page in answer_sheet.
-
#hidden_by_choice_field?(answer_sheet) ⇒ Boolean
-
#hidden_by_conditional?(answer_sheet, page) ⇒ Boolean
-
#label(locale = nil) ⇒ Object
HUMANIZED_ATTRIBUTES = { slug: “Variable” }changed.include?(‘address1’).
-
#limit(answer_sheet = nil) ⇒ Object
-
#matches_filter(filter) ⇒ Object
matches in an AND method; if requested we can add a second filter method later to match on an OR basis.
-
#page_id(page = nil) ⇒ Object
-
#pages_on ⇒ Object
returns all pages this element is on, whether that be directly, through a grid, or as a choice field conditional option.
-
#position(page = nil) ⇒ Object
-
#previous_element(question_sheet, page = nil) ⇒ Object
assume each element is on a question sheet only once to make things simpler.
-
#ptemplate ⇒ Object
by default the partial for an element matches the class name (override as necessary).
-
#question? ⇒ Boolean
-
#required?(answer_sheet = nil, page = nil) ⇒ Boolean
use page if it’s passed in, otherwise it will revert to the first page in answer_sheet.
-
#reuseable? ⇒ Boolean
-
#set_conditional_element ⇒ Object
-
#set_position(position, page = nil) ⇒ Object
-
#tooltip(locale = nil) ⇒ Object
-
#update_any_previous_conditional_elements ⇒ Object
-
#update_page_all_element_ids ⇒ Object
-
#visibility_affecting_element_ids ⇒ Object
return an array of all elements whose answers or visibility might affect the visibility of this element.
-
#visibility_affecting_questions ⇒ Object
-
#visible?(answer_sheet = nil, page = nil) ⇒ Boolean
use page if it’s passed in, otherwise it will revert to the first page in answer_sheet.
Instance Attribute Details
#old_id ⇒ Object
Returns the value of attribute old_id.
6
7
8
|
# File 'app/models/fe/element.rb', line 6
def old_id
@old_id
end
|
Class Method Details
.create_from_import(element_data, page, question_sheet) ⇒ Object
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
|
# File 'app/models/fe/element.rb', line 318
def self.create_from_import(element_data, page, question_sheet)
element_data[:old_id] = element_data.delete('id')
children = element_data.delete(:children)
element = element_data['kind'].constantize.create!(element_data)
question_sheet.element_id_mappings[element.old_id] = element.id
children.each do |child|
byebug unless child.class == Hash
child_element = create_from_import(child, page, question_sheet)
if child['choice_field_id'].present?
child_element.choice_field_id = element.id
end
byebug if child_element.label == 'Your Name:'
if child['question_grid_id'].present?
child_element.question_grid_id = element.id
end
child_element.save!
end
element
end
|
.max_label_length ⇒ Object
267
268
269
|
# File 'app/models/fe/element.rb', line 267
def self.max_label_length
@@max_label_length ||= Fe::Element.columns.find{ |c| c.name == "label" }.limit
end
|
Instance Method Details
#all_elements ⇒ Object
240
241
242
243
244
245
246
247
248
249
250
|
# File 'app/models/fe/element.rb', line 240
def all_elements
if respond_to?(:elements)
elements.reload
elements.collect{ |el|
[el, el.all_elements]
}.flatten
else
[]
end
end
|
#conditional_answers ⇒ Object
257
258
259
|
# File 'app/models/fe/element.rb', line 257
def conditional_answers
conditional_answer.split(';').collect(&:strip)
end
|
#conditional_match(answer_sheet) ⇒ Object
261
262
263
264
265
|
# File 'app/models/fe/element.rb', line 261
def conditional_match(answer_sheet)
displayed_response = display_response(answer_sheet)
return false unless displayed_response && conditional_answer
conditional_answers.include?(displayed_response)
end
|
#content(locale = nil) ⇒ Object
64
65
66
|
# File 'app/models/fe/element.rb', line 64
def content(locale = nil)
content_translations[locale].present? ? content_translations[locale] : self[:content]
end
|
#css_classes ⇒ Object
314
315
316
|
# File 'app/models/fe/element.rb', line 314
def css_classes
css_class.to_s.split(' ').collect(&:strip)
end
|
#duplicate(page, parent = nil) ⇒ Object
copy an item and all it’s children
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
# File 'app/models/fe/element.rb', line 219
def duplicate(page, parent = nil)
new_element = self.class.new(self.attributes.except('id', 'created_at', 'updated_at'))
case parent.class.to_s
when "Fe::QuestionGrid", "Fe::QuestionGridWithTotal"
new_element.question_grid_id = parent.id
when "Fe::ChoiceField"
new_element.choice_field_id = parent.id
end
new_element.position = parent.elements.maximum(:position).to_i + 1 if parent
new_element.save!(validate: false)
Fe::PageElement.create(element: new_element, page: page) unless parent
if respond_to?(:elements) && elements.present?
elements.each {|e| e.duplicate(page, new_element)}
end
new_element
end
|
#export_hash ⇒ Object
338
339
340
341
|
# File 'app/models/fe/element.rb', line 338
def export_hash
children = choice_field_children.collect(&:export_hash)
self.attributes.to_hash.merge(children: children)
end
|
#export_to_yaml ⇒ Object
343
344
345
|
# File 'app/models/fe/element.rb', line 343
def export_to_yaml
export_hash.to_yaml
end
|
#has_response?(answer_sheet = nil) ⇒ Boolean
78
79
80
|
# File 'app/models/fe/element.rb', line 78
def has_response?(answer_sheet = nil)
false
end
|
#hidden?(answer_sheet = nil, page = nil) ⇒ Boolean
use page if it’s passed in, otherwise it will revert to the first page in answer_sheet
167
168
169
170
171
|
# File 'app/models/fe/element.rb', line 167
def hidden?(answer_sheet = nil, page = nil)
page ||= pages_on.detect{ |p| answer_sheet.question_sheets.include?(p.question_sheet) }
return true if !page || page.hidden?(answer_sheet)
return page.all_hidden_elements(answer_sheet).include?(self)
end
|
#hidden_by_choice_field?(answer_sheet) ⇒ Boolean
155
156
157
158
159
|
# File 'app/models/fe/element.rb', line 155
def hidden_by_choice_field?(answer_sheet)
choice_field.present? &&
choice_field.is_a?(Fe::ChoiceField) &&
choice_field.is_response_false(answer_sheet)
end
|
#hidden_by_conditional?(answer_sheet, page) ⇒ Boolean
147
148
149
150
151
152
153
|
# File 'app/models/fe/element.rb', line 147
def hidden_by_conditional?(answer_sheet, page)
return false unless answer_sheet.question_sheets.include?(page.question_sheet)
prev_el = previous_element(page.question_sheet, page)
prev_el.is_a?(Fe::Question) &&
prev_el.conditional == self &&
!prev_el.conditional_match(answer_sheet)
end
|
#label(locale = nil) ⇒ Object
HUMANIZED_ATTRIBUTES =
slug: "Variable"
changed.include?(‘address1’)
def self.human_attrib_name(attr)
HUMANIZED_ATTRIBUTES[attr.to_sym] || super
end
60
61
62
|
# File 'app/models/fe/element.rb', line 60
def label(locale = nil)
label_translations[locale].present? ? label_translations[locale] : self[:label]
end
|
#limit(answer_sheet = nil) ⇒ Object
82
83
84
85
86
87
88
89
90
91
92
93
94
|
# File 'app/models/fe/element.rb', line 82
def limit(answer_sheet = nil)
if answer_sheet && object_name.present? && attribute_name.present?
begin
unless eval("answer_sheet." + self.object_name + ".nil?")
klass = eval("answer_sheet." + self.object_name + ".class")
column = klass.columns_hash[self.attribute_name]
return column.limit
end
rescue
nil
end
end
end
|
#matches_filter(filter) ⇒ Object
matches in an AND method; if requested we can add a second filter method later to match on an OR basis
310
311
312
|
# File 'app/models/fe/element.rb', line 310
def matches_filter(filter)
filter.all? { |method| self.send(method) }
end
|
#page_id(page = nil) ⇒ Object
200
201
202
203
204
205
206
|
# File 'app/models/fe/element.rb', line 200
def page_id(page = nil)
if page
page.id
else
pages.first.try(:id)
end
end
|
#pages_on ⇒ Object
returns all pages this element is on, whether that be directly, through a grid, or as a choice field conditional option
73
74
75
76
|
# File 'app/models/fe/element.rb', line 73
def pages_on
all_pages = pages.reload + [question_grid, question_grid_with_total, choice_field].compact.collect(&:pages_on)
all_pages.flatten.uniq
end
|
#position(page = nil) ⇒ Object
182
183
184
185
186
187
188
|
# File 'app/models/fe/element.rb', line 182
def position(page = nil)
if page
page_elements.where(page_id: page.id).first.try(:position)
else
self[:position]
end
end
|
#previous_element(question_sheet, page = nil) ⇒ Object
assume each element is on a question sheet only once to make things simpler. if not, just take the first one NOTE: getting the previous_element isn’t an expensive operation any more because of the all_elements_id cache
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
# File 'app/models/fe/element.rb', line 98
def previous_element(question_sheet, page = nil)
return false unless question_sheet
page ||= pages_on.detect{ |p| p.question_sheet == question_sheet }
index = page.all_element_ids_arr.index(self.id)
unless index
page.rebuild_all_element_ids
index = page.all_element_ids_arr.index(self.id)
end
if index && index > 0 && prev_el_id = page.all_element_ids_arr[index-1]
el = Fe::Element.find_by(id: prev_el_id)
unless el
page.rebuild_all_element_ids
index = page.all_element_ids_arr.index(self.id)
prev_el_id = page.all_element_ids_arr[index-1]
el = Fe::Element.find(prev_el_id) end
return el
end
end
|
#ptemplate ⇒ Object
by default the partial for an element matches the class name (override as necessary)
214
215
216
|
# File 'app/models/fe/element.rb', line 214
def ptemplate
self.class.to_s.underscore
end
|
#question? ⇒ Boolean
208
209
210
|
# File 'app/models/fe/element.rb', line 208
def question?
self.kind_of?(Question)
end
|
#required?(answer_sheet = nil, page = nil) ⇒ Boolean
use page if it’s passed in, otherwise it will revert to the first page in answer_sheet
174
175
176
177
178
179
180
|
# File 'app/models/fe/element.rb', line 174
def required?(answer_sheet = nil, page = nil)
if answer_sheet && hidden?(answer_sheet, page)
return false
else
required == true
end
end
|
#set_conditional_element ⇒ Object
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
# File 'app/models/fe/element.rb', line 271
def set_conditional_element
case conditional_type
when "Fe::Element"
pages_on.each do |page|
if index = page.all_element_ids_arr.index(self.id)
self.conditional_id = page.all_element_ids_arr[index+1]
else
self.conditional_id = nil
end
end
when ""
self.conditional_type = nil
end
end
|
#set_position(position, page = nil) ⇒ Object
190
191
192
193
194
195
196
197
198
|
# File 'app/models/fe/element.rb', line 190
def set_position(position, page = nil)
if page
pe = page_elements.where(page_id: page.id).first
pe.update_attribute(:position, position) if pe
else
self[:position] = position
end
position
end
|
68
69
70
|
# File 'app/models/fe/element.rb', line 68
def tooltip(locale = nil)
tip_translations[locale].present? ? tip_translations[locale] : self[:tooltip]
end
|
#update_any_previous_conditional_elements ⇒ Object
288
289
290
291
292
293
294
295
296
297
298
|
# File 'app/models/fe/element.rb', line 288
def update_any_previous_conditional_elements
pages_on.each do |page|
index = page.all_element_ids_arr.index(self.id)
if index && index > 0
prev_el = Fe::Element.find(page.all_element_ids_arr[index-1])
if prev_el.conditional_type == "Fe::Element"
prev_el.update_column(:conditional_id, id)
end
end
end
end
|
#update_page_all_element_ids ⇒ Object
300
301
302
303
304
305
306
|
# File 'app/models/fe/element.rb', line 300
def update_page_all_element_ids
[question_grid, question_grid_with_total, choice_field].compact.each do |field|
field.update_page_all_element_ids
end
pages.reload.each do |p| p.rebuild_all_element_ids end
end
|
#visibility_affecting_element_ids ⇒ Object
return an array of all elements whose answers or visibility might affect the visibility of this element
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
# File 'app/models/fe/element.rb', line 126
def visibility_affecting_element_ids
return @visibility_affecting_element_ids if @visibility_affecting_element_ids
Rails.cache.fetch([self, 'element#visibility_affecting_element_ids', Fe::Element.order('updated_at desc, id desc').first]) do
elements = []
elements << question_grid if question_grid
elements << choice_field if choice_field
elements += Fe::Element.where(conditional_type: 'Fe::Element', conditional_id: id)
element_ids = elements.collect(&:id) +
elements.collect { |e| e.visibility_affecting_element_ids }.flatten
element_ids.uniq
end
end
|
#visibility_affecting_questions ⇒ Object
143
144
145
|
# File 'app/models/fe/element.rb', line 143
def visibility_affecting_questions
Fe::Question.where(id: visibility_affecting_element_ids)
end
|
#visible?(answer_sheet = nil, page = nil) ⇒ Boolean
use page if it’s passed in, otherwise it will revert to the first page in answer_sheet
162
163
164
|
# File 'app/models/fe/element.rb', line 162
def visible?(answer_sheet = nil, page = nil)
!hidden?(answer_sheet, page)
end
|