anacona16/dependent-forms-bundle
composer require anacona16/dependent-forms-bundle
config/bundles.php:
Anacona16\Bundle\DependentFormsBundle\DependentFormsBundle::class => ['all' => true],
config/routes/dependent_forms.yaml:
anacona16_dependent_forms:
resource: '@DependentFormsBundle/Resources/config/routing.xml'
config/packages/twig.yaml:
twig:
form_themes:
- '@DependentForms/Form/fields.html.twig'
php bin/console assets:install --symlink
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
Create a form with dependent fields (e.g., country → state/city):
use Anacona16\Bundle\DependentFormsBundle\Form\Type\DependentType;
$builder->add('country', EntityType::class, [
'class' => Country::class,
'choices' => $countries,
]);
$builder->add('state', DependentType::class, [
'dependent_field' => 'country',
'dependent_field_options' => [
'class' => State::class,
'query_builder' => function (EntityRepository $er, $countryId) {
return $er->createQueryBuilder('s')
->where('s.country = :country')
->setParameter('country', $countryId);
},
],
]);
Dynamic Field Population
Use DependentType for fields that depend on another field's value (e.g., dropdowns, selects).
$builder->add('city', DependentType::class, [
'dependent_field' => 'state',
'dependent_field_options' => [
'class' => City::class,
'query_builder' => function (EntityRepository $er, $stateId) {
return $er->createQueryBuilder('c')
->where('c.state = :state')
->setParameter('state', $stateId);
},
],
]);
Custom Query Logic
Override query_builder to fetch data dynamically:
'query_builder' => function (EntityRepository $er, $parentValue) {
return $er->createQueryBuilder('e')
->where('e.parent = :parent')
->andWhere('e.is_active = :active')
->setParameter('parent', $parentValue)
->setParameter('active', true);
},
Non-Entity Dependencies
Use choices instead of class for non-DOCTRINE entities:
'dependent_field_options' => [
'choices' => $this->getDynamicChoices($parentValue),
],
Chaining Dependencies Nested dependencies (e.g., country → state → city):
$builder->add('country', EntityType::class, [...]);
$builder->add('state', DependentType::class, [
'dependent_field' => 'country',
// ...
]);
$builder->add('city', DependentType::class, [
'dependent_field' => 'state',
// ...
]);
Form Events for Pre-Fetching
Use PRE_SET_DATA to pre-load dependent fields:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
if ($data && $data->getCountry()) {
$form->get('state')->setData($data->getState());
}
});
jQuery Dependency
Circular Dependencies
A depends on B, B depends on A). The bundle does not handle this natively.Query Builder Pitfalls
query_builder returns no results, the dependent field will not update.query_builder always returns a valid QueryBuilder, even if empty:
return $er->createQueryBuilder('e')
->where('1=1') // Fallback to all records if no filter
->setParameter('parent', $parentValue);
Symfony 5+ Compatibility
FormTypeExtension) may need adjustments.Caching Issues
php bin/console cache:clear
CSRF Token Conflicts
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
Check Network Requests
F12) and verify AJAX requests are firing when changing the parent field.Log Query Builders
query_builder logic by logging the generated SQL:
$queryBuilder = $er->createQueryBuilder('e')
->where('e.parent = :parent')
->setParameter('parent', $parentValue);
\Log::debug($queryBuilder->getQuery()->getSQL());
Disable JavaScript Temporarily
Verify Twig Theme
@DependentForms/Form/fields.html.twig is loaded. Override it if needed:
twig:
form_themes:
- 'bundles/yourbundle/form/fields.html.twig'
Custom Templates Override the Twig template to modify rendering:
{% extends '@DependentForms/Form/fields.html.twig' %}
{% block dependent_field_widget %}
{{ parent() }} <!-- Customize here -->
{% endblock %}
Event Listeners Extend functionality with form events:
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
// Custom logic
});
Ajax Customization Override the bundle’s JavaScript behavior by extending its assets:
// public/js/dependent-forms.js
$(document).on('change', '.dependent-field', function() {
// Custom AJAX logic
});
Then include it after jQuery:
<script src="{{ asset('js/dependent-forms.js') }}"></script>
How can I help you explore Laravel packages today?