@@ -171,6 +171,109 @@ After creating this class, use it in your form:
171
171
172
172
Congratulations! Your ``EntityType `` is now Ajax-powered!
173
173
174
+ .. _passing-extra-options-to-the-ajax-powered-autocomplete :
175
+
176
+ Passing Extra Options to the Ajax-powered Autocomplete
177
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
178
+
179
+ .. versionadded :: 2.13
180
+
181
+ The ability to pass extra options was added in LiveComponents 2.13.
182
+
183
+ By default, when you pass any options while adding a field to a form type, they will be lost
184
+ when the autocomplete field is rendered on an Ajax call. To partially avoid this limitation,
185
+ the `extra_options ` option was added. It can only hold a scalar values, but it covers most use cases.
186
+
187
+ Considering the following example, when the form type is rendered for the first time, it will use the `query_builder ` defined
188
+ while adding a `food ` field to the `FoodForm `. However, when the Ajax is used to fetch the results, on the consequent renders,
189
+ the default `query_builder ` will be used::
190
+
191
+ // src/Form/FoodForm.php
192
+ // ...
193
+
194
+ class FoodForm extends AbstractType
195
+ {
196
+ public function buildForm(FormBuilderInterface $builder, array $options): void
197
+ {
198
+ $currentFoodId = $builder->getData()->getId();
199
+
200
+ $builder
201
+ ->add('food', FoodAutocompleteField::class, [
202
+ 'query_builder' => function (EntityRepository $er) {
203
+ $qb = $er->createQueryBuilder('o');
204
+
205
+ $qb->andWhere($qb->expr()->notIn('o.id', [$currentFoodId]));
206
+
207
+ return $qb;
208
+ };
209
+ }
210
+ ])
211
+ ;
212
+ }
213
+ }
214
+
215
+ If some food can be consisted of other foods, we might want to exclude the "root" food from the list of available foods.
216
+ To achieve this, we can remove the `query_builder ` option from the above example and pass the `excluded_foods ` extra option
217
+ to the `FoodAutocompleteField `::
218
+
219
+ // src/Form/FoodForm.php
220
+ // ...
221
+
222
+ class FoodForm extends AbstractType
223
+ {
224
+ public function buildForm(FormBuilderInterface $builder, array $options): void
225
+ {
226
+ $currentFoodId = $builder->getData()->getId();
227
+
228
+ $builder
229
+ ->add('food', FoodAutocompleteField::class, [
230
+ 'extra_options' => [
231
+ 'excluded_foods' => [$currentFoodId],
232
+ ],
233
+ )
234
+ ;
235
+ }
236
+ }
237
+
238
+ The magic of the `extra_options ` option is that it will be passed to the `FoodAutocompleteField ` every time an Ajax call is made.
239
+ So now, we can just use the `excluded_foods ` extra option in the default `query_builder ` of the `FoodAutocompleteField `::
240
+
241
+ // src/Form/FoodAutocompleteField.php
242
+ // ...
243
+
244
+ use Symfony\Bundle\SecurityBundle\Security;
245
+ use Symfony\UX\Autocomplete\Form\AsEntityAutocompleteField;
246
+ use Symfony\UX\Autocomplete\Form\BaseEntityAutocompleteType;
247
+
248
+ #[AsEntityAutocompleteField]
249
+ class FoodAutocompleteField extends AbstractType
250
+ {
251
+ public function configureOptions(OptionsResolver $resolver)
252
+ {
253
+ $resolver->setDefaults([
254
+ // ...
255
+ 'query_builder' => function (Options $options) {
256
+ return function (EntityRepository $er) use ($options) {
257
+ $qb = $er->createQueryBuilder('o');
258
+
259
+ $excludedFoods = $options['extra_options']['excluded_foods'] ?? [];
260
+ if ([] !== $excludedFoods) {
261
+ $qb->andWhere($qb->expr()->notIn('o.id', $excludedFoods));
262
+ }
263
+
264
+ return $qb;
265
+ };
266
+ }
267
+ ]);
268
+ }
269
+
270
+ public function getParent(): string
271
+ {
272
+ return BaseEntityAutocompleteType::class;
273
+ }
274
+ }
275
+
276
+
174
277
Styling Tom Select
175
278
------------------
176
279
@@ -274,6 +377,9 @@ to the options above, you can also pass:
274
377
Set to ``focus `` to call the ``load `` function when control receives focus.
275
378
Set to ``true `` to call the ``load `` upon control initialization (with an empty search).
276
379
380
+ ``extra_options `` (default ``[] ``)
381
+ Allow you to pass extra options for Ajax-based autocomplete fields.
382
+
277
383
Using with a TextType Field
278
384
---------------------------
279
385
@@ -481,6 +587,62 @@ the ``ux_entity_autocomplete`` route and ``alias`` route wildcard:
481
587
Usually, you'll pass this URL to the Stimulus controller, which is
482
588
discussed in the next section.
483
589
590
+ Passing Extra Options to the Autocompleter
591
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
592
+
593
+ .. versionadded :: 2.13
594
+
595
+ The ability to pass extra options was added in LiveComponents 2.13.
596
+
597
+ If you need to pass extra options to the autocompleter, you can do so by implementing the
598
+ ``\Symfony\UX\Autocomplete\OptionsAwareEntityAutocompleterInterface `` interface.
599
+
600
+ .. tip ::
601
+
602
+ If you want to know **why ** you might need to use the `extra options ` feature, see :ref: `passing-extra-options-to-the-ajax-powered-autocomplete `.
603
+
604
+ .. code-block :: diff
605
+
606
+ use Doctrine\ORM\EntityRepository;
607
+ use Doctrine\ORM\QueryBuilder;
608
+ use Sylius\Component\Product\Model\ProductAttributeInterface;
609
+ use Symfony\Bundle\SecurityBundle\Security;
610
+ use Symfony\UX\Autocomplete\OptionsAwareEntityAutocompleterInterface;
611
+
612
+ #[AutoconfigureTag('ux.entity_autocompleter', ['alias' => 'food'])]
613
+ class FoodAutocompleter implements OptionsAwareEntityAutocompleterInterface
614
+ {
615
+ + /**
616
+ + * @var array<string, mixed>
617
+ + */
618
+ + private array $options = [];
619
+
620
+ // ...
621
+
622
+ + public function createFilteredQueryBuilder(EntityRepository $repository, string $query): QueryBuilder
623
+ + {
624
+ + $excludedFoods = $this->options['extra_options']['excluded_foods'] ?? [];
625
+ +
626
+ + $qb = $repository->createQueryBuilder('o');
627
+ +
628
+ + if ($productAttributesToBeExcluded !== []) {
629
+ + $qb
630
+ + ->andWhere($qb->expr()->notIn('o.id', $excludedFoods));
631
+ + ->setParameter('excludedFoods', $excludedFoods)
632
+ + ;
633
+ + }
634
+ +
635
+ + return $qb;
636
+ + }
637
+
638
+ +/**
639
+ + * @param array<string, mixed> $options
640
+ + */
641
+ +public function setOptions(array $options): void
642
+ +{
643
+ + $this->options = $options;
644
+ +}
645
+
484
646
.. _manual-stimulus-controller :
485
647
486
648
Manually using the Stimulus Controller
0 commit comments