brunops/select24entity-bundle
Installation:
composer require brunops/select24entity-bundle
Add to bundles.php:
Brunops\Select24EntityBundle\BrunopsSelect24EntityBundle::class => ['all' => true],
Enable AJAX Endpoint:
Configure a route for AJAX entity fetching (e.g., select2_ajax_entity):
# config/routes.yaml
select2_ajax_entity:
path: /ajax/entity/{entityClass}
defaults: { _controller: Brunops\Select24EntityBundle\Controller\Select2Controller::ajaxEntityAction }
First Use Case:
Replace a standard EntityType field in a form with Select2EntityType:
use Brunops\Select24EntityBundle\Form\Type\Select2EntityType;
$builder->add('user', Select2EntityType::class, [
'class' => User::class,
'ajax_route' => 'select2_ajax_entity',
'placeholder' => 'Select a user...',
]);
JavaScript Activation: Initialize Select2 manually in your JS (no auto-initialization):
$(document).ready(function() {
$('.select2').select2({
ajax: {
url: Routing.generate('select2_ajax_entity', { entityClass: 'App\Entity\User' }),
dataType: 'json',
delay: 250,
data: function(params) {
return {
q: params.term,
page: params.page
};
},
processResults: function(data) {
return {
results: $.map(data.items, function(item) {
return { text: item.name, id: item.id };
})
};
},
cache: true
},
minimumInputLength: 1,
});
});
Form Integration:
EntityType with Select2EntityType for AJAX-driven entity selection.ajax_route to point to your custom controller (default: select2_ajax_entity).multiple for many-to-many relationships (e.g., tags, roles).AJAX Controller Customization: Extend the default controller to filter entities dynamically:
// src/Controller/Select2Controller.php
namespace App\Controller;
use Brunops\Select24EntityBundle\Controller\Select2Controller as BaseController;
use App\Entity\User;
use Symfony\Component\HttpFoundation\Request;
class Select2Controller extends BaseController
{
public function ajaxEntityAction(Request $request, $entityClass)
{
$this->setEntityClass($entityClass);
$this->setSearchField('name'); // Override default search field
$this->setSearchMethod('contains'); // 'startsWith', 'contains', 'exact'
return parent::ajaxEntityAction($request, $entityClass);
}
}
Twig Integration: Render the field with Select2-ready classes:
{{ form_widget(form.user, { 'attr': {'class': 'select2'} }) }}
Dynamic Configuration:
Pass options to Select2EntityType for runtime flexibility:
$builder->add('tags', Select2EntityType::class, [
'class' => Tag::class,
'ajax_route' => 'select2_ajax_entity',
'multiple' => true,
'placeholder' => 'Add tags...',
'attr' => ['data-minimum-input-length' => 2],
]);
Event Listeners: Attach listeners to modify AJAX responses or form behavior:
// src/EventListener/Select2EntityListener.php
use Brunops\Select24EntityBundle\Event\Select2EntityEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class Select2EntityListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
Select2EntityEvent::PRE_AJAX => 'onPreAjax',
];
}
public function onPreAjax(Select2EntityEvent $event)
{
$query = $event->getQuery();
$query->andWhere('u.enabled = :enabled')->setParameter('enabled', true);
}
}
No Auto-Initialization:
.select2() in JavaScript.$(document).ready() or use event delegation for dynamic forms.Route Configuration:
ajax_route (select2_ajax_entity) must match your route name exactly.php bin/console debug:router and adjust ajax_route in the form type.Entity Class Naming:
entityClass parameter in the AJAX route must be a fully qualified class name (e.g., App\Entity\User).get_class($entity) or hardcode the FQCN in the route.Pagination Limits:
$query->setMaxResults(10)->setFirstResult(($request->query->getInt('page') - 1) * 10);
CORS Issues:
Form Theme Overrides:
select24entity block:
{# templates/select24entity.html.twig #}
<div class="select2-container {{ id }}">
{{ form_widget(form, {'attr': {'class': 'select2'}}) }}
</div>
Check AJAX Responses:
F12) to verify payloads and responses.{
"items": [
{"id": 1, "text": "User 1", "name": "User 1"},
{"id": 2, "text": "User 2", "name": "User 2"}
]
}
Log Queries:
# config/packages/dev/doctrine.yaml
doctrine:
dbal:
logging: true
profiling: true
Clear Cache:
php bin/console cache:clear
Custom Data Transformers:
$builder->add('user', Select2EntityType::class, [
'class' => User::class,
'ajax_route' => 'select2_ajax_entity',
'transformer' => function ($entity) {
return [
'id' => $entity->getId(),
'text' => $entity->getFullName(),
'email' => $entity->getEmail(),
];
},
]);
Custom Templates:
{# templates/brunops_select24entity/select2_entity_widget.html.twig #}
<div class="custom-select2-wrapper">
{{ form_widget(form, {'attr': {'class': 'select2-custom'}}) }}
</div>
Event Dispatching:
Select2EntityEvent::PRE_AJAX: Modify the query before execution.Select2EntityEvent::POST_AJAX: Alter the response data.Select2EntityEvent::PRE_SET_DATA: Transform form data before binding.Dependency Injection:
use App\Service\CustomEntityService;
class Select2Controller extends BaseController
{
public function __construct(private CustomEntityService $entityService) {}
public function ajaxEntityAction(Request $request, $entityClass)
{
$this->setEntityClass($entityClass);
$this->setSearchField($this->entityService->getSearchField($entityClass));
// ...
}
}
Lazy Loading:
public function ajaxEntityAction(Request $request, $entityClass)
{
$this->setEntityClass($entityClass);
$query = $this->get
How can I help you explore Laravel packages today?