Class: Quby::Compiler::Entities::Question

Inherits:
Item
  • Object
show all
Defined in:
lib/quby/compiler/entities/question.rb

Constant Summary collapse

MARKDOWN_ATTRIBUTES =
%w(description title).freeze

Instance Attribute Summary collapse

Attributes inherited from Item

#presentation, #raw_content, #switch_cycle

Instance Method Summary collapse

Methods inherited from Item

#as_json

Constructor Details

#initialize(key, options = {}) ⇒ Question

rubocop:disable CyclomaticComplexity, Metrics/MethodLength



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/quby/compiler/entities/question.rb', line 140

def initialize(key, options = {})
  super(options)

  @extra_data ||= {}
  @options = []
  @allow_duplicate_option_values = options[:allow_duplicate_option_values]
  @questionnaire = options[:questionnaire]
  @key = key
  @sbg_key = options[:sbg_key]
  @type = options[:type]
  @as = options[:as]
  @title = options[:title]
  @context_free_title = options[:context_free_title]
  @allow_blank_titles = options[:allow_blank_titles]
  @description = options[:description]
  @context_description = options[:context_description]
  @display_modes = options[:display_modes]
  @presentation = options[:presentation]
  @validations = []
  @visibility_rules = []
  @parent = options[:parent]
  @hidden = options[:hidden]
  @table = options[:table]
  @parent_option_key = options[:parent_option_key]
  @autocomplete = options[:autocomplete] || "off"
  @show_values = options[:show_values] || :bulk
  @deselectable = (options[:deselectable].nil? || options[:deselectable])
  @disallow_bulk = options[:disallow_bulk]
  @score_header = options[:score_header] || :none
  @sets_textvar = "#{questionnaire.key}_#{options[:sets_textvar]}" if options[:sets_textvar]
  @unit = options[:unit]
  @lines = options[:lines] || 6
  @cols = options[:cols] || 40
  @default_invisible = options[:default_invisible] || false
  @labels = []
  @labels_i18n_key = nil
  @css_vars = options[:css_vars]
  @indent = options[:indent]

  @col_span = options[:col_span] || 1
  @row_span = options[:row_span] || 1

  set_depends_on(options[:depends_on])

  @question_group = options[:question_group]
  @group_minimum_answered = options[:group_minimum_answered]
  @group_maximum_answered = options[:group_maximum_answered]

  @input_data = {}
  @input_data[:value_tooltip] = true if options[:value_tooltip]

  # Require subquestions of required questions by default
  options[:required] = true if @parent&.validations&.first&.fetch(:type, nil) == :requires_answer
  @validations << {type: :requires_answer, explanation: options[:error_explanation] } if options[:required]

  if @type == :float
    @validations << {type: :valid_float, explanation: options[:error_explanation]}
  elsif @type == :integer
    @validations << {type: :valid_integer, explanation: options[:error_explanation]}
  end

  if options[:minimum] and (@type == :integer || @type == :float)
    fail "deprecated" # pretty sure this is not used anywhere
  end
  if options[:maximum] and (@type == :integer || @type == :float)
    fail "deprecated" # pretty sure this is not used anywhere
  end
  @default_position = options[:default_position]

  if @question_group
    if @group_minimum_answered
      @validations << {type: :answer_group_minimum, group: @question_group, value: @group_minimum_answered,
                       explanation: options[:error_explanation]}
    end
    if @group_maximum_answered
      @validations << {type: :answer_group_maximum, group: @question_group, value: @group_maximum_answered,
                       explanation: options[:error_explanation]}
    end
  end
end

Instance Attribute Details

#allow_blank_titlesObject

Question validation fails when there are no title and no context_free_title. When :allow_blank_titles => true passed, validation does not fail. Any other value will raise the failure.



58
59
60
# File 'lib/quby/compiler/entities/question.rb', line 58

def allow_blank_titles
  @allow_blank_titles
end

#allow_duplicate_option_valuesObject (readonly)

Whether to skip the uniqueness validation on radio and select option values



42
43
44
# File 'lib/quby/compiler/entities/question.rb', line 42

def allow_duplicate_option_values
  @allow_duplicate_option_values
end

#asObject

How should we display this question



29
30
31
# File 'lib/quby/compiler/entities/question.rb', line 29

def as
  @as
end

#autocompleteObject

Whether the browser should autocomplete this question (off by default)



62
63
64
# File 'lib/quby/compiler/entities/question.rb', line 62

def autocomplete
  @autocomplete
end

#col_spanObject

rubocop:enable AccessorMethodName



242
243
244
# File 'lib/quby/compiler/entities/question.rb', line 242

def col_span
  options.length > 0 && type != :select ? options.length : @col_span
end

#colsObject

Returns the value of attribute cols.



121
122
123
# File 'lib/quby/compiler/entities/question.rb', line 121

def cols
  @cols
end

#context_descriptionObject

Returns the value of attribute context_description.



21
22
23
# File 'lib/quby/compiler/entities/question.rb', line 21

def context_description
  @context_description
end

#context_free_titleObject

Returns the value of attribute context_free_title.



19
20
21
# File 'lib/quby/compiler/entities/question.rb', line 19

def context_free_title
  @context_free_title
end

#css_varsObject

extra styling options



32
33
34
# File 'lib/quby/compiler/entities/question.rb', line 32

def css_vars
  @css_vars
end

#default_invisibleObject

Returns the value of attribute default_invisible.



130
131
132
# File 'lib/quby/compiler/entities/question.rb', line 130

def default_invisible
  @default_invisible
end

#default_positionObject



288
289
290
291
292
# File 'lib/quby/compiler/entities/question.rb', line 288

def default_position
  return unless as == :slider
  half = (type == :float) ? 2.0 : 2
  @default_position || ((minimum + maximum) / half if minimum && maximum)
end

#dependenciesObject

Returns the value of attribute dependencies.



77
78
79
# File 'lib/quby/compiler/entities/question.rb', line 77

def dependencies
  @dependencies
end

#depends_onObject

This question should not validate itself unless the depends_on question is answered. May also be an array of “#question_key_#option_key” strings that specify options this question depends on.



99
100
101
# File 'lib/quby/compiler/entities/question.rb', line 99

def depends_on
  @depends_on
end

#descriptionObject

Returns the value of attribute description.



20
21
22
# File 'lib/quby/compiler/entities/question.rb', line 20

def description
  @description
end

#deselectableObject

Whether this radio question is deselectable



85
86
87
# File 'lib/quby/compiler/entities/question.rb', line 85

def deselectable
  @deselectable
end

#disallow_bulkObject

Whether we can collapse this in bulk view



93
94
95
# File 'lib/quby/compiler/entities/question.rb', line 93

def disallow_bulk
  @disallow_bulk
end

#display_modesObject

In what modes do we display this question NOTE We always display questions in print-view (if they have an answer)



47
48
49
# File 'lib/quby/compiler/entities/question.rb', line 47

def display_modes
  @display_modes
end

#extra_dataObject

Extra data hash to store on the question item’s html element



102
103
104
# File 'lib/quby/compiler/entities/question.rb', line 102

def extra_data
  @extra_data
end

#group_maximum_answeredObject

Returns the value of attribute group_maximum_answered.



113
114
115
# File 'lib/quby/compiler/entities/question.rb', line 113

def group_maximum_answered
  @group_maximum_answered
end

#group_minimum_answeredObject

Returns the value of attribute group_minimum_answered.



112
113
114
# File 'lib/quby/compiler/entities/question.rb', line 112

def group_minimum_answered
  @group_minimum_answered
end

#hiddenObject

To hide old questions



38
39
40
# File 'lib/quby/compiler/entities/question.rb', line 38

def hidden
  @hidden
end

#indentObject

indent the question, to make it belong to the previous one.



34
35
36
# File 'lib/quby/compiler/entities/question.rb', line 34

def indent
  @indent
end

#input_dataObject

data-attributes for the input tag.



105
106
107
# File 'lib/quby/compiler/entities/question.rb', line 105

def input_data
  @input_data
end

#keyObject

Standard attributes



14
15
16
# File 'lib/quby/compiler/entities/question.rb', line 14

def key
  @key
end

#labelsObject

Returns the value of attribute labels.



23
24
25
# File 'lib/quby/compiler/entities/question.rb', line 23

def labels
  @labels
end

#labels_i18n_keyObject

Returns the value of attribute labels_i18n_key.



23
24
25
# File 'lib/quby/compiler/entities/question.rb', line 23

def labels_i18n_key
  @labels_i18n_key
end

#linesObject

Amount of rows and cols a textarea has



120
121
122
# File 'lib/quby/compiler/entities/question.rb', line 120

def lines
  @lines
end

#opt_groupsObject

Returns the value of attribute opt_groups.



51
52
53
# File 'lib/quby/compiler/entities/question.rb', line 51

def opt_groups
  @opt_groups
end

#optionsObject

Multiple-choice questions have options to choose from



50
51
52
# File 'lib/quby/compiler/entities/question.rb', line 50

def options
  @options
end

#parentObject

Some questions are a tree.



89
90
91
# File 'lib/quby/compiler/entities/question.rb', line 89

def parent
  @parent
end

#parent_option_keyObject

Returns the value of attribute parent_option_key.



90
91
92
# File 'lib/quby/compiler/entities/question.rb', line 90

def parent_option_key
  @parent_option_key
end

#question_groupObject

options for grouping questions and setting a minimum or maximum number of answered questions in the group



111
112
113
# File 'lib/quby/compiler/entities/question.rb', line 111

def question_group
  @question_group
end

#questionnaireObject

Returns the value of attribute questionnaire.



17
18
19
# File 'lib/quby/compiler/entities/question.rb', line 17

def questionnaire
  @questionnaire
end

#row_spanObject

Returns the value of attribute row_span.



128
129
130
# File 'lib/quby/compiler/entities/question.rb', line 128

def row_span
  @row_span
end

#sbg_keyObject

Returns the value of attribute sbg_key.



16
17
18
# File 'lib/quby/compiler/entities/question.rb', line 16

def sbg_key
  @sbg_key
end

#score_headerObject

Whether we use the :description, the :value or :none for the score header above this question



108
109
110
# File 'lib/quby/compiler/entities/question.rb', line 108

def score_header
  @score_header
end

#sets_textvarObject

Text variable name that will be replaced with the answer to this question In all following text elements that support markdown



117
118
119
# File 'lib/quby/compiler/entities/question.rb', line 117

def sets_textvar
  @sets_textvar
end

#show_valuesObject

Whether we show the value for each option :all => in all questionnaire display modes :none => in none of display modes :paged => for only in :paged display mode :bulk => for only in :bulk display mode



69
70
71
# File 'lib/quby/compiler/entities/question.rb', line 69

def show_values
  @show_values
end

#sizeObject

To specify size of string/number input boxes



82
83
84
# File 'lib/quby/compiler/entities/question.rb', line 82

def size
  @size
end

#tableObject

Table this question might belong to



124
125
126
# File 'lib/quby/compiler/entities/question.rb', line 124

def table
  @table
end

#titleObject

Returns the value of attribute title.



18
19
20
# File 'lib/quby/compiler/entities/question.rb', line 18

def title
  @title
end

#title_questionObject

string question that is displayed after the title of this question.



54
55
56
# File 'lib/quby/compiler/entities/question.rb', line 54

def title_question
  @title_question
end

#typeObject

What kind of question is this?



26
27
28
# File 'lib/quby/compiler/entities/question.rb', line 26

def type
  @type
end

#unitObject

To display unit for number items



80
81
82
# File 'lib/quby/compiler/entities/question.rb', line 80

def unit
  @unit
end

#validationsObject

Structuring



75
76
77
# File 'lib/quby/compiler/entities/question.rb', line 75

def validations
  @validations
end

#visibility_rulesObject (readonly)

Quby2 only



76
77
78
# File 'lib/quby/compiler/entities/question.rb', line 76

def visibility_rules
  @visibility_rules
end

Instance Method Details

#after_buildObject

called after DSL has instance_evalled everything within the question block.



223
224
# File 'lib/quby/compiler/entities/question.rb', line 223

def after_build
end

#all_optionsObject



260
261
262
263
264
265
266
267
268
269
# File 'lib/quby/compiler/entities/question.rb', line 260

def all_options
  options.flat_map { |option|
    case option
    when Quby::Compiler::Entities::QuestionOptgroup
      option.options
    else
      option
    end
  }
end

#answer_keysObject

Returns all possible answer keys of this question (excluding subquestions, including options). radio/select/scale-options do not create answer_keys, but answer values.



284
285
286
# File 'lib/quby/compiler/entities/question.rb', line 284

def answer_keys
  [key]
end

#claimed_keysObject

The keys this question claims as his own. Not including options and subquestions. Includes keys for the question, inputs and answers.



278
279
280
# File 'lib/quby/compiler/entities/question.rb', line 278

def claimed_keys
  [key]
end

#context_free_title_or_titleObject



230
231
232
# File 'lib/quby/compiler/entities/question.rb', line 230

def context_free_title_or_title
  context_free_title || title
end

#hidden?Boolean

Returns:

  • (Boolean)


312
313
314
# File 'lib/quby/compiler/entities/question.rb', line 312

def hidden?
  hidden
end

#html_idObject



304
305
306
# File 'lib/quby/compiler/entities/question.rb', line 304

def html_id
  "answer_#{key}_input"
end

#input_keysObject

Returns all keys belonging to html inputs generated by this question.



251
252
253
254
255
256
257
258
# File 'lib/quby/compiler/entities/question.rb', line 251

def input_keys
  if options.blank?
    answer_keys
  else
    # Some options don't have a key (inner_title), they are stripped
    all_options.reject(&:inner_title?).map{ |opt| opt.input_key }
  end
end

#key_in_use?(k) ⇒ Boolean

Returns:

  • (Boolean)


271
272
273
274
# File 'lib/quby/compiler/entities/question.rb', line 271

def key_in_use?(k)
  claimed_keys.include?(k) ||
  options.any? { |option| option.key_in_use?(k) }
end

#maximumObject

Maximum value for float and integer types, set by validation



300
301
302
# File 'lib/quby/compiler/entities/question.rb', line 300

def maximum
  validations.find { |i| i[:type] == :maximum }.try(:fetch, :value)
end

#minimumObject

Minimum value for float and integer types, set by validation



295
296
297
# File 'lib/quby/compiler/entities/question.rb', line 295

def minimum
  validations.find { |i| i[:type] == :minimum }.try(:fetch, :value)
end

#path_strObject



226
227
228
# File 'lib/quby/compiler/entities/question.rb', line 226

def path_str
  "#{questionnaire.key}:Question:#{key}"
end

#set_depends_on(keys) ⇒ Object

rubocop:disable AccessorMethodName



235
236
237
238
239
# File 'lib/quby/compiler/entities/question.rb', line 235

def set_depends_on(keys)
  return if keys.blank?
  keys = [keys] unless keys.is_a?(Array)
  @depends_on = keys
end

#show_values_in_mode?(mode) ⇒ Boolean

Returns:

  • (Boolean)


316
317
318
319
320
321
322
# File 'lib/quby/compiler/entities/question.rb', line 316

def show_values_in_mode?(mode)
  case show_values
  when :none then false
  when :all then true
  else show_values == mode
  end
end

#subquestion?Boolean

Returns:

  • (Boolean)


328
329
330
# File 'lib/quby/compiler/entities/question.rb', line 328

def subquestion?
  !parent_option_key.nil?
end

#subquestionsObject



324
325
326
# File 'lib/quby/compiler/entities/question.rb', line 324

def subquestions
  options.map { |opt| opt.questions }.flatten
end

#title_question?Boolean

Returns:

  • (Boolean)


246
247
248
# File 'lib/quby/compiler/entities/question.rb', line 246

def title_question?
  presentation == :next_to_title
end

#view_selectorObject



308
309
310
# File 'lib/quby/compiler/entities/question.rb', line 308

def view_selector
  table.blank? ? "#item_#{key}" : "[data-for=#{key}], #answer_#{key}_input"
end