Class: Fluxbit::Form::SelectComponent

Inherits:
TextFieldComponent
  • Object
show all
Defined in:
app/components/fluxbit/form/select_component.rb

Overview

The ‘Fluxbit::Form::SelectComponent` is a styled dropdown/select field for forms. It supports standard, grouped, and time zone options, integrates with Rails form builders, and provides flexible props for prompt, disabled/selected options, helper text, and more.

Examples:

Basic usage

= render Fluxbit::Form::SelectComponent.new(name: :role, options: ["Admin", "User", "Guest"], label: "User Role")

See Also:

  • For detailed documentation and examples.

Instance Method Summary collapse

Constructor Details

#initialize(**props) ⇒ SelectComponent

Initializes the select component with the given properties.

Parameters:

  • name (String)

    Name of the field (required unless using form builder)

  • label (String, false)

    Label text for the select field (optional, auto-generated from attribute if using form builder)

  • help_text (String, Array, false)

    Help text displayed below the field (optional, supports i18n)

  • helper_popover (String, false)

    Content for an info popover next to the label (optional, supports i18n)

  • helper_popover_placement (String)

    Placement of the popover: “top”, “right”, “bottom”, “left” (default: “right”)

  • value (String)

    Value for the field (optional)

  • grouped (Boolean)

    Enables grouped select options (default: false)

  • time_zone (Boolean)

    Uses Rails time zone select options (default: false)

  • select_options (Hash)

    Options for select tag (prompt, selected, disabled, etc)

  • choices (Array)

    List of choices for options (alternative to options)

  • options (Array, Hash, String)

    List or hash of options, or pre-formatted HTML from options_for_select

  • prompt (String, Boolean, false)

    Prompt text, true to use default, or false to disable (optional, defaults to I18n if object/attribute present)

  • include_blank (String, Boolean)

    Include blank option (optional)

  • selected (Object)

    Pre-selected value (optional)

  • disabled (Array, Object)

    Disabled options (optional)

  • color (Symbol)

    Color state: :default, :success, :danger, :warning, :info (optional)

  • sizing (Integer)

    Field size (0 to 2, default: 1)

  • class (String)

    Additional CSS classes for the select element

  • ...

    any other HTML attribute supported by <select>



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'app/components/fluxbit/form/select_component.rb', line 33

def initialize(**props)
  super(**props)
  @grouped = @props.delete(:grouped) || false
  @time_zone = @props.delete(:time_zone) || false
  @select_options = @props.delete(:select_options) || {}
  @choices = @props.delete(:choices) || nil
  @options = @props.delete(:options) || {}

  # Extract select-specific options
  prompt_value = @select_options.delete(:prompt) || @props.delete(:prompt)
  @include_blank = @select_options.delete(:include_blank) || @props.delete(:include_blank)
  @selected = @select_options.delete(:selected) || @props.delete(:selected)
  @disabled_options = @select_options.delete(:disabled) || @props.delete(:disabled)

  @options = ::ActiveSupport::TimeZone.all if @time_zone

  # Define prompt with I18n support
  define_prompt(prompt_value)
end

Instance Method Details

#build_options_for_selectObject

Build pre-formatted option tags for select_tag and form.select



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
# File 'app/components/fluxbit/form/select_component.rb', line 97

def build_options_for_select
  # If options are already HTML (from options_for_select/grouped_options_for_select), use as-is
  if options_are_preformatted?
    html = @options.dup
    # Add prompt if needed and not already in the HTML (only for select_tag)
    html = add_prompt_to_html(html) if @prompt && !html.include?(@prompt.to_s) && !using_form_builder?
    return html
  end

  # Otherwise, build the HTML from raw data
  html = if @grouped
    grouped_options_for_select(
      @options,
      @selected,
      disabled: @disabled_options,
      divider: @divider
    )
  elsif @time_zone
    time_zone_options_for_select(@selected)
  else
    options_for_select(@options, selected: @selected, disabled: @disabled_options)
  end

  # Add prompt option at the beginning if specified
  # Only add it manually for select_tag (form.select handles it via options hash)
  html = add_prompt_to_html(html) if @prompt && !using_form_builder?
  html
end

#build_select_options_hashObject

Build options hash for form.select (prompt, include_blank, etc.) Note: Don’t include selected/disabled if options are pre-formatted HTML



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/components/fluxbit/form/select_component.rb', line 82

def build_select_options_hash
  options_hash = @select_options.dup
  options_hash[:prompt] = @prompt if @prompt
  options_hash[:include_blank] = @include_blank if @include_blank

  # Only add selected/disabled if we're building options from raw data
  unless options_are_preformatted?
    options_hash[:selected] = @selected if @selected
    options_hash[:disabled] = @disabled_options if @disabled_options
  end

  options_hash
end

#inputObject



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
# File 'app/components/fluxbit/form/select_component.rb', line 53

def input
  if @form.present? && @attribute.present?
    # form.select(attribute, choices, options = {}, html_options = {})
    # For form builder with time zones, use the specialized helper
    if @time_zone
      @form.time_zone_select(@attribute, nil, build_select_options_hash, @props)
    else
      # form.select can accept raw choices OR pre-formatted option tags
      # We use pre-formatted tags for consistency with grouped selects
      @form.select(
        @attribute,
        build_options_for_select,
        build_select_options_hash,
        @props
      )
    end
  else
    # select_tag(name, option_tags = nil, options = {})
    # option_tags should be pre-formatted HTML
    select_tag(
      @name,
      build_options_for_select,
      @props
    )
  end
end