Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed
Comment thread
mhenrixon marked this conversation as resolved.

- **`FileInput` multiple uploads submit an array** (Rails `file_field` parity):
with `multiple:` set, the input name now gets `[]` appended (unless already
present), for the standalone component, the `Plain` variant, and the form
builder path. Without it the browser collapsed a multi-file selection into
ONE scalar param, which a host app's `params.expect(attr: [])` silently
discarded — uploads no-opped with a success response.

### Added

- **`checkbox_group` — batched checkbox group for array-valued fields** (the
Expand Down
5 changes: 4 additions & 1 deletion lib/forms/file_input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ class FileInput < Phlex::HTML
def initialize(*modifiers, name: nil, id: nil, multiple: false, accept: nil,
error: false, disabled: false, required: false, full_width: true, **attributes)
@modifiers = normalize_modifiers(modifiers)
@name = name
# Rails file_field parity: a multiple input needs an array param name, or
# the browser collapses the selection into one scalar file — which a host
# app's `params.expect(attr: [])` then silently discards.
@name = multiple && name && !name.to_s.end_with?("[]") ? "#{name}[]" : name
@id = id
@multiple = multiple
@accept = accept
Expand Down
46 changes: 46 additions & 0 deletions spec/forms/file_input_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true

require "spec_helper"

# Rails' file_field appends [] to the input name when multiple is set; without
# it the browser collapses a multi-file selection into ONE scalar param, which
# a host app's `params.expect(attr: [])` silently discards — uploads no-op
# with a success response (cosmos production, Aug 2026).
describe Forms::FileInput do
it "keeps the plain name for single-file inputs" do
output = render_component(described_class.new(name: "user[avatar]"))

expect(output).to include('name="user[avatar]"')
expect(output).not_to include("multiple")
end

it "appends [] to the name when multiple (Rails file_field parity)" do
output = render_component(described_class.new(name: "retreat[gallery]", multiple: true))

expect(output).to include('name="retreat[gallery][]"')
expect(output).to include("multiple")
end

it "does not double-append when the caller already passed []" do
output = render_component(described_class.new(name: "retreat[gallery][]", multiple: true))

expect(output).to include('name="retreat[gallery][]"')
expect(output).not_to include("[][]")
end

it "appends [] through the form builder too" do
user = build_model(:user, name: "Ada")
output = PhlexHelpers::FormContext.new(
model: user, form_args: {},
form_block: ->(f) { f.FileInput(:name, multiple: true) }
).call

expect(output).to include('name="user[name][]"')
end

it "applies the same normalization to the Plain variant" do
output = render_component(Forms::Plain::FileInput.new(name: "retreat[gallery]", multiple: true))

expect(output).to include('name="retreat[gallery][]"')
end
end
Loading