PHPackages                             acseo/select-autocomplete-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. acseo/select-autocomplete-bundle

ActiveSymfony-bundle[Database &amp; ORM](/categories/database)

acseo/select-autocomplete-bundle
================================

Make Symfony form autocompletion easily

2.1(5y ago)32.9k↓50%1MITPHPPHP ^7.2 || ^8.0

Since Jan 11Pushed 5y ago3 watchersCompare

[ Source](https://github.com/acseo/select-autocomplete-bundle)[ Packagist](https://packagist.org/packages/acseo/select-autocomplete-bundle)[ Docs](https://github.com/acseo/select-autocomplete-bundle)[ RSS](/packages/acseo-select-autocomplete-bundle/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (4)Dependencies (20)Versions (5)Used By (0)

ACSEO SELECT AUTOCOMPLETE BUNDLE
================================

[](#acseo-select-autocomplete-bundle)

[![Build Status](https://camo.githubusercontent.com/a2ae1726af8b6a2c73bcbf843804106db45a89da9d87e06c2f1907e8d4703d15/68747470733a2f2f7472617669732d63692e636f6d2f616373656f2f73656c6563742d6175746f636f6d706c6574652d62756e646c652e7376673f6272616e63683d6d6173746572)](https://travis-ci.com/acseo/select-autocomplete-bundle)

- Table of content
    ----------------

    [](#table-of-content)

    - [Introduction](#introduction)
    - [Installation](#installation)
    - [Usage](#usage)
    - [Form options](#form-options)
        - [class](#class)
        - [properties](#properties)
        - [display](#display)
        - [strategy](#strategy)
        - [multiple](#multiple)
        - [format](#format)
        - [identifier](#identifier)
        - [transformer](#transformer)
        - [autocomplete\_url](#autocomplete-url)
        - [provider](#provider)
    - [Providers](#providers)

Introduction
------------

[](#introduction)

This bundle helps you to build autocomplete fields in your symfony forms without declaring any controller or action.

Fully configurable, you can override any part of the autocompletion process very easily.

Doctrine **ORM** &amp; **ODM** are supported by default, but you can create your own providers for other extensions !

Installation
------------

[](#installation)

Install source code with composer :

```
$ composer require acseo/select-autocomplete-bundle
```

Enable the bundle :

```
// config/bundles.php

return [
    Acseo\SelectAutocomplete\SelectAutocompleteBundle::class => ['all' => true]
];
```

Use the bundle form theme globally (or locally in your templates) :

```
# config/packages/twig.yaml

twig:
    form_themes:
        - '@SelectAutocomplete/form_theme.html.twig'
```

Usage:
------

[](#usage)

Let's start by a simple example :

```
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\User;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => User::class,
        // The searchable properties used for query
        'properties' => ['profile.firstName', 'profile.lastName'],
    ])
;
```

With your favorite js library, transform the rendered input to autocomplete input (example with select2) :

```
$('.acseo-select-autocomplete').each((i, el) => {
    const $el = $(el);

    $el.select2({
        minimumInputLength: 1,
        ajax: {
            cache: false,
            url: $el.data('autocomplete-url'),        // Get autocomplete url to retrieve search responses
            delay: 250,
            dataType: 'json',
            data: params => ({
                q: params.term || '',                  // Append the search terms to url
                // response_format: 'json'             // (optional, json by default, see form type options for allowed values)
            }),
            processResults: data => ({                 // Transform entrypoint resuls
                results: Object.keys(data).map(value => ({
                    id: value,
                    text: data[value]
                }))
            })
        }
    });
});
```

Please note 3 important things in this js example :

- The rendered input has a `data-autocomplete-url` attribute and the value inside can be used to retrieve search results.
- The query param `q`, which represents the search terms, has to be added to data-autocomplete-url value.
- By default search results are returned by entrypoint like `[{ "value": "label" }]`.

Your autocomplete is now functional !

Form options
------------

[](#form-options)

NameTypeRequiredDefaultDescription[class](#class)stringyesnullThe model class supposed to be autocompleted[properties](#properties)string arraynoidThe properties used in database query to filter search results of autocomplete action. This properties can be nested with path like "nestedProperty.property".[display](#display)string callable arrayno[properties](#properties)The displayable properties used to build label of selectable choices. This properties can be nested with path like "nestedProperty.property".[strategy](#strategy)stringnocontainsThe strategy used to filter search results (allowed : starts\_with / ends\_with / contains / equals).[multiple](#multiple)boolnofalseIs collection field.[format](#format)string callablenojsonDefault format used to encode choices of autocomplete response. Values allowed are provided by your own serializer (basically json / xml / csv / yaml in symfony serializer). Use callable to override encoding process.[identifier](#identifier)stringnoidName of your model identifier property (will be used as value of each choice option).[autocomplete\_url](#autocomplete-url)stringnorequest.pathInfoThe entrypoint where autocomplete results can be retrieved. By default we use the route where the form has been built. This value will be set in attribute "data-autocomplete-url" of field input.[transformer](#transformer)boolean objectnoModelTransformerDisable/Override the form type transformer. If this value is false, transformer deals only with the identifier(s) value(s) (useful for filters).[provider](#provider)string callable array objectnonullCreate your own custom queries or specify a provider to use.**Tips** : You can also override any part of the process more globally by creating a class which extends AutocompleteType.

### class

[](#class)

```
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\TargetClass;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => TargetClass::class
    ])
;
```

### properties

[](#properties)

```
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\TargetClass;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => TargetClass::class,
        'properties' => 'targetProperty',
        // OR
        'properties' => ['name', 'profile.email'],
    ])
;
```

### display

[](#display)

```
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\TargetClass;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => TargetClass::class,

        'display' => 'targetPropertyOrMethod',
        // OR
        'display' => 'nestedProperty.targetProperty',
        // OR
        'display' => ['user.firstName', 'user.lastName'],
        // OR
        'display' => function(TargetClass $object): string {
            return $object->getTargetProperty();
        },
    ])
;
```

### strategy

[](#strategy)

```
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\TargetClass;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => TargetClass::class,

        'strategy' => 'starts_with', // LIKE ...%
        // OR
        'strategy' => 'ends_with',   // LIKE %...
        // OR
        'strategy' => 'contains',    // LIKE %...%
        // OR
        'strategy' => 'equals',      // = ...
    ])
;
```

### multiple

[](#multiple)

```
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\TargetClass;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => TargetClass::class,
        'multiple' => true,
    ])
;
```

### format

[](#format)

```
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\TargetClass;
use Symfony\Component\HttpFoundation\Response;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => TargetClass::class,

        // Options values are provided by your serializer (these are default format supported by symfony serializer)
        // Format can be override from js by add response_format param in data-autocomplete-url
        'format' => 'json', // xml|csv|yaml|...

        // OR

        // Encode response with your logic
        'format' => function (array $normalized, Response $response): Response {
            return $response->setContent(json_encode($normalized));
        }
    ])
;
```

### identifier

[](#identifier)

```
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\TargetClass;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => TargetClass::class,

        // Identifier is used as choice value
        'identifier' => 'targetPropertyOrMethod',
    ])
;
```

### autocomplete\_url

[](#autocomplete_url)

Sometimes you will need this option to retrieve search results from specific entrypoint.

```
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\TargetClass;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => TargetClass::class,

        // This option value will be set in data-autocomplete-url of select input attributes
        'autocomplete_url' => '/my-custom-entrypoint?param1=kevin',
    ])
;
```

### transformer

[](#transformer)

```
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\TargetClass;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => TargetClass::class,

        // Don't transform identifiers values to objects
        'transformer' => false,

        // OR

        // Use custom transformer
        'transformer' => $myCustomTransformer
    ])
;
```

### provider

[](#provider)

```
use Acseo\SelectAutocomplete\DataProvider\Doctrine\AbstractDoctrineDataProvider;
use Acseo\SelectAutocomplete\Form\Type\AutocompleteType;
use App\Entity\TargetClass;

$formBuilder
    ->add('example', AutocompleteType::class, [
        'class' => TargetClass::class,

        // Override provider on search action to retrieve custom collection (Usage of partial query is allowed)
        // The second argument is the default provider which supports the model class
        'provider' => function(string $terms, AbstractDoctrineDataProvider $provider) {
            return $provider->getRepository(TargetClass::class)
                ->createQueryBuilder('o')
                ->where('o.name LIKE :name')
                ->setParameter('name', $terms.'%')
                ->getQuery()
                ->getResult()
            ;

            // You can also just override default query (available with ORM & ODM Doctrine providers)
            //
            // if ($provider instanceof ORMDataProvider) {
            //     $qb = $provider->createSearchQueryBuilder('o', TargetClass::class, ['name'], $terms, 'starts_with');
            //     // Custom query
            //     return $qb->getQuery()->getResult();
            // }
            //
            // if ($provider instanceof ODMDataProvider) {
            //     $qb = $provider->createSearchAggregationBuilder(TargetClass::class, ['name'], $terms, 'starts_with');
            //     // Custom query
            //     return $qb->execute()->toArray();
            // }
        },

        // OR

        // Use your own provider object
        'provider' => $myProvider,

        // OR

        // You can specify provider to use (the service has to be tagged as acseo_select_autocomplete.data_provider).
        // 2 providers are included by default : ORMDataProvider and ODMDataProvider.
        // You can add many providers, for specific model class or other kind of databases !
        'provider' => MyCustomProvider::class,

        // OR

        // Create custom provider
        // To know more about providers, please see Providers section.
        'provider' => [
            'find_by_ids' => function(array $ids, AbstractDoctrineDataProvider $provider) {
                return $provider->getRepository(TargetClass::class)->findBy(['id' => $ids]);
            },
            'find_by_terms' => function(string $terms, AbstractDoctrineDataProvider $provider) {
                return $provider->getRepository(TargetClass::class)
                    ->createQueryBuilder('o')
                    ->where('o.name LIKE :name')
                    ->setParameter('name', $terms.'%')
                    ->getQuery()
                    ->getResult()
                ;
            }
        ],

        // If provider option is not set, the provider used is the first which supports model class
    ])
;
```

Providers
---------

[](#providers)

Providers classes are used to **retrieve search results** form database and **transform form view data** to model object.

2 Doctrine providers are included by default : ORMDataProvider and ODMDataProvider which supports multiple db connexions.

You can create your own provider for specific model class or specific database. This is an arbitrary example :

```
