adamquaile/symfony-fieldset-bundle
Adds a FieldsetType to Symfony Forms so you can group fields with a and custom legend. Define fields via a builder callback or a simple array, keeping form structure tidy and reusable.
Installation:
composer require adamquaile/symfony-fieldset-bundle
Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3):
AdamQuaile\Bundle\FieldsetBundle\AdamQuaileFieldsetBundle::class => ['all' => true],
First Use Case: Create a form type and add a fieldset with a callback:
use AdamQuaile\Bundle\FieldsetBundle\Form\Type\FieldsetType;
class MyFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('address', FieldsetType::class, [
'legend' => 'Contact Information',
'fields' => function(FormBuilderInterface $builder) {
$builder->add('street', TextType::class);
$builder->add('city', TextType::class);
}
]);
}
}
FormBuilderInterface since fieldsets extend it.Nested Fieldsets: Fieldsets can contain other fieldsets for hierarchical forms:
$builder->add('profile', FieldsetType::class, [
'fields' => function($builder) {
$builder->add('personal', FieldsetType::class, [
'fields' => function($builder) {
$builder->add('name', TextType::class);
}
]);
}
]);
Dynamic Fields: Use closures to conditionally add fields based on runtime logic:
'fields' => function(FormBuilderInterface $builder) use ($user) {
if ($user->isAdmin()) {
$builder->add('admin_options', FieldsetType::class);
}
}
Reusable Fieldsets: Extract fieldset definitions into separate form types for DRY code:
class AddressFieldsetType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('street', TextType::class);
$builder->add('city', TextType::class);
}
}
Then reuse:
$builder->add('address', AddressFieldsetType::class);
Array-Based Fields: For static configurations, use the array syntax:
'fields' => [
['name' => 'email', 'type' => EmailType::class],
['name' => 'phone', 'type' => TelType::class],
]
$builder->add('billing', FieldsetType::class, [
'validation_groups' => ['billing'],
]);
AdamQuaileFieldsetBundle:Form:fieldset.html.twig).Label Conflicts:
Set 'label' => false to avoid duplicate labels when using legend. The bundle doesn’t automatically suppress parent labels.
CSRF Mismatches:
Nested fieldsets in AJAX-loaded forms may trigger CSRF errors. Use 'csrf_protection' => false sparingly (only for non-submittable fieldsets).
Deprecated Symfony: The bundle was last updated in 2017 for Symfony 2/3. Test thoroughly in newer versions (e.g., Symfony 5+ may require adjustments for form theme changes).
Field Naming Collisions:
Ensure field names (e.g., first_name) are unique across nested fieldsets to avoid array key conflicts in submitted data.
$form->createView();
dump($form->createView()->children);
errors property:
$form->get('fieldset_name')->getErrors();
Custom Fieldset Types:
Extend FieldsetType to add logic (e.g., auto-populating fields):
class CustomFieldsetType extends FieldsetType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'custom_option' => true,
]);
}
}
Event Subscribers:
Listen to PRE_SET_DATA or PRE_SUBMIT events to modify fieldsets dynamically:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
$data = $event->getData();
if ($data->isPremium()) {
$event->getForm()->add('premium_fields', FieldsetType::class);
}
});
Twig Extensions: Create custom Twig filters to render fieldsets conditionally:
{% if user.can_edit %}
{{ form_row(form.address) }}
{% endif %}
twig:form_themes in config/packages/twig.yaml includes:
form_themes: ['AdamQuaileFieldsetBundle:Form:fieldset.html.twig']
'legend' => 'address.details', // Key for translation
How can I help you explore Laravel packages today?