Would there be any documentation about autocomplete Forms ?
I saw that it was possible to use it with Resources (Customer for example) but I am quickly lost.
If anyone could enlighten me on this, thank you!
EDIT: If you need a little explanation: I would like to be able to search for a Customer from an autocomplete field, as it already exists for products.
It will then be possible for me to add a rule in promotions to assign a promotion to a single customer (for example)
I created my form (without forgetting to add the addModelTransformer)
->add('customer', ResourceAutocompleteChoiceType::class, [
'label' => 'sylius.ui.customer',
'resource' => 'sylius.customer',
'choice_name' => 'name',
'choice_value' => 'id',
])
$builder->get('customer')->addModelTransformer(
new ReversedTransformer(
new ResourceToIdentifierTransformer($this->customerRepository, 'id')
)
);
Then this part for Twig
<div class="ui tab" data-tab="customer">
<h3 class="ui dividing header">{{ 'sylius.ui.customer'|trans }}</h3>
{{ form_label(form.user) }}
<div class="ui fluid search selection dropdown">
{{ form_row(form.user, {'attr': {'class': 'autocomplete'}}) }}
<i class="dropdown icon"></i>
<div class="default text">{{'sylius.ui.select_customer'|trans}}</div>
<div class="menu"></div>
</div>
</div>
It's from here that I start to get lost on how to get the field (what concerns routing is not the most disturbing)
Finally, I managed to implement my autocomplete form (thanks to my super colleague). It has not been easy!
_(I would suggest documentation on this subject from time to time)_
@splyy would you have a while to add this documentation that you've proposed as a quick cookbook maybe? :)
I have not yet started writing documentation on this subject.
I would like to finish the one I started about SyliusMenu @CoderMaggie :D
This kind of cookbook would have really helped me!
I'm currently writing the documentation, I'd just like to test what's necessary! I hope to be able to do a PR by the end of the week :smile:
This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in a week if no further activity occurs. Thank you for your contributions.
By the end of the week is a little overpast :smile:
Is there any progress on this doc ?
i'm interested too ^^
I would have to find time soon to finish the piece of documentation I had started writing. From memory, I was on the end, all I had to do was test my explanations (which is not easy...) to make sure I had written a good doc :)
This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in a week if no further activity occurs. Thank you for your contributions.
Hi guys,
Just implemented this for the Customer resource in the project I'm developing. This issue @splyy raised as well as others helped me get going, then all it took was some code analysis.
Here is a quick run down under v1.6 (works at least up to 1.7 ALPHA 2) to help people along. Be warned it is a very very rough run down and is probably not exhaustive, there is probably some stuff I'm forgetting and you'll have to adapt it to your project but it will at least give you an idea. I'd advice to take inspiration from Product or Taxon Autocompletes.
1) Extend the CustomerRepository and implement your custom fetch method in it that will take a name and limit (as per our example) as arguments. Ie:
[...]
/**
* {@inheritdoc}
*/
public function findByNamePart(string $phrase, ?int $limit = null): array
{
return $this->createQueryBuilder('o')
->andWhere('o.lastName LIKE :name')
->setParameter('name', '%' . $phrase . '%')
->setMaxResults($limit)
->getQuery()
->getResult();
}
[...]
2) Create a CustomerAutocompleteChoiceType
```
declare(strict_types=1);
namespace App\Form\Type;
use Sylius\Bundle\ResourceBundle\Form\Type\ResourceAutocompleteChoiceType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CustomerAutocompleteChoiceType extends AbstractType
{
/*
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'resource' => 'sylius.customer',
'choice_name' => 'lastName',
'choice_value' => 'id',
]);
}
/*
* @psalm-suppress MissingPropertyType
/
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$view->vars['remote_criteria_type'] = 'contains';
$view->vars['remote_criteria_name'] = 'phrase';
}
/*
* {@inheritdoc}
/
public function getBlockPrefix(): string
{
return 'sylius_customer_autocomplete_choice';
}
/*
* {@inheritdoc}
*/
public function getParent(): string
{
return ResourceAutocompleteChoiceType::class;
}
}
3) Edit your EntityType's customer field with it
[...]
->add('customer', CustomerAutocompleteChoiceType::class, [
'label' => 'sylius.ui.customer',
'resource' => 'sylius.customer',
'choice_name' => 'lastName',
'choice_value' => 'id',
])
$builder->get('customer')->addModelTransformer(
new ReversedTransformer(
new ResourceToIdentifierTransformer($this->customerRepository, 'id')
)
)->addModelTransformer(
new ResourceToIdentifierTransformer($this->customerRepository, 'id')
);
[...]
> Don't forget to inject the Sylius\Component\Core\Repository\CustomerRepositoryInterface
4) Override AdminBundle/Resources/views/Form/theme.html.twig to add:
[...]
{% block sylius_customer_autocomplete_choice_row %}
{{ form_row(form, {'remote_url': path('sylius_admin_ajax_customer_by_name_phrase'), 'load_edit_url': '' }) }}
{% endblock %}
[...]
> Note the "sylius_customer_autocomplete_choice_row" with is generated from the block prefix defined in our CustomerAutocompleteChoiceType (see 2.).
5) Add your route
sylius_admin_ajax_customer_by_name_phrase:
path: /admin/customer/search
methods: [GET]
defaults:
_controller: sylius.controller.customer:indexAction
_format: json
_sylius:
serialization_groups: [Default]
permission: true
repository:
method: findByNamePart
arguments:
phrase: $phrase
limit: 25
```
This part is where you fill your custom Repository fetch method:
repository:
method: findByNamePart
arguments:
phrase: $phrase
limit: 25
Results:

I'm new to Sylius and this is my first project so I dunno if the code is good (it does need to use more appropriate serialization) but it is working for me, just need to customize it further so it can fetch (and display) by full name rather than last (so fine tune the doctrine query & solve that serialization issue). Once the project is over and I solved the serialization part I'll try and document this properly as a cookbook entry, if @splyy doesn't first that is.
All in all I feel it really wouldn't be that hard to implement if it was properly documented.
Thank you for your return @tuala ! I hope it will help other users in need :+1:
For the documentation, I think you can largely take care of it. Unfortunately, I'm no longer working on the project corresponding to my issue. And I didn't have time to finish the documentation I started either...
Maybe on occasion I'll try to finalize it and I could share it to see if it matches the method you used to solve the problem :)
That's the goal, I know those posts help get you going when there is no documentation ^^
I've never written public documentation so this will take some time, which I won't have for some months, and the more eyes the better 😛
I solved the serialization part btw, so for those interested:
Most helpful comment
Hi guys,
Just implemented this for the Customer resource in the project I'm developing. This issue @splyy raised as well as others helped me get going, then all it took was some code analysis.
Here is a quick run down under v1.6 (works at least up to 1.7 ALPHA 2) to help people along. Be warned it is a very very rough run down and is probably not exhaustive, there is probably some stuff I'm forgetting and you'll have to adapt it to your project but it will at least give you an idea. I'd advice to take inspiration from Product or Taxon Autocompletes.
1) Extend the CustomerRepository and implement your custom fetch method in it that will take a name and limit (as per our example) as arguments. Ie:
2) Create a CustomerAutocompleteChoiceType
```
declare(strict_types=1);
namespace App\Form\Type;
use Sylius\Bundle\ResourceBundle\Form\Type\ResourceAutocompleteChoiceType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CustomerAutocompleteChoiceType extends AbstractType
{
/*
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'resource' => 'sylius.customer',
'choice_name' => 'lastName',
'choice_value' => 'id',
]);
}
/*
* @psalm-suppress MissingPropertyType
/
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$view->vars['remote_criteria_type'] = 'contains';
$view->vars['remote_criteria_name'] = 'phrase';
}
/*
* {@inheritdoc}
/
public function getBlockPrefix(): string
{
return 'sylius_customer_autocomplete_choice';
}
/*
* {@inheritdoc}
*/
public function getParent(): string
{
return ResourceAutocompleteChoiceType::class;
}
}
[...]
->add('customer', CustomerAutocompleteChoiceType::class, [
'label' => 'sylius.ui.customer',
'resource' => 'sylius.customer',
'choice_name' => 'lastName',
'choice_value' => 'id',
])
$builder->get('customer')->addModelTransformer(
new ReversedTransformer(
new ResourceToIdentifierTransformer($this->customerRepository, 'id')
)
)->addModelTransformer(
new ResourceToIdentifierTransformer($this->customerRepository, 'id')
);
[...]
templates/bundles/SyliusAdminBundle/Form/theme.html.twig
[...]
{% block sylius_customer_autocomplete_choice_row %}
{{ form_row(form, {'remote_url': path('sylius_admin_ajax_customer_by_name_phrase'), 'load_edit_url': '' }) }}
{% endblock %}
[...]
sylius_admin_ajax_customer_by_name_phrase:
path: /admin/customer/search
methods: [GET]
defaults:
_controller: sylius.controller.customer:indexAction
_format: json
_sylius:
serialization_groups: [Default]
permission: true
repository:
method: findByNamePart
arguments:
phrase: $phrase
limit: 25
```
This part is where you fill your custom Repository fetch method:
Results:
I'm new to Sylius and this is my first project so I dunno if the code is good (it does need to use more appropriate serialization) but it is working for me, just need to customize it further so it can fetch (and display) by full name rather than last (so fine tune the doctrine query & solve that serialization issue). Once the project is over and I solved the serialization part I'll try and document this properly as a cookbook entry, if @splyy doesn't first that is.
All in all I feel it really wouldn't be that hard to implement if it was properly documented.