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

Ux Autocomplete Laravel Package

symfony/ux-autocomplete

JavaScript-powered autocomplete for Symfony forms. Enhances select and entity fields with search-as-you-type suggestions, async loading, and a smooth UX. Part of Symfony UX; docs and issues live in the main symfony/ux repository.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require symfony/ux-autocomplete
    npm install @symfony/ux-autocomplete
    
  2. Enable the bundle in config/bundles.php:
    return [
        // ...
        Symfony\UX\AutocompleteBundle\AutocompleteBundle::class => ['all' => true],
    ];
    
  3. Import Stimulus controllers in assets/app.js:
    import './controllers/autocomplete_controller';
    
  4. Use in a form type (e.g., UserAutocompleteType):
    use Symfony\UX\Autocomplete\Attribute\AsEntityAutocompleteField;
    
    #[AsEntityAutocompleteField]
    class UserAutocompleteType extends AbstractType {
        public function configureOptions(OptionsResolver $resolver): void {
            $resolver->setDefaults([
                'class' => User::class,
                'choice_label' => 'email', // Field to display
            ]);
        }
    }
    
  5. Create a route for AJAX requests (e.g., config/routes/autocomplete.yaml):
    autocomplete_user:
        path: /api/user-autocomplete
        controller: App\Controller\AutocompleteController::searchUsers
        methods: GET
    
  6. Controller for AJAX endpoint:
    #[Route('/api/user-autocomplete', name: 'autocomplete_user')]
    public function searchUsers(Request $request, EntityManagerInterface $em): Response {
        return $this->json(
            $this->getAutocompleteResults($request->query->get('query'), $em)
        );
    }
    

First Use Case: Entity Search

Replace a standard EntityType field with AsEntityAutocompleteField for a seamless search experience:

$builder->add('user', UserAutocompleteType::class, [
    'label' => 'Search Users',
    'min_characters' => 2, // Trigger search after 2 chars
    'max_results' => 10,   // Limit dropdown items
]);

Implementation Patterns

1. Entity Autocomplete (Most Common)

  • Pattern: Use AsEntityAutocompleteField for Doctrine entities.
  • Workflow:
    1. Define a form type with #[AsEntityAutocompleteField].
    2. Implement a controller to return JSON results (e.g., findBy query).
    3. Customize with options like choice_label, choice_value, or getAttributes().
  • Example:
    #[AsEntityAutocompleteField]
    class ProductAutocompleteType extends AbstractType {
        public function configureOptions(OptionsResolver $resolver): void {
            $resolver->setDefaults([
                'class' => Product::class,
                'choice_label' => 'name',
                'choice_value' => 'id',
                'get_attributes' => function (?Product $product) {
                    return ['data-price' => $product->getPrice()];
                },
            ]);
        }
    }
    

2. Remote Data Autocomplete

  • Pattern: Use AsAutocompleteField for non-entity data (e.g., API responses).
  • Workflow:
    1. Define a form type with #[AsAutocompleteField].
    2. Point to a custom route that returns JSON (e.g., from an external API).
    3. Configure tom_select_options for UI customization.
  • Example:
    #[AsAutocompleteField(route: 'api_search_products')]
    class RemoteProductAutocompleteType extends AbstractType {
        public function configureOptions(OptionsResolver $resolver): void {
            $resolver->setDefaults([
                'route' => 'api_search_products',
                'tom_select_options' => [
                    'plugins' => ['remove_button'],
                    'placeholder' => 'Search products...',
                ],
            ]);
        }
    }
    

3. LiveComponent Integration

  • Pattern: Use autocomplete inside a LiveComponent for dynamic forms.
  • Key Tips:
    • Ensure disabled or option changes trigger updates (works out-of-the-box since v2.8).
    • Use reset_on_focus to clear stale data:
      $resolver->setDefaults([
          'reset_on_focus' => true,
      ]);
      
  • Example:
    #[AsEntityAutocompleteField]
    class DynamicUserAutocompleteType extends AbstractType {
        public function configureOptions(OptionsResolver $resolver): void {
            $resolver->setDefaults([
                'class' => User::class,
                'reset_on_focus' => true, // Critical for LiveComponents
            ]);
        }
    }
    

4. Pagination and Performance

  • Pattern: Use max_results + automatic pagination for large datasets.
  • Workflow:
    1. Set max_results (e.g., 10).
    2. Implement server-side pagination in your controller (e.g., Doctrine\ORM\QueryBuilder with setMaxResults).
    3. Return a loading_more_text option for UX feedback:
    $resolver->setDefaults([
        'max_results' => 10,
        'tom_select_options' => [
            'loading_more_text' => 'Loading more...',
        ],
    ]);
    

5. Custom Attributes and Option Groups

  • Pattern: Extend autocomplete with custom data or group options.
  • Example:
    #[AsEntityAutocompleteField]
    class CategoryAutocompleteType extends AbstractType {
        public function configureOptions(OptionsResolver $resolver): void {
            $resolver->setDefaults([
                'class' => Category::class,
                'get_attributes' => function (?Category $category) {
                    return ['data-color' => $category->getColor()];
                },
                'tom_select_options' => [
                    'option_group_field' => 'parent', // For nested categories
                    'option_group_label' => 'name',
                ],
            ]);
        }
    }
    

6. Security and Validation

  • Pattern: Leverage Symfony’s validation and security systems.
  • Key Points:
    • Use choice_loader for custom validation (e.g., LazyChoiceLoader).
    • Escape HTML in responses to prevent XSS (default since v2.36):
      $resolver->setDefaults([
          'options_as_html' => false, // Default (safe)
      ]);
      
    • For HTML content (e.g., rich text), opt in:
      $resolver->setDefaults([
          'options_as_html' => true,
      ]);
      

Gotchas and Tips

Common Pitfalls

  1. Route Configuration:

    • Gotcha: Forgetting to update the route path after v2.6.0 (from Resources/routes.php to config/routes.php).
    • Fix: Verify your ux_autocomplete route in config/routes/ux_autocomplete.yaml.
  2. PHP/Symfony Version Mismatch:

    • Gotcha: Using v3.x with Symfony <7.4 or PHP <8.4 will fail.
    • Fix: Pin to v2.x if upgrading:
      composer require symfony/ux-autocomplete:^2.35
      
  3. Stimulus Controller Not Loaded:

    • Gotcha: Autocomplete not working because autocomplete_controller.js isn’t imported.
    • Fix: Ensure assets/app.js includes:
      import './controllers/autocomplete_controller';
      
  4. Case-Sensitive IDs:

    • Gotcha: UUIDs or custom IDs may fail if not handled properly.
    • Fix: Use choice_value to specify the exact field:
      $resolver->setDefaults([
          'choice_value' => 'uuid', // Instead of 'id'
      ]);
      
  5. LiveComponent Stale Data:

    • Gotcha: Autocomplete not resetting in LiveComponents.
    • Fix: Add reset_on_focus:
      $resolver->setDefaults([
          'reset_on_focus' => true,
      ]);
      
  6. XSS Vulnerabilities:

    • Gotcha: Unescaped HTML in autocomplete responses (pre-v2.36).
    • Fix: Set options_as_html explicitly if needed:
      $resolver->setDefaults([
          'options_as_html' => true, // Only if intentional
      ]);
      
  7. TomSelect Plugins Not Working:

    • Gotcha: Custom plugins (e.g., clear_button) not applying.
    • Fix: Disable default plugins explicitly:
      $resolver->setDefaults([
          'tom_select_options' => [
              'plugins' => [
                  'clear_button' => false,
              ],
          ],
      ]);
      

Debugging Tips

  1. Check AJAX Requests:
    • Use browser dev tools (Network tab) to verify:
      • The endpoint is hit.
      • JSON response matches expected format (e.g., [{text: "...", value: 1}]).
    • **Common Issue
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor