The Fluxbit Form Builder provides a seamless integration with Rails form helpers, allowing you to build beautiful, accessible forms with automatic I18n support, validation states, and consistent styling across your application.

Overview

Fluxbit form components work seamlessly with Rails’ form_with, form_for, and standalone usage. All form components automatically integrate with your models, ActiveRecord validations, and I18n translations.

Basic Usage

With Form Builder

<%= form_with model: @user, url: users_path, builder: Fluxbit::FormBuilder do |form| %>
  <%= form.fx_text_field :email %>
  < form.fx_text_field :password, type: :password %>
  <%= form.fx_select :role, ["Admin", "User", "Guest"] %>
  <%= form.fx_checkbox :terms_accepted %>
  <%= form.fx_submit "Create Account" %>
< end %>

Standalone Usage

< fx_text_field name: "email", label: "Email Address", placeholder: "Enter your email" %>
< fx_select "role", ["Admin", "User", "Guest"], prompt: "Select a role" %>
< fx_checkbox name: "terms", label: "I accept the terms" %>

Available Form Components

Component Helper Method Description
TextField fx_text_field Text input, textarea, email, password, number, etc.
  fx_color_field  
  fx_number_field  
  fx_email_field  
  fx_password_field  
  fx_search_field  
  fx_tel_field  
  fx_url_field  
  fx_date_field  
  fx_datetime_local_field  
  fx_month_field  
  fx_time_field  
  fx_week_field  
  fx_currency_field  
  fx_text_area  
  fx_textarea  
Select fx_select Dropdown select with single or multiple selection
Checkbox fx_checkbox Single checkbox or checkbox group
Toggle fx_toggle Toggle switch (styled checkbox)
Radio fx_radio Radio button group
Range fx_range Range slider input
UploadImage fx_upload_image File upload with drag and drop
Dropzone fx_dropzone File upload with drag and drop

Internationalization (I18n)

One of the most powerful features of Fluxbit form components is automatic I18n support. Components automatically look up translations based on your model name and attribute names.

Translation Structure

The I18n lookup follows this structure:

en:
  model_name:           # Pluralized, underscored model name (e.g., "users", "blog_posts")
    fields:             # Field labels
      attribute_name: "Display Label"
    help_text:          # Help text shown below fields
      attribute_name: "Helpful information"
    helper_popover:     # Popover content (info icon next to label)
      attribute_name: "Additional context"
    placeholders:       # Placeholder text for inputs
      attribute_name: "Placeholder text"
    prompts:            # Prompt text for select dropdowns
      attribute_name: "Select an option"

Complete Example

Here’s a complete example for a User model:

# config/locales/en.yml
en:
  users:
    fields:
      email: "Email Address"
      password: "Password"
      first_name: "First Name"
      last_name: "Last Name"
      role: "User Role"
      country: "Country"
      bio: "Biography"
      terms_accepted: "Terms & Conditions"
      newsletter_subscribed: "Newsletter Subscription"

    help_text:
      email: "We'll never share your email with anyone"
      password: "Must be at least 8 characters with letters and numbers"
      role: "This determines the user's permissions in the system"
      country: "Your country affects shipping rates and tax calculations"
      bio: "Tell us about yourself (max 500 characters)"
      terms_accepted: "You must accept the terms to continue"

    helper_popover:
      password: "Use a mix of uppercase, lowercase, numbers, and special characters for better security"
      role: "Admins have full access, Users have limited access, Guests can only view"
      newsletter_subscribed: "You can unsubscribe at any time from your account settings"

    placeholders:
      email: "[email protected]"
      password: "Enter a secure password"
      first_name: "John"
      last_name: "Doe"
      bio: "Tell us about yourself..."

    prompts:
      role: "Select a role"
      country: "Choose your country"

Using I18n in Forms

With the translations in place, your forms become much cleaner:

<%= form_with model: @user do |form| %>
  <%# All labels, help text, placeholders automatically loaded from I18n %>
  <%= form.fx_text_field :email %>
  <%= form.fx_text_field :password, type: :password %>
  <%= form.fx_text_field :first_name %>
  <%= form.fx_text_field :last_name %>
  <%= form.fx_text_field :bio, multiline: true %>
  <%= form.fx_select :role, ["Admin", "User", "Guest"] %>
  <%= form.fx_select :country, countries_collection %>
  <%= form.fx_checkbox :terms_accepted %>
  <%= form.fx_checkbox :newsletter_subscribed %>
  <%= form.fx_submit "Create Account" %>
<% end %>

This form will automatically display:

  • Labels from the fields section
  • Help text from the help_text section
  • Popover information from the helper_popover section
  • Placeholders from the placeholders section
  • Select prompts from the prompts section

Override Behavior

You can override I18n translations in three ways:

1. Provide a Custom Value

<%# Override the I18n label with a custom label %>
<%= form.fx_text_field :email, label: "Email (Required)" %>

<%# Override the placeholder %>
<%= form.fx_text_field :email, placeholder: "[email protected]" %>

<%# Override the help text %>
<%= form.fx_text_field :password, help_text: "Custom help text here" %>

2. Disable Automatic Lookup

<%# Disable the label (no label will be shown) %>
<%= form.fx_text_field :email, label: false %>

<%# Disable the placeholder %>
<%= form.fx_text_field :email, placeholder: false %>

<%# Disable the help text %>
<%= form.fx_text_field :email, help_text: false %>

<%# Disable the prompt in selects %>
<%= form.fx_select :role, roles, prompt: false %>

3. Use Default Behavior

<%# Leave blank to use I18n lookup %>
<%= form.fx_text_field :email %>

Fallback Behavior

When I18n translations are not found, the components use sensible defaults:

Attribute Fallback Behavior
Label Uses Model.human_attribute_name(:attribute) or humanized attribute name
Help Text No help text shown
Helper Popover No popover shown
Placeholder No placeholder shown
Prompt No prompt shown (except when explicitly set to true, which uses “Please select”)

Validation States

Fluxbit form components automatically integrate with ActiveRecord validations and display errors.

Automatic Error Display

When a model has validation errors, components automatically:

  • Change color to danger/error state
  • Display error messages as help text
  • Add appropriate ARIA attributes for accessibility
<%# If @user.errors[:email] contains errors, they will automatically display %>
<%= form.fx_text_field :email %>

Manual Validation States

You can manually set validation states using the color parameter:

<%# Success state %>
<%= form.fx_text_field :email, color: :success %>

<%# Error/Danger state %>
<%= form.fx_text_field :email, color: :danger %>

<%# Warning state %>
<%= form.fx_text_field :email, color: :warning %>

<%# Info state %>
<%= form.fx_text_field :email, color: :info %>

<%# Default state %>
<%= form.fx_text_field :email, color: :default %>

Complete Form Example

Here’s a complete form demonstrating all features:

<%= form_with model: @user, url: users_path, local: true do |form| %>
  <div class="space-y-6">
    <%# Basic Information Section %>
    <div class="bg-white p-6 rounded-lg shadow">
      <h2> class="text-xl font-semibold mb-4">Basic Information</h2>

      <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
        <%= form.fx_text_field :first_name, required: true %>
        <%= form.fx_text_field :last_name, required: true %>
      </div>

      <%= form.fx_text_field :email, type: :email, required: true, icon: :mail %>
      <%= form.fx_text_field :password, type: :password, required: true, icon: :lock %>

      <%= form.fx_text_field :bio, multiline: true, sizing: 2 %>
    </div>

    <%# Account Settings Section %>
    <div class="bg-white p-6 rounded-lg shadow">
      <h2> class="text-xl font-semibold mb-4">Account Settings</h2>

      <%= form.fx_select :role,
          ["Admin", "User", "Guest"],
          { include_blank: false } %>

      <%= form.fx_select :country,
          options_from_collection_for_select(@countries, :code, :name),
          {} %>

      <%= form.fx_select :timezone,
          time_zone: true %>
    </div>

    <%# Preferences Section %>
    <div class="bg-white p-6 rounded-lg shadow">
      <h2> class="text-xl font-semibold mb-4">Preferences</h2>

      <%= form.fx_checkbox :terms_accepted, required: true %>
      <%= form.fx_toggle :newsletter_subscribed %>
      <%= form.fx_toggle :email_notifications %>
    </div>

    <%# Submit Button %>
    <div class="flex justify-end gap-3">
      <%= link_to "Cancel", users_path, class: "px-4 py-2 border rounded" %>
      <%= form.fx_submit "Create Account", color: :primary %>
    </div>
  </div>
<% end %>

Multi-Language Support

Fluxbit form components make it easy to support multiple languages:

# config/locales/en.yml
en:
  users:
    fields:
      email: "Email Address"
      password: "Password"
    placeholders:
      email: "[email protected]"
    prompts:
      role: "Select a role"

# config/locales/pt-BR.yml
pt-BR:
  users:
    fields:
      email: "Endereço de Email"
      password: "Senha"
    placeholders:
      email: "[email protected]"
    prompts:
      role: "Selecione uma função"

# config/locales/es.yml
es:
  users:
    fields:
      email: "Dirección de Correo"
      password: "Contraseña"
    placeholders:
      email: "[email protected]"
    prompts:
      role: "Seleccionar un rol"

The same form code works for all languages - just change I18n.locale:

# application_controller.rb
class ApplicationController < ActionController::Base
  before_action :set_locale

  def set_locale
    I18n.locale = params[:locale] || I18n.default_locale
  end
end

Form Builder Methods

All standard Rails form builder methods are available with the fx_ prefix:

Text Inputs

  • fx_text_field - Standard text input
  • fx_email_field - Email input (alias: fx_text_field(type: :email))
  • fx_password_field - Password input (alias: fx_text_field(type: :password))
  • fx_number_field - Number input (alias: fx_text_field(type: :number))
  • fx_url_field - URL input (alias: fx_text_field(type: :url))
  • fx_telephone_field - Phone input (alias: fx_text_field(type: :tel))
  • fx_text_area - Multi-line text (alias: fx_text_field(multiline: true))

Select Inputs

  • fx_select - Dropdown select
  • fx_time_zone_select - Time zone select (alias: fx_select(time_zone: true))

Checkboxes and Radios

  • fx_checkbox - Single checkbox or checkbox group
  • fx_toggle - Toggle switch
  • fx_radio - Radio button group

Other Inputs

  • fx_range - Range slider
  • fx_dropzone - File upload with drag and drop

Buttons

  • fx_submit - Submit button
  • fx_button - Generic button

Best Practices

1. Use I18n for All User-Facing Text

&lt;%# Good: Uses I18n %&gt;
&lt;%= form.fx_text_field :email %&gt;

&lt;%# Avoid: Hardcoded text %&gt;
&lt;%= form.fx_text_field :email, label: "Email", placeholder: "Enter email" %&gt;

2. Organize Translations by Model

Keep your translation files organized by model for easier maintenance:

config/locales/
  en/
    users.yml
    products.yml
    orders.yml
  pt-BR/
    users.yml
    products.yml
    orders.yml

3. Use Validation States Appropriately

&lt;%# Let errors display automatically %&gt;
&lt;%= form.fx_text_field :email %&gt;

&lt;%# Only override when you have a specific reason %&gt;
&lt;%= form.fx_text_field :email, color: :success if @user.email_verified? %&gt;

Use HTML structure to group related fields:

&lt;div class="form-section"&gt;
  &lt;h3&gt;Contact Information&lt;/h3&gt;
  &lt;%= form.fx_text_field :email %&gt;
  &lt;%= form.fx_text_field :phone %&gt;
&lt;/div&gt;

&lt;div class="form-section"&gt;
  &lt;h3&gt;Address&lt;/h3&gt;
  &lt;%= form.fx_text_field :street %&gt;
  &lt;%= form.fx_text_field :city %&gt;
&lt;/div&gt;

5. Provide Helpful Context

Use helper popovers for complex fields:

en:
  users:
    helper_popover:
      api_key: "Your API key is used to authenticate requests. Keep it secret and never share it publicly."
      webhook_url: "Enter the URL where you want to receive webhook notifications. Must be HTTPS."

Accessibility

All Fluxbit form components are built with accessibility in mind:

  • Proper &lt;label&gt; elements with for attributes
  • ARIA attributes for validation states
  • Keyboard navigation support
  • Screen reader friendly error messages
  • Required field indicators
&lt;%# Automatically accessible %&gt;
&lt;%= form.fx_text_field :email, required: true %&gt;

&lt;%# Renders with proper ARIA attributes:
  - aria-required="true"
  - aria-invalid="true" (if errors)
  - aria-describedby="email_help" (if help text)
%&gt;

Common Patterns

Conditional Fields

&lt;%= form.fx_select :account_type, ["Personal", "Business"] %&gt;

&lt;%= form.fx_text_field :company_name if @user.account_type == "Business" %&gt;

Dynamic Options

&lt;%= form.fx_select :country,
    options_from_collection_for_select(@countries, :id, :name, @user.country_id) %&gt;

&lt;%= form.fx_select :state,
    options_from_collection_for_select(@states, :id, :name, @user.state_id),
    { prompt: true },
    { data: { dependent_on: "user_country" } } %&gt;

File Uploads

&lt;%= form.fx_dropzone :avatar,
    accept: "image/*",
    max_size: 5.megabytes,
    help_text: "Upload a profile photo (max 5MB)" %&gt;

Array Fields

&lt;%= form.fx_text_field :tags,
    value: @user.tags.join(", "),
    placeholder: "ruby, rails, javascript",
    help_text: "Separate tags with commas" %&gt;

Troubleshooting

Translations Not Loading

  1. Check your I18n file structure:
    en:
      users:  # Must be pluralized model name
        fields:
          email: "Email"
    
  2. Verify your locale is set:
    I18n.locale  # => :en
    
  3. Check if translations exist:
    I18n.exists?(:email, scope: [:users, :fields])  # => true/false
    

Errors Not Displaying

  1. Ensure your model has errors:
    @user.errors.any?  # => true
    
  2. Check the attribute has errors:
    @user.errors[:email]  # => ["can't be blank"]
    
  3. Verify you’re using a form builder:
    &lt;%= form_with model: @user do |form| %&gt;
      &lt;%= form.fx_text_field :email %&gt;  &lt;%# Will show errors %&gt;
    &lt;% end %&gt;
    

Custom Styling Not Applied

  1. Check if classes are being removed:
    &lt;%= form.fx_text_field :email, remove_class: "unwanted-class" %&gt;
    
  2. Ensure custom classes are added after component initialization:
    &lt;%= form.fx_text_field :email, class: "custom-class" %&gt;
    

See Also