Skip to content

feat: add one-to-many collection field support#89

Merged
phmatray merged 1 commit intomainfrom
feat/20-one-to-many-model-support
Feb 26, 2026
Merged

feat: add one-to-many collection field support#89
phmatray merged 1 commit intomainfrom
feat/20-one-to-many-model-support

Conversation

@phmatray
Copy link
Owner

Summary

Adds collection field support to FormCraft, enabling one-to-many model forms (e.g., Order with OrderItems). Implements the fluent API proposed in #20.

Fixes #20

Changes

Core library (FormCraft/)

  • Forms/Core/ICollectionFieldConfiguration.cs — New generic interface defining collection field config (accessor, setter, min/max items, add/remove/reorder flags)
  • Forms/Core/ICollectionFieldConfigurationBase.cs — Non-generic base interface for type-erased storage in collections
  • Forms/Core/CollectionFieldConfiguration.cs — Implementation with expression-based property access and setter compilation
  • Forms/Core/IFormConfiguration.cs — Added ICollectionFormConfiguration<TModel> interface (non-breaking); FormConfiguration now implements it with CollectionFields list
  • Forms/Builders/CollectionFieldBuilder.cs — Fluent builder with AllowAdd(), AllowRemove(), AllowReorder(), WithMinItems(), WithMaxItems(), WithItemForm()
  • Forms/Builders/FormBuilder.cs — Added AddCollectionField<TItem>() method
  • Forms/Validators/CollectionFieldValidator.cs — Validates min/max item counts and recursively validates each item's fields

MudBlazor layer (FormCraft.ForMudBlazor/)

  • Features/CollectionField/CollectionFieldComponent.razor[.cs] — Renders collection with MudBlazor: add button, item cards with remove/reorder controls, per-item field rendering
  • Features/CollectionField/CollectionFieldRenderer.cs — Reflection bridge from non-generic ICollectionFieldConfigurationBase to generic CollectionFieldComponent<TModel, TItem>
  • Features/FormContainer/FormCraftComponent.razor — Renders collection fields after scalar fields
  • Features/FormContainer/FormCraftComponent.razor.cs — Added CollectionConfiguration property and HandleCollectionChanged method
  • Features/Validation/DynamicFormValidator.cs — Extended to validate collection fields recursively on form submission

Tests (FormCraft.UnitTests/)

  • Builders/CollectionFieldBuilderTests.cs — 15 tests covering builder API, chaining, defaults, accessor, item form, and full API pattern matching owner's proposal
  • Validators/CollectionFieldValidatorTests.cs — 5 tests covering min/max validation and per-item recursive validation

Testing

  • 20 new unit tests added, all passing
  • 557 existing tests remain passing (577 total, 0 failures)
  • Build succeeds on all target frameworks (net8.0, net9.0, net10.0)
  • Full API matches the owner's proposed pattern from issue comments

Discovered Issues

  • The Title attribute on MudIconButton triggers MUD0002 warnings in the MudBlazor analyzer (pre-existing pattern in the codebase, not introduced by this PR)
  • EditContext flat model design means nested field identifiers (e.g., Items[0].ProductName) are handled at the component level rather than through Blazor's built-in field identifier system — this works but could be improved in a future iteration
  • Drag-and-drop reordering not included (uses up/down buttons as specified in the analysis)

Implement AddCollectionField API for FormBuilder with fluent configuration,
MudBlazor rendering component, and recursive validation support.

New types:
- ICollectionFieldConfiguration<TModel, TItem> / ICollectionFieldConfigurationBase
- CollectionFieldConfiguration<TModel, TItem>
- CollectionFieldBuilder<TModel, TItem> (fluent API)
- CollectionFieldValidator<TModel, TItem> (min/max items + per-item validation)
- CollectionFieldComponent (MudBlazor rendering with add/remove/reorder)
- CollectionFieldRenderer (reflection-based generic bridge)

Extended:
- FormBuilder<TModel>.AddCollectionField() method
- ICollectionFormConfiguration<TModel> interface (non-breaking)
- FormConfiguration<TModel> implements ICollectionFormConfiguration
- FormCraftComponent renders collection fields
- DynamicFormValidator validates collection fields recursively

Tests: 20 new tests covering builder API, validation, and full API pattern.

Fixes #20
@phmatray phmatray merged commit acdc198 into main Feb 26, 2026
1 check passed
@phmatray phmatray deleted the feat/20-one-to-many-model-support branch February 26, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: one-to-many model support

1 participant