Files
nairobi/lib/consul_form_builder.rb
Javi Martín cdf859621e Allow links in forms to open in new tabs
We used to open these links in new tabs, but accidentally stopped doing
so in commit 75a28fafc.

While, in general, automatically opening a link in a new tab/window is a
bad idea, the exception comes when people are filling in a form and
there are links to pages that contain information which will help them
fill in a form.

There are mainly two advantages of this approach. First, it makes less
likely for people to accidentally lose the information they were filling
in. And, second, having both the form and a help page open at the same
time can make it easier to fill in the form.

However, opening these links in new tabs also has disadvantages, like
taking control away from people or making it harder to navigate through
pages when using a mobile phone.

So this is a compromise solution.
2023-10-23 18:19:48 +02:00

101 lines
3.0 KiB
Ruby

class ConsulFormBuilder < FoundationRailsHelper::FormBuilder
include ActionView::Helpers::SanitizeHelper
def enum_select(attribute, options = {}, html_options = {})
choices = object.class.send(attribute.to_s.pluralize).keys.map do |name|
[object.class.human_attribute_name("#{attribute}.#{name}"), name]
end
select attribute, choices, options, html_options
end
%i[text_field text_area date_field number_field password_field email_field].each do |field|
define_method field do |attribute, options = {}|
label_with_hint(attribute, options.merge(label_options: label_options_for(options))) +
super(attribute, options.merge(
label: false, hint: nil,
aria: { describedby: help_text_id(attribute, options) }
))
end
end
def check_box(attribute, options = {})
if options[:label] == false
super
else
label = tag.span sanitized_label_text(attribute, options[:label]), class: "checkbox"
super(attribute, options.merge(
label: label,
label_options: { class: "checkbox-label" }.merge(label_options_for(options))
))
end
end
def radio_button(attribute, tag_value, options = {})
default_label = object.class.human_attribute_name("#{attribute}_#{tag_value}")
super(attribute, tag_value, { label: default_label }.merge(options))
end
def select(attribute, choices, options = {}, html_options = {})
label_with_hint(attribute, options.merge(label_options: label_options_for(options))) +
super(attribute, choices, options.merge(label: false, hint: nil), html_options.merge({
aria: { describedby: help_text_id(attribute, options) }
}))
end
private
def custom_label(attribute, text, options)
if text == false
super
else
super(attribute, sanitized_label_text(attribute, text), options)
end
end
def label_with_hint(attribute, options)
custom_label(attribute, options[:label], options[:label_options]) +
help_text(attribute, options)
end
def label_text(attribute, text)
if text.nil? || text == true
default_label_text(object, attribute)
else
text
end
end
def sanitized_label_text(attribute, text)
sanitize(label_text(attribute, text), attributes: allowed_attributes)
end
def allowed_attributes
self.class.sanitized_allowed_attributes + ["target"]
end
def label_options_for(options)
label_options = options[:label_options] || {}
if options[:id]
{ for: options[:id] }.merge(label_options)
else
label_options
end
end
def help_text(attribute, options)
if options[:hint].present?
tag.span options[:hint], class: "help-text", id: help_text_id(attribute, options)
end
end
def help_text_id(attribute, options)
if options[:hint].present?
"#{custom_label(attribute, "Example", nil).match(/for="([^"]+)"/)[1]}-help-text"
end
end
end