armetiz/form-extension-bundle
Installation:
composer require armetiz/form-extension-bundle:1.x-dev
Enable the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 2/3):
Armetiz\FormExtensionBundle\ArmetizFormExtensionBundle::class => ['all' => true],
First Use Case:
Replace a standard entity field with entity_ajax in your form type:
$builder->add('owner', EntityAjaxType::class, [
'class' => User::class,
'property' => 'username',
'choice_label' => 'username',
]);
Frontend Integration: Pair with Chosen or Ajax Chosen for dynamic loading. Example:
{{ form_widget(form.owner, {'attr': {'data-url': path('app_user_search')}}) }}
Lazy-Loading Entities:
entity_ajax for related entities (e.g., Book.owner) to avoid loading all records upfront.User → Post).owner of a Book in the form, then fetch additional users via AJAX.Integration with Frontend Libraries:
/search/users).// src/Controller/UserSearchController.php
public function searchAction(Request $request): Response
{
$query = $request->query->get('term');
$users = $this->getDoctrine()->getRepository(User::class)
->createQueryBuilder('u')
->where('u.username LIKE :query')
->setParameter('query', "%$query%")
->getQuery()
->getResult();
return $this->render('ArmetizFormExtensionBundle:User:search.xml.twig', [
'users' => $users,
]);
}
Form Type Configuration:
EntityType options (e.g., choice_label, query_builder).ajax_route to specify the search endpoint:
$builder->add('owner', EntityAjaxType::class, [
'class' => User::class,
'ajax_route' => 'app_user_search',
]);
Validation and Submission:
entity_ajax submits data identically to entity.if ($form->isSubmitted() && $form->isValid()) {
$book->setOwner($form->get('owner')->getData());
$em->persist($book);
}
Frontend Dependency:
Route Configuration:
<item> tags, but JSON is also viable with adjustments to the frontend JS.{
"results": [
{"id": 1, "text": "John Doe"},
{"id": 2, "text": "Jane Smith"}
]
}
Caching:
query_builder, cache the DQL query to avoid performance issues with repeated AJAX calls.$builder->add('owner', EntityAjaxType::class, [
'query_builder' => function (EntityManagerInterface $em) {
return $em->getRepository(User::class)
->createQueryBuilder('u')
->where('u.active = :active')
->setParameter('active', true);
},
]);
Symfony Version Compatibility:
createFormBuilder → createForm in Symfony 4+).Debugging AJAX Responses:
// src/Controller/DebugController.php
public function debugSearchAction(): Response
{
return $this->render('ArmetizFormExtensionBundle:User:search.xml.twig', [
'users' => $this->getDoctrine()->getRepository(User::class)->findAll(),
]);
}
Extending the Bundle:
EntityAjaxType class to add custom behavior (e.g., default query parameters):
// src/Form/Extension/EntityAjaxTypeExtension.php
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Armetiz\FormExtensionBundle\Form\Type\EntityAjaxType;
class CustomEntityAjaxTypeExtension extends EntityAjaxType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'default_query' => 'active_users',
]);
}
}
services.yaml:
services:
App\Form\Extension\CustomEntityAjaxTypeExtension:
tags: [form.type_extension, { extended_type: 'entity_ajax', extension_type: 'form' }]
Performance:
->setMaxResults(20)
Accessibility:
$(selector).chosen({
search_contains: true,
no_results_text: 'No users found',
disable_search_threshold: 3,
width: '100%'
});
How can I help you explore Laravel packages today?