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
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
|
# File 'app/models/fe/element.rb', line 325
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
274
275
276
|
# File 'app/models/fe/element.rb', line 274
def self.max_label_length
@@max_label_length ||= Fe::Element.columns.find{ |c| c.name == "label" }.limit
end
|
Instance Method Details
#all_elements ⇒ Object
247
248
249
250
251
252
253
254
255
256
257
|
# File 'app/models/fe/element.rb', line 247
def all_elements
if respond_to?(:elements)
elements.reload
elements.collect{ |el|
[el, el.all_elements]
}.flatten
else
[]
end
end
|
#conditional_answers ⇒ Object
264
265
266
|
# File 'app/models/fe/element.rb', line 264
def conditional_answers
conditional_answer.split(';').collect(&:strip)
end
|
#conditional_match(answer_sheet) ⇒ Object
268
269
270
271
272
|
# File 'app/models/fe/element.rb', line 268
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
71
72
73
|
# File 'app/models/fe/element.rb', line 71
def content(locale = nil)
content_translations[locale].present? ? content_translations[locale] : self[:content]
end
|
#css_classes ⇒ Object
321
322
323
|
# File 'app/models/fe/element.rb', line 321
def css_classes
css_class.to_s.split(' ').collect(&:strip)
end
|
#duplicate(page, parent = nil) ⇒ Object
copy an item and all it’s children
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
# File 'app/models/fe/element.rb', line 226
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
345
346
347
348
|
# File 'app/models/fe/element.rb', line 345
def export_hash
children = choice_field_children.collect(&:export_hash)
self.attributes.to_hash.merge(children: children)
end
|
#export_to_yaml ⇒ Object
350
351
352
|
# File 'app/models/fe/element.rb', line 350
def export_to_yaml
export_hash.to_yaml
end
|
#has_response?(answer_sheet = nil) ⇒ Boolean
85
86
87
|
# File 'app/models/fe/element.rb', line 85
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
174
175
176
177
178
|
# File 'app/models/fe/element.rb', line 174
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
162
163
164
165
166
|
# File 'app/models/fe/element.rb', line 162
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
154
155
156
157
158
159
160
|
# File 'app/models/fe/element.rb', line 154
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
67
68
69
|
# File 'app/models/fe/element.rb', line 67
def label(locale = nil)
label_translations[locale].present? ? label_translations[locale] : self[:label]
end
|
#limit(answer_sheet = nil) ⇒ Object
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# File 'app/models/fe/element.rb', line 89
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
317
318
319
|
# File 'app/models/fe/element.rb', line 317
def matches_filter(filter)
filter.all? { |method| self.send(method) }
end
|
#page_id(page = nil) ⇒ Object
207
208
209
210
211
212
213
|
# File 'app/models/fe/element.rb', line 207
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
80
81
82
83
|
# File 'app/models/fe/element.rb', line 80
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
189
190
191
192
193
194
195
|
# File 'app/models/fe/element.rb', line 189
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
# File 'app/models/fe/element.rb', line 105
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)
221
222
223
|
# File 'app/models/fe/element.rb', line 221
def ptemplate
self.class.to_s.underscore
end
|
#question? ⇒ Boolean
215
216
217
|
# File 'app/models/fe/element.rb', line 215
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
181
182
183
184
185
186
187
|
# File 'app/models/fe/element.rb', line 181
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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
|
# File 'app/models/fe/element.rb', line 278
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
197
198
199
200
201
202
203
204
205
|
# File 'app/models/fe/element.rb', line 197
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
|
75
76
77
|
# File 'app/models/fe/element.rb', line 75
def tooltip(locale = nil)
tip_translations[locale].present? ? tip_translations[locale] : self[:tooltip]
end
|
#update_any_previous_conditional_elements ⇒ Object
295
296
297
298
299
300
301
302
303
304
305
|
# File 'app/models/fe/element.rb', line 295
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
307
308
309
310
311
312
313
|
# File 'app/models/fe/element.rb', line 307
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
# File 'app/models/fe/element.rb', line 133
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
150
151
152
|
# File 'app/models/fe/element.rb', line 150
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
169
170
171
|
# File 'app/models/fe/element.rb', line 169
def visible?(answer_sheet = nil, page = nil)
!hidden?(answer_sheet, page)
end
|