Skip to content

Add fieldset formwidget#1435

Open
mjauvin wants to merge 17 commits into
developfrom
fieldset-formwidget
Open

Add fieldset formwidget#1435
mjauvin wants to merge 17 commits into
developfrom
fieldset-formwidget

Conversation

@mjauvin

@mjauvin mjauvin commented Jan 8, 2026

Copy link
Copy Markdown
Member

This formwidget wraps form elements with a <fieldset> HTML tag.

The fields are visually grouped but saved as if they were regular fields at the parent level.

The field's label config is used for the <fieldset> legend.

The Form widget's getSaveData() method now checks for a getFormFields() method on widgets in order to pull child fields from the widget.

image

The field config is akin to a nestedform:

myFieldSet:
  type: fieldset
  label: Grouped Fields
  form:
    fields:
      ...

Summary by CodeRabbit

  • New Features

    • Adds a FieldSet form widget to embed a nested form section with an optional legend and an option to hide labels.
  • Style

    • New themed styling for the FieldSet, including dark-mode support and improved tab visuals.
  • Bug Fixes

    • Nested widget fields are now collected and saved correctly during form submission.

@mjauvin mjauvin requested a review from LukeTowers January 8, 2026 15:35
@mjauvin mjauvin self-assigned this Jan 8, 2026
@mjauvin mjauvin added enhancement PRs that implement a new feature or substantial change needs review Issues/PRs that require a review from a maintainer labels Jan 8, 2026
@coderabbitai

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as outdated.

@damsfx

damsfx commented Jan 8, 2026

Copy link
Copy Markdown
Contributor

@mjauvin How is the responsive design being managed?
Does the span left/right/auto or custom Css with span:storm still works ?

@mjauvin

mjauvin commented Jan 8, 2026

Copy link
Copy Markdown
Member Author

@mjauvin How is the responsive design being managed? Does the span left/right/auto or custom Css with span:storm still works ?

It's pretty much derived from a nestedform ... so it renders a form within the <fieldset> tag.

The main difference is that fields are exported to the parent when saving (does not use a JSON field).

coderabbitai[bot]

This comment was marked as outdated.

@mjauvin mjauvin marked this pull request as draft January 14, 2026 15:17
@mjauvin mjauvin marked this pull request as ready for review January 14, 2026 22:28
Comment thread modules/backend/formwidgets/FieldSet.php
@LukeTowers

Copy link
Copy Markdown
Member

@mjauvin can you make a PR to the docs and include examples in the nestedform and fieldset sections as to when you should pick one vs the other?

@LukeTowers LukeTowers added this to the 1.3.0 milestone Feb 20, 2026
@mjauvin

mjauvin commented Feb 20, 2026

Copy link
Copy Markdown
Member Author

@mjauvin can you make a PR to the docs and include examples in the nestedform and fieldset sections as to when you should pick one vs the other?

Done in wintercms/docs#258

Comment thread modules/backend/formwidgets/fieldset/assets/less/fieldset.less
Comment thread modules/backend/formwidgets/fieldset/partials/_fieldset.php Outdated
Comment thread modules/backend/formwidgets/FieldSet.php
Comment thread modules/backend/widgets/Form.php
mjauvin and others added 3 commits February 20, 2026 12:10
@mjauvin mjauvin marked this pull request as draft February 20, 2026 17:35
@mjauvin mjauvin marked this pull request as ready for review March 10, 2026 21:19
@mjauvin

mjauvin commented Mar 10, 2026

Copy link
Copy Markdown
Member Author

This is now working great with forwidgets inside the fielset. It won't work at multiple levels, though (e.g. widget inside a nestedform inside the fieldset).

@mjauvin mjauvin requested a review from LukeTowers March 10, 2026 23:11
@LukeTowers

Copy link
Copy Markdown
Member

@mjauvin if it won't work under certain conditions can we detect that and throw a systemexception when an unsupported configuration is detected?

@LukeTowers

Copy link
Copy Markdown
Member

Given the changes to the Form widget getSaveData I'd really like to see some unit testing around that, do we have anything there right now or do we need to add coverage from scratch?

@mjauvin

mjauvin commented Mar 11, 2026

Copy link
Copy Markdown
Member Author

Given the changes to the Form widget getSaveData I'd really like to see some unit testing around that, do we have anything there right now or do we need to add coverage from scratch?

It doesn't change Form's getSaveData(), it adds a specific case for the FieldSet widget if present. Current behavior is not changed if no FieldSet is used.

@mjauvin

mjauvin commented Mar 11, 2026

Copy link
Copy Markdown
Member Author

@mjauvin if it won't work under certain conditions can we detect that and throw a systemexception when an unsupported configuration is detected?

Not sure it's worth processing all fields recursively to find potential issues down below...

@LukeTowers

Copy link
Copy Markdown
Member

@mjauvin wouldn't all those fields have to be processed recursively anyways? What specific conditions cause the issue that you were talking about and what is the impact of that issue? Perhaps I didn't understand you fully the first time

@mjauvin

mjauvin commented Mar 13, 2026

Copy link
Copy Markdown
Member Author

There is no more issues, they were resolved by calling widget's getSaveValue() when going through the FieldSets' internal fields (see below):

            if ($widget instanceof FieldSet) {
                foreach ($widget->getFormFields() as $field) {
                    $parts = HtmlHelper::nameToArray($field->fieldName);
                    if (($value = $this->dataArrayGet($data, $parts)) !== null) {
                        switch ($field->type) {
                            case 'number':
                                $value = !strlen(trim($value)) ? null : (float) $value;
                                break;
                            case 'widget':
                                $value = $widget->getFormWidget($field->fieldName)->getSaveValue($value);
                                break;
                        }
                        $this->dataArraySet($result, $parts, $value);
                    }
                }
                continue;
            }

The only remaining "gap" is if og of those widgets itself has widgets, but the FieldSet shouldn't be used for deeply nested fields anyway.

@mjauvin mjauvin modified the milestones: 1.3.0, 1.2.13 Mar 13, 2026
@LukeTowers LukeTowers modified the milestones: 1.2.13, 1.3.0 Jun 10, 2026
@mjauvin

mjauvin commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

@LukeTowers anything preventing this to get merged?

@LukeTowers

Copy link
Copy Markdown
Member

@mjauvin if it only supports fields under form then we should just perform that merge ourselves so that the definition only provides fields.* instead of form.fields.*. If you can make that change to the code and docs then I should be able to review and merge.

@mjauvin

mjauvin commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

@mjauvin if it only supports fields under form then we should just perform that merge ourselves so that the definition only provides fields.* instead of form.fields.*. If you can make that change to the code and docs then I should be able to review and merge.

Why would it be different than with the nestedform widget?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement PRs that implement a new feature or substantial change needs review Issues/PRs that require a review from a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants