Module: GovukElementsErrorsHelper

Extended by:
ActionView::Context, ActionView::Helpers::TagHelper
Defined in:
app/helpers/govuk_elements_errors_helper.rb

Class Method Summary collapse

Class Method Details

.array_to_parent(list, object, child_to_parents = {}, parent_object) ⇒ Object



41
42
43
44
45
46
# File 'app/helpers/govuk_elements_errors_helper.rb', line 41

def self.array_to_parent list, object, child_to_parents={}, parent_object
  list.each do |child|
    child_to_parents[child] = object
    child_to_parent child, child_to_parents, parent_object
  end
end

.attribute_objects(object) ⇒ Object



34
35
36
37
38
39
# File 'app/helpers/govuk_elements_errors_helper.rb', line 34

def self.attribute_objects object
  object.
    instance_variables.
    map { |var| instance_variable(object, var) }.
    compact
end

.attributes(object, parent_object = nil) ⇒ Object



25
26
27
28
29
30
31
32
# File 'app/helpers/govuk_elements_errors_helper.rb', line 25

def self.attributes object, parent_object=nil
  return [] if object == parent_object
  parent_object ||= object

  child_objects = attribute_objects object
  nested_child_objects = child_objects.map { |o| attributes(o, parent_object) }
  (child_objects + nested_child_objects).flatten - [object]
end

.child_errors_present?(object) ⇒ Boolean

Returns:

  • (Boolean)


21
22
23
# File 'app/helpers/govuk_elements_errors_helper.rb', line 21

def self.child_errors_present? object
  attributes(object).any? { |child| errors_exist?(child) }
end

.child_to_parent(object, child_to_parents = {}, parent_object = nil) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'app/helpers/govuk_elements_errors_helper.rb', line 48

def self.child_to_parent object, child_to_parents={}, parent_object=nil
  return child_to_parents if object == parent_object
  parent_object ||= object

  attribute_objects(object).each do |child|
    if child.is_a?(Array)
      array_to_parent(child, object, child_to_parents, parent_object)
    else
      child_to_parents[child] = object
      child_to_parent child, child_to_parents, parent_object
    end
  end

  child_to_parents
end

.children_with_errors(object) ⇒ Object



84
85
86
# File 'app/helpers/govuk_elements_errors_helper.rb', line 84

def self.children_with_errors object
  attributes(object).select { |child| errors_present?(child) }
end

.default_label(attribute) ⇒ Object



144
145
146
# File 'app/helpers/govuk_elements_errors_helper.rb', line 144

def self.default_label attribute
  attribute.to_s.humanize.capitalize
end

.error_summary(object, heading, description) ⇒ Object



8
9
10
11
12
13
14
15
# File 'app/helpers/govuk_elements_errors_helper.rb', line 8

def self.error_summary object, heading, description
  return unless errors_exist? object
  error_summary_div do
    error_summary_heading(heading) +
    error_summary_description(description) +
    error_summary_list(object)
  end
end

.error_summary_list(object) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
# File 'app/helpers/govuk_elements_errors_helper.rb', line 111

def self.error_summary_list object
  (:ul, class: 'error-summary-list') do
    child_to_parents = child_to_parent(object)
    messages = error_summary_messages(object, child_to_parents)

    messages << children_with_errors(object).map do |child|
      error_summary_messages(child, child_to_parents)
    end

    messages.flatten.join('').html_safe
  end
end

.error_summary_message(object, attribute, child_to_parents) ⇒ Object



130
131
132
133
134
135
136
137
138
# File 'app/helpers/govuk_elements_errors_helper.rb', line 130

def self.error_summary_message object, attribute, child_to_parents
  messages = object.errors.full_messages_for attribute
  messages.map do |message|
    object_prefixes = object_prefixes object, child_to_parents
    link = link_to_error(object_prefixes, attribute)
    message.sub! default_label(attribute), localized_label(object_prefixes, attribute)
    (:li, (:a, message, href: link))
  end
end

.errors_exist?(object) ⇒ Boolean

Returns:

  • (Boolean)


17
18
19
# File 'app/helpers/govuk_elements_errors_helper.rb', line 17

def self.errors_exist? object
  errors_present?(object) || child_errors_present?(object)
end

.errors_present?(object) ⇒ Boolean

Returns:

  • (Boolean)


80
81
82
# File 'app/helpers/govuk_elements_errors_helper.rb', line 80

def self.errors_present? object
  respond_to_errors?(object) && object.errors.present?
end

.instance_variable(object, var) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
# File 'app/helpers/govuk_elements_errors_helper.rb', line 64

def self.instance_variable object, var
  field = var.to_s.sub('@','').to_sym
  if object.respond_to?(field)
    child = object.send(field)
    if respond_to_errors?(child) || child.is_a?(Array)
      child
    else
      nil
    end
  end
end


140
141
142
# File 'app/helpers/govuk_elements_errors_helper.rb', line 140

def self.link_to_error object_prefixes, attribute
  ['#error', *object_prefixes, attribute].join('_')
end

.localized_label(object_prefixes, attribute) ⇒ Object



148
149
150
151
152
153
154
155
# File 'app/helpers/govuk_elements_errors_helper.rb', line 148

def self.localized_label object_prefixes, attribute
  object_key = object_prefixes.shift
  object_prefixes.each { |prefix| object_key += "[#{prefix}]" }
  key = "#{object_key}.#{attribute}"
  I18n.t(key,
    default: default_label(attribute),
    scope: 'helpers.label').presence
end

.object_prefixes(object, child_to_parents) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
# File 'app/helpers/govuk_elements_errors_helper.rb', line 168

def self.object_prefixes object, child_to_parents
  parents = parents_list object, child_to_parents

  if parents.present?
    root = parents.shift
    prefixes = [underscore_name(root)]
    parents.each { |p| prefixes << "#{underscore_name p}_attributes" }
    prefixes << "#{underscore_name object}_attributes"
  else
    prefixes = [underscore_name(object)]
  end
end

.parents_list(object, child_to_parents) ⇒ Object



157
158
159
160
161
162
163
164
165
166
# File 'app/helpers/govuk_elements_errors_helper.rb', line 157

def self.parents_list object, child_to_parents
  if parent = child_to_parents[object]
    [].tap do |parents|
      while parent && !parents.include?(parent)
        parents.unshift parent # prepends parent to front of parents
        parent = child_to_parents[parent]
      end
    end
  end
end

.respond_to_errors?(object) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
# File 'app/helpers/govuk_elements_errors_helper.rb', line 76

def self.respond_to_errors? object
  object && object.respond_to?(:errors)
end

.underscore_name(object) ⇒ Object

‘underscore` changes ’::‘ to ’/‘ to convert namespaces to paths



182
183
184
# File 'app/helpers/govuk_elements_errors_helper.rb', line 182

def self.underscore_name object
  object.class.name.underscore.tr('/'.freeze, '_'.freeze)
end