Smart Form Controls

Ajax-Powered Autocomplete <select>

Breathe life into EntityType and ChoiceType fields with Tom Select and a sprinkle of Ajax.

composer require symfony/ux-autocomplete

What Autocomplete gives you

  • Search as you type

    Query the server without leaving the form.

  • A real form type

    Drop it into any Symfony form.

  • Doctrine aware

    Point it at an entity and it queries for you.

  • Create on the fly

    Let users add a value that does not exist yet.

  • Multiple selection

    Tags, grouping and dependent fields.

Ajax-powered Form Select

Add Autocomplete to your app.

Ajax-powered, auto-completable select elements

src/Form/TimeForAMealForm.php
// ... use statements hidden - click to show
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;

/**
 * @extends AbstractType<array<string, mixed>>
 */
class TimeForAMealForm extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('foods', FoodAutocompleteField::class)
            ->add('name', TextType::class, [
                'label' => 'What should we call this meal?',
            ])
        ;
    }
}
// ... use statements hidden - click to show
use App\Entity\Food;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Count;
use Symfony\UX\Autocomplete\Form\AsEntityAutocompleteField;
use Symfony\UX\Autocomplete\Form\BaseEntityAutocompleteType;

/**
 * @extends AbstractType<Collection<int, Food>>
 */
#[AsEntityAutocompleteField]
class FoodAutocompleteField extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'class' => Food::class,
            'searchable_fields' => ['name'],
            'label' => 'What sounds tasty?',
            'choice_label' => 'name',
            'multiple' => true,
            'constraints' => [
                new Count(min: 1, minMessage: 'We need to eat *something*'),
            ],
            // 'security' => 'ROLE_SOMETHING',
        ]);
    }

    public function getParent(): string
    {
        return BaseEntityAutocompleteType::class;
    }
}
Symfony logo

UX Autocomplete

From a select to a search field

Where the options come from.

A plain select ships every row to the browser. Autocomplete keeps them on the server and fetches only what the visitor is looking for.

One option to switch it on

Add autocomplete to an existing EntityType or ChoiceType and the field becomes searchable.

$builder->add('food', EntityType::class, [
    'class' => Food::class,
    'autocomplete' => true,
]);

Its own endpoint

The attribute registers a dedicated controller, so the browser queries the database instead of downloading it.

#[AsEntityAutocompleteField]
class FoodField extends AbstractType
{
    public function configureOptions(
        OptionsResolver $resolver,
    ): void {
        $resolver->setDefaults([
            'class' => Food::class,
        ]);
    }
}

Values that do not exist yet

allow_options_create lets a visitor type something new. Your code decides whether to persist it.

$resolver->setDefaults([
    'class' => Food::class,
    'allow_options_create' => true,
]);

Install Autocomplete.

$ composer require symfony/ux-autocomplete

More from Symfony UX.

Autocomplete is one package among many. They share the same Stimulus foundation and install the same way.

Image for the Native UX package

Native

Build native mobile apps that wrap your Symfony web application

Image for the Pagination UX package

Pagination New

Paginate any data with numbered pages, lookahead, or cursors.

Image for the Translator UX package

Translator

Use Symfony's translations in JavaScript

Browse every package

Keep Autocomplete at hand.

Documentation, the people behind it, and where to ask when something does not behave.