Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Select Autocompleter Bundle Laravel Package

danilovl/select-autocompleter-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require danilovl/select-autocompleter-bundle
    

    Register the bundle in config/bundles.php:

    Danilovl\SelectAutocompleterBundle\SelectAutocompleterBundle::class => ['all' => true],
    
  2. Basic Configuration: Add to config/packages/danilovl_select_autocompleter.yaml:

    danilovl_select_autocompleter:
        select2:
            theme: "bootstrap4" # or 'bootstrap5', 'classic', 'bootstrap4-dark'
            width: "100%"
            placeholder: "Search..."
    
  3. First Use Case: Create a form type extending AbstractAutocompleterType:

    use Danilovl\SelectAutocompleterBundle\Form\Type\AbstractAutocompleterType;
    
    class UserAutocompleteType extends AbstractAutocompleterType
    {
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults([
                'class' => User::class,
                'choice_label' => 'fullName',
                'ajax_route' => 'user_autocomplete',
                'min_input_length' => 2,
            ]);
        }
    }
    
  4. Route for Autocomplete: Define a route in config/routes.yaml:

    user_autocomplete:
        path: /api/users/autocomplete
        controller: App\Controller\UserAutocompleteController::class
        methods: GET
    

    Controller:

    use Danilovl\SelectAutocompleterBundle\Controller\AutocompleteControllerTrait;
    
    class UserAutocompleteController extends AbstractController
    {
        use AutocompleteControllerTrait;
    
        public function __invoke(Request $request, UserRepository $userRepository)
        {
            return $this->handleAutocomplete($request, $userRepository, 'fullName');
        }
    }
    
  5. Use in Form:

    $builder->add('user', UserAutocompleteType::class);
    

Implementation Patterns

Common Workflows

1. Basic Integration with Existing Forms

Replace standard EntityType with AbstractAutocompleterType:

// Before
$builder->add('user', EntityType::class, ['class' => User::class]);

// After
$builder->add('user', UserAutocompleteType::class);

2. Customizing Autocomplete Behavior

Override default options in configureOptions:

$resolver->setDefaults([
    'ajax_route' => 'custom_route',
    'min_input_length' => 1,
    'multiple' => true,
    'allow_clear' => true,
    'select2_options' => [
        'ajax' => [
            'dataType' => 'json',
            'delay' => 250,
        ],
    ],
]);

3. Dynamic Route Parameters

Pass dynamic parameters via ajax_route_parameters:

$resolver->setDefaults([
    'ajax_route' => 'department_autocomplete',
    'ajax_route_parameters' => ['company_id' => $companyId],
]);

4. Handling Complex Data Structures

Customize the response format in the controller:

public function __invoke(Request $request, ProductRepository $productRepository)
{
    $results = $productRepository->findByName($request->query->get('term'));

    return $this->json(array_map(function ($product) {
        return [
            'id' => $product->getId(),
            'text' => $product->getName(),
            'price' => $product->getPrice(),
        ];
    }, $results));
}

Update the form type to handle custom fields:

$resolver->setDefaults([
    'template' => '@DanilovlSelectAutocompleter/autocompleter_widget.html.twig',
    'select2_options' => [
        'templateResult' => 'customTemplate',
        'templateSelection' => 'customTemplate',
    ],
]);

Add custom Twig templates (e.g., templates/custom_autocomplete.html.twig):

{# templates/custom_autocomplete.html.twig #}
<div class="custom-autocomplete">
    {{ form_widget(form) }}
    <span class="price">{{ data.price }}</span>
</div>

5. Integration with API Platform

Use the bundle with API Platform entities:

$resolver->setDefaults([
    'class' => Product::class,
    'ajax_route' => 'api_products',
    'ajax_route_parameters' => [],
    'choice_label' => 'name',
    'api_platform' => true, // Enable API Platform integration
]);

6. Lazy Loading with Pagination

Implement pagination in the autocomplete controller:

public function __invoke(Request $request, UserRepository $userRepository)
{
    $page = $request->query->getInt('page', 1);
    $limit = 10;
    $users = $userRepository->findByNamePaginated(
        $request->query->get('term'),
        $page,
        $limit
    );

    $data = array_map(function ($user) {
        return ['id' => $user->getId(), 'text' => $user->getFullName()];
    }, $users);

    return $this->json([
        'results' => $data,
        'pagination' => [
            'page' => $page,
            'last_page' => ceil($users->getTotalItems() / $limit),
        ],
    ]);
}

Update the form type to handle pagination:

$resolver->setDefaults([
    'select2_options' => [
        'ajax' => [
            'data' => function ($params) {
                return [
                    'term' => $params['term'],
                    'page' => $params['page'] ?? 1,
                ];
            },
            'processResults' => function ($data) {
                return [
                    'results' => $data['results'],
                    'pagination' => [
                        'more' => $data['pagination']['page'] < $data['pagination']['last_page'],
                    ],
                ];
            },
        ],
    ],
]);

Integration Tips

1. Symfony UX Turbo/Stimulus

Combine with Symfony UX for enhanced interactivity:

// assets/controllers/autocomplete_controller.js
import { Controller } from '@hotwired/stimulus';

export default class extends Controller {
    connect() {
        this.element.addEventListener('change', (event) => {
            // Handle selection changes
        });
    }
}

Update Twig template:

{{ form_widget(form) }}
{{ stimulus_controller('autocomplete', {'value': form.vars.value|default('')}) }}

2. Form Events

Listen to form events for dynamic updates:

$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
    $form = $event->getForm();
    $data = $event->getData();

    if ($data) {
        $form->add('custom_field', TextType::class, [
            'data' => $data->getCustomField(),
        ]);
    }
});

3. Validation and Error Handling

Customize error messages:

$resolver->setDefaults([
    'error_bubbling' => true,
    'constraints' => [
        new NotBlank(),
        new Callback([$this, 'validateUser']),
    ],
]);

public function validateUser($value, ExecutionContextInterface $context)
{
    if ($value && !$value->isActive()) {
        $context->buildViolation('User is inactive.')
            ->atPath('user')
            ->addViolation();
    }
}

4. Server-Side Processing

Offload heavy processing to the server:

$resolver->setDefaults([
    'ajax_route' => 'user_autocomplete_processed',
    'select2_options' => [
        'ajax' => [
            'beforeSend' => function ($jqXHR, settings) {
                settings.data.push({ name: 'process', value: 'heavy' });
            },
        ],
    ],
]);

Gotchas and Tips

Pitfalls

1. CORS Issues

  • Problem: Autocomplete requests may fail due to CORS if the API and frontend are on different domains.
  • Solution: Configure CORS in Symfony:
    # config/packages/nelmio_cors.yaml
    nelmio_cors:
        defaults:
            allow_origin: ['*']
            allow_methods: ['GET', 'POST']
            allow_headers: ['Content-Type']
            expose_headers: []
            max_age: 3600
            hosts: []
            origin_regex: false
    
    Install NelmioCors
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nasirkhan/laravel-sharekit
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony