burgov/key-value-form-bundle
Installation:
composer require burgov/key-value-form-bundle
Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3):
return [
// ...
Burgov\Bundle\KeyValueFormBundle\BurgovKeyValueFormBundle::class => ['all' => true],
];
First Use Case:
Add KeyValueType to a form builder in a controller or service:
use Burgov\Bundle\KeyValueFormBundle\Form\Type\KeyValueType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
$builder->add('config', KeyValueType::class, [
'value_type' => TextType::class,
'label' => 'Configuration Settings',
]);
Template Rendering:
Use Symfony’s collection rendering (e.g., prototype for dynamic fields):
{{ form_row(form.config) }}
For dynamic fields, include the prototype template (see Symfony Collection Docs).
Basic Key-Value Storage:
Use KeyValueType for editable key-value pairs (e.g., user preferences, API configs):
$builder->add('metadata', KeyValueType::class, [
'value_type' => TextType::class,
'value_options' => ['attr' => ['class' => 'metadata-value']],
]);
Custom Key/Value Types:
Override default types (e.g., EmailType for keys, NumberType for values):
$builder->add('settings', KeyValueType::class, [
'key_type' => EmailType::class,
'value_type' => NumberType::class,
]);
Data Transformation:
Bind to an array or object with getData()/setData():
$form->getData(); // Returns ['key1' => 'value1', 'key2' => 'value2']
Validation:
Add constraints to the root form or via value_options:
$builder->add('tags', KeyValueType::class, [
'value_type' => TextType::class,
'value_options' => [
'constraints' => [new Length(['max' => 50])],
],
]);
Dynamic Fields:
Use allow_add/allow_delete for interactive forms:
$builder->add('dynamic_data', KeyValueType::class, [
'value_type' => TextType::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true, // Enable prototype template
]);
key_value_row.html.twig) for custom styling.JsonResponse/JsonRequest.config table with settings column).Missing value_type:
Required option—omit it, and the form will fail silently or throw an exception.
// ❌ Fails
$builder->add('bad_form', KeyValueType::class);
Prototype Template: Forgetting to include the prototype template breaks dynamic field addition. Ensure:
{% include 'BurgovKeyValueFormBundle:Form:key_value_row.html.twig' %}
Data Binding: Keys/values must be strings or castable to strings. Non-string keys (e.g., objects) will break rendering.
CSRF in Dynamic Forms:
Dynamic fields require CSRF tokens. Use Symfony’s form_row with prototype:
{{ form_row(form.dynamic_data, {'prototype': true}) }}
Validation Scope:
Constraints in value_options apply to individual values, not the entire collection. Use root form constraints for global rules.
{{ form_errors(form) }} in Twig or dump($form->getErrors()) in PHP.var_dump($form->getData()) to verify key-value binding.php bin/console cache:clear) if templates render incorrectly.key_value_row.html.twig in templates/Bundles/BurgovKeyValueFormBundle/Form/.PRE_SET_DATA/POST_SUBMIT for preprocessing/postprocessing:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$data = $event->getData() ?: [];
$data['default_key'] = 'default_value';
$event->setData($data);
});
FormEvents::SUBMIT to transform data before submission:
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
$data = $event->getData();
$data = array_map('strtoupper', $data); // Example: uppercase keys
$event->setData($data);
});
key_type defaults to TextType, but value_type must be specified.allowed_key... options (likely a typo for allowed_keys). Use:
$builder->add('restricted', KeyValueType::class, [
'value_type' => TextType::class,
'allowed_keys' => ['admin', 'user'], // Only allow these keys
]);
null/empty values in PRE_SET_DATA to avoid validation errors.How can I help you explore Laravel packages today?