Skip to content

Commit 9d8220a

Browse files
committed
[Docs] Autocomplete cookbook
1 parent ca31711 commit 9d8220a

File tree

3 files changed

+168
-0
lines changed

3 files changed

+168
-0
lines changed

docs/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* [Customizing the menu](cookbook/admin_panel/menu.md)
1212
* [Configuring the security access](cookbook/admin_panel/security.md)
1313
* [Customizing the page titles](cookbook/admin_panel/page_titles.md)
14+
* [Using autocompletes](cookbook/admin_panel/autocompletes.md)
1415
* [How to use in a DDD architecture](cookbook/ddd_architecture.md)
1516
* [Architecture overview](cookbook/ddd_architecture/overview.md)
1617
* [Resource configuration](cookbook/ddd_architecture/resource_configuration.md)

docs/cookbook/admin_panel.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
* [Customizing the menu](admin_panel/menu.md)
66
* [Configuring the security access](admin_panel/security.md)
77
* [Customizing the page titles](admin_panel/page_titles.md)
8+
* [Using autocompletes](admin_panel/autocompletes.md)
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# Using autocompletes
2+
3+
Sylius stack uses [Symfony UX](https://ux.symfony.com/) under the hood.
4+
Thus, UX autocomplete is already setup and configured in your admin panel.
5+
6+
## Configure entity autocomplete route for admin section
7+
8+
{% tabs %}
9+
{% tab title="YAML" %}
10+
{% code lineNumbers="true" %}
11+
``̀`yaml
12+
#config/routes/ux_autocomplete.yaml
13+
#...
14+
ux_entity_autocomplete_admin:
15+
path: '/admin/autocomplete/{alias}'
16+
controller: 'ux.autocomplete.entity_autocomplete_controller'
17+
``̀`
18+
{% endcode %}
19+
{% endtab %}
20+
21+
{% tab title="PHP" %}
22+
{% code lineNumbers="true" %}
23+
```php
24+
<?php
25+
// config/routes/ux_autocomplete.php
26+
declare(strict_types=1);
27+
28+
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
29+
30+
return static function (RoutingConfigurator $routingConfigurator): void {
31+
// ...
32+
$routingConfigurator
33+
->add('ux_entity_autocomplete_admin', '/admin/autocomplete/{alias}')
34+
->controller('ux.autocomplete.entity_autocomplete_controller')
35+
;
36+
};
37+
```
38+
{% endcode %}
39+
{% endtab %}
40+
{% endtabs %}
41+
42+
Now you have a new ajax route `ux_entity_autocomplete_admin` for your autocompletes.
43+
44+
## Add a grid filter with entity autocomplete
45+
46+
First, you need to create the [entity autocomplete field](https://symfony.com/bundles/ux-autocomplete/current/index.html#usage-in-a-form-with-ajax).
47+
48+
```php
49+
<?php
50+
51+
declare(strict_types=1);
52+
53+
namespace App\Form;
54+
55+
use App\Entity\Speaker;
56+
use Symfony\Component\Form\AbstractType;
57+
use Symfony\Component\OptionsResolver\OptionsResolver;
58+
use Symfony\UX\Autocomplete\Form\AsEntityAutocompleteField;
59+
use Symfony\UX\Autocomplete\Form\BaseEntityAutocompleteType;
60+
61+
#[AsEntityAutocompleteField(
62+
alias: 'app_admin_speaker',
63+
route: 'ux_entity_autocomplete_admin', // We use the route we just configured before.
64+
)]
65+
final class SpeakerAutocompleteType extends AbstractType
66+
{
67+
public function configureOptions(OptionsResolver $resolver): void
68+
{
69+
$resolver->setDefaults([
70+
'class' => Speaker::class,
71+
'choice_label' => 'fullName',
72+
]);
73+
}
74+
75+
public function getParent(): string
76+
{
77+
return BaseEntityAutocompleteType::class;
78+
}
79+
}
80+
```
81+
82+
Then you need to create the grid filter.
83+
84+
```php
85+
<?php
86+
87+
declare(strict_types=1);
88+
89+
namespace App\Grid\Filter;
90+
91+
use App\Form\SpeakerAutocompleteType;
92+
use Sylius\Component\Grid\Data\DataSourceInterface;
93+
use Sylius\Component\Grid\Filter\EntityFilter;
94+
use Sylius\Component\Grid\Filtering\ConfigurableFilterInterface;
95+
96+
final class SpeakerFilter implements ConfigurableFilterInterface
97+
{
98+
public function __construct(
99+
private readonly EntityFilter $entityFilter,
100+
) {
101+
}
102+
103+
public function apply(DataSourceInterface $dataSource, string $name, mixed $data, array $options): void
104+
{
105+
$this->entityFilter->apply($dataSource, $name, $data, $options);
106+
}
107+
108+
public static function getFormType(): string
109+
{
110+
return SpeakerAutocompleteType::class;
111+
}
112+
113+
public static function getType(): string
114+
{
115+
return self::class; // it will allow to use FQCN instead of a string key.
116+
}
117+
}
118+
```
119+
120+
We also need to configure the Twig template for our new grid filter.
121+
122+
```yaml
123+
# config/packages/sylius_grid.yaml
124+
sylius_grid:
125+
# ...
126+
templates:
127+
filter:
128+
'App\Grid\Filter\SpeakerFilter': '@SyliusBootstrapAdminUi/shared/grid/filter/entity.html.twig'
129+
130+
```
131+
132+
Now our new grid filtered is configured, we can use it in a grid.
133+
134+
```php
135+
<?php
136+
137+
declare(strict_types=1);
138+
139+
namespace App\Grid;
140+
141+
use App\Grid\Filter\SpeakerFilter;
142+
use Sylius\Bundle\GridBundle\Builder\Filter\Filter;
143+
use Sylius\Bundle\GridBundle\Builder\GridBuilderInterface;
144+
use Sylius\Bundle\GridBundle\Grid\AbstractGrid;
145+
use Sylius\Bundle\GridBundle\Grid\ResourceAwareGridInterface;
146+
147+
final class TalkGrid extends AbstractGrid implements ResourceAwareGridInterface
148+
{
149+
// ...
150+
151+
public function buildGrid(GridBuilderInterface $gridBuilder): void
152+
{
153+
$gridBuilder
154+
// ...
155+
->addFilter(
156+
Filter::create(name: 'speaker', type: SpeakerFilter::class) // We use the new Speaker filter we just created.
157+
->setLabel('app.ui.speaker')
158+
->setOptions(['fields' => ['speakers.id']]),
159+
)
160+
// ...
161+
;
162+
}
163+
164+
// ...
165+
}
166+
```

0 commit comments

Comments
 (0)