Class: CCS::Components::GovUK::Field::Input::CharacterCount

Inherits:
Object
  • Object
show all
Defined in:
lib/ccs/components/govuk/field/input/character_count.rb,
lib/ccs/components/govuk/field/input/character_count/count_message.rb

Overview

GOV.UK Character count

This is used for generating the character count component from the GDS - Components - Character count

This is a wrapper around a Textarea module and so makes use of the methods in Textarea

Defined Under Namespace

Classes: CountMessage

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attribute:, context:, character_count_options: {}, **options) ⇒ CharacterCount

Returns a new instance of CharacterCount.

Parameters:

  • character_count_options (Hash) (defaults to: {})

    options for the character count

  • context (ActionView::Base)

    the view context

  • content (String)

    the content of the textarea

  • rows (Integer)

    the number of rows for the text area

  • label (Hash)

    attributes for the label, see Label#initialize for more details.

  • before_input (String)

    text or HTML to go before the input

  • after_input (String)

    text or HTML to go after the input

  • attribute (String, Symbol)

    the attribute of the field

  • hint (Hash)

    attributes for the hint, see Hint#initialize for more details. If no hint is given then no hint will be rendered

  • form_group (Hash)

    attributes for the form group, see FormGroup#initialize for more details.

  • options (Hash)

    options that will be used for the parts of the field

Options Hash (**options):

  • :error_message (String) — default: nil

    the error message to be displayed

  • :model (ActiveModel) — default: nil

    optional model that can be used to find an error message

  • :form (ActionView::Helpers::FormBuilder) — default: nil

    optional form builder used to create the field and find the error message

  • :classes (String)

    additional CSS classes for the field HTML

  • :attributes (Hash) — default: {}

    any additional attributes that will added as part of the HTML



38
39
40
41
42
# File 'lib/ccs/components/govuk/field/input/character_count.rb', line 38

def initialize(attribute:, context:, character_count_options: {}, **options)
  character_count_attribute = options[:form] ? "#{options[:form].object_name}_#{attribute}" : attribute

  initialise_textarea(attribute, character_count_attribute, character_count_options, context, options)
end

Instance Attribute Details

#character_count_html_optionsHash (readonly)

Returns HTML options for the character count.

Returns:

  • (Hash)

    HTML options for the character count



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/ccs/components/govuk/field/input/character_count.rb', line 23

class CharacterCount
  private

  attr_reader :textarea, :textarea_description

  public

  # @param (see CCS::Components::GovUK::Field::Input::Textarea#initialize)
  # @param character_count_options [Hash] options for the character count
  # @param context [ActionView::Base] the view context
  #
  # @option (see CCS::Components::GovUK::Field::Input::Textarea#initialize)
  #
  # @option (see initialise_character_count_html_options)

  def initialize(attribute:, context:, character_count_options: {}, **options)
    character_count_attribute = options[:form] ? "#{options[:form].object_name}_#{attribute}" : attribute

    initialise_textarea(attribute, character_count_attribute, character_count_options, context, options)
  end

  delegate :render, to: :textarea

  private

  # Initialises the Textarea for the character count
  #
  # @param attribute [Symbol] the attribute of the field
  # @param character_count_attribute [String] the name of the field as it will appear in the textarea
  # @param character_count_options [Hash] options for the character count
  # @param context [ActionView::Base] the view context
  # @param options [Hash] options that will be used for the textarea
  #
  # @option (see CCS::Components::GovUK::Field::Input::Textarea#initialize)

  def initialise_textarea(attribute, character_count_attribute, character_count_options, context, options)
    set_character_count_from_group_options(character_count_options, options)

    ((options[:attributes] ||= {})[:aria] ||= {})[:describedby] = [options.dig(:attributes, :aria, :describedby), "#{character_count_attribute}-info"].compact.join(' ')
    options[:classes] = "govuk-js-character-count #{options[:classes]}".rstrip

    count_message = CountMessage.new(character_count_attribute: character_count_attribute, context: context, character_count_options: character_count_options, after_input: options.delete(:after_input))
    @textarea = Textarea.new(attribute: attribute, context: context, after_input: count_message.render, **options)
  end

  # Sets the charcter count form group options
  #
  # @param character_count_options [Hash] options for the charcter count
  #
  # @option character_count_options [String] :maxlength the maximum number of characters.
  #                                                     If +maxwords+ is set, this is not required.
  #                                                     If +maxwords+ is provided, the +maxlength+ option will be ignored.
  # @option character_count_options [String] :maxwords the maximum number of words.
  #                                                    If maxlength is set, this is not required.
  #                                                    If +maxwords+ is provided, the +maxlength+ option will be ignored.
  # @option character_count_options [String] :threshold the percentage value of the limit at which point the count message is displayed.
  #                                                     If this attribute is set, the count message will be hidden by default.
  # @option character_count_options [Hash] :textarea_description ({}) additional parameters that will be used to create the hint containing the character count text:
  #                                                            - +:count_message+ replaced the default text for the count message.
  #                                                                               If you want the count number to appear, put %<count>s in the string and it will be replaced with the number
  #                                                            - +classes+ additional CSS classes for the textarea description HTML
  # @option character_count_options [String] :characters_under_limit Message displayed when the number of characters is under the configured maximum, maxlength
  # @option character_count_options [String] :characters_at_limit_text Message displayed when the number of characters reaches the configured maximum, maxlength
  # @option character_count_options [String] :characters_over_limit Message displayed when the number of characters is over the configured maximum, maxlength
  # @option character_count_options [String] :words_under_limit Message displayed when the number of words is under the configured maximum, maxwords
  # @option character_count_options [String] :words_at_limit_text Message displayed when the number of words reaches the configured maximum, maxwords
  # @option character_count_options [String] :words_over_limit Message displayed when the number of words is over the configured maximum, maxwords

  def set_character_count_from_group_options(character_count_options, options)
    (options[:form_group] ||= {})[:classes] = "govuk-character-count #{options.dig(:form_group, :classes)}".rstrip
    ((options[:form_group][:attributes] ||= {})[:data] ||= {})[:module] = 'govuk-character-count'

    %i[maxlength threshold maxwords].each do |data_attribute|
      options[:form_group][:attributes][:data][data_attribute] = character_count_options[data_attribute].to_s if character_count_options[data_attribute]
    end

    get_chacrter_count_translations(character_count_options) do |data_attribute, value|
      options[:form_group][:attributes][:data][data_attribute] = value
    end
  end

  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

  # Generator for the translation options for character count
  #
  # @param (see initialise_character_count_html_options)
  #
  # @option (see initialise_character_count_html_options)
  #
  # @return [Hash]

  def get_chacrter_count_translations(character_count_options)
    %i[characters_at_limit words_at_limit].each do |data_attribute|
      data_attribute_name = :"#{data_attribute}_text"

      next unless character_count_options[data_attribute_name]

      yield :"i18n.#{data_attribute.to_s.gsub('_', '-')}", character_count_options[data_attribute_name]
    end

    %i[characters_under_limit characters_over_limit words_under_limit words_over_limit].each do |data_attribute|
      next unless character_count_options[data_attribute]

      %i[other one].each do |plural_rule|
        next unless character_count_options[data_attribute][plural_rule]

        yield :"i18n.#{data_attribute.to_s.gsub('_', '-')}.#{plural_rule}", character_count_options[data_attribute][plural_rule]
      end
    end

    yield :'i18n.textarea-description.other', character_count_options[:textarea_description][:count_message] if character_count_options.dig(:textarea_description, :count_message) && !(character_count_options[:maxwords] || character_count_options[:maxlength])
  end

  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
end