Purpose: Provides comprehensive bulk selection functionality with visual feedback and dynamic UI updates based on selection state.

Features

  • Master checkbox with indeterminate state
  • Automatic selection count updates
  • Dynamic show/hide elements based on selection
  • Enable/disable buttons based on selection state
  • Event triggering for integration with other controllers

Static Targets

static targets = [
  "selectAll",              // Master checkbox
  "select",                 // Individual checkboxes
  "disableOnEmptySelect",   // Elements to disable when nothing selected
  "enableOnEmptySelect",    // Elements to enable when nothing selected
  "hideOnEmptySelect",      // Elements to hide when nothing selected
  "showOnEmptySelect",      // Elements to show when nothing selected
  "count"                   // Elements to display count
]

Static Values

static values = {
  disableIndeterminate: { type: Boolean, default: false }
}

Usage Examples

Basic Bulk Selection

<div data-controller="fx-select-all">
  <table class="w-full">
    <thead>
      <tr>
        <th class="w-12">
          <input type="checkbox"
                 data-fx-select-all-target="selectAll"
                 class="rounded">
        </th>
        <th>Name</th>
        <th>Email</th>
      </tr>
    </thead>
    <tbody>
      <% @users.each do |user| %>
        <tr>
          <td>
            <input type="checkbox"
                   name="selected_ids[]"
                   value="<%= user.id %>"
                   data-fx-select-all-target="select"
                   class="rounded">
          </td>
          <td><%= user.name %></td>
          <td><%= user.email %></td>
        </tr>
      <% end %>
    </tbody>
  </table>

  <!-- Action buttons that appear when items are selected -->
  <div class="mt-4 hidden" data-fx-select-all-target="showOnEmptySelect">
    <span data-fx-select-all-target="count">0</span> items selected
    <button class="btn btn-danger"
            data-fx-select-all-target="disableOnEmptySelect">
      Delete Selected
    </button>
  </div>
</div>

Advanced Selection with Form Integration

<%= form_with url: bulk_actions_path, local: true, data: { controller: "fx-select-all" } do |f| %>
  <div class="flex justify-between items-center mb-4">
    <label class="flex items-center">
      <input type="checkbox"
             data-fx-select-all-target="selectAll"
             class="mr-2">
      Select All
    </label>

    <div class="hidden" data-fx-select-all-target="showOnEmptySelect">
      <span class="mr-2">
        <strong data-fx-select-all-target="count">0</strong> selected
      </span>
      <%= f.select :action, [['Delete', 'delete'], ['Archive', 'archive']],
          { prompt: 'Choose action' },
          { data: { fx_select_all_target: "disableOnEmptySelect" } } %>
      <%= f.submit "Execute",
          class: "btn btn-primary",
          data: { fx_select_all_target: "disableOnEmptySelect" } %>
    </div>
  </div>

  <div class="grid gap-4">
    <% @items.each do |item| %>
      <div class="border p-4 rounded">
        <label class="flex items-start">
          <input type="checkbox"
                 name="selected_ids[]"
                 value="<%= item.id %>"
                 data-fx-select-all-target="select"
                 class="mt-1 mr-3">
          <div>
            <h4><%= item.title %></h4>
            <p class="text-gray-600"><%= item.description %></p>
          </div>
        </label>
      </div>
    <% end %>
  </div>
<% end %>

Disable Indeterminate State

<div data-controller="fx-select-all"
     data-fx-select-all-disable-indeterminate-value="true">
  <!-- Checkboxes here -->
</div>