How can be implemented HTML5 datalist with values from the database (Doctrine)?
Purpose: replace selects with many options to inputs with autocompletion.
How can be implemented HTML5 datalist with values from the database (Doctrine)?
Purpose: replace selects with many options to inputs with autocompletion.
First, add your new FormType
for the field:.
<?php
// src/Acme/Form/Type/DatalistType
namespace Acme\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class DatalistType extends AbstractType
{
public function getParent()
{
return TextType::class;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired(['choices']);
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['choices'] = $options['choices'];
}
public function getName()
{
return 'datalist';
}
}
In services.yml
:
form.type.datalist_type:
class: Acme\Form\Type\DatalistType
tags:
- { name: form.type, alias: datalist }
Do you have a form theme? If yes, skip to the next step, if no, create a new one in app/Resources/views/Form/fields.html.twig
and change your default Twig theme to it:
# app/config/config.yml
twig:
form_themes:
- ':Form:fields.html.twig'
Now define a template for your new field in the form theme:
{% block datalist_widget %}
<input list="{{ id }}_list" {{ block('widget_attributes') }}{% if value is not empty %}value="{{ value }}"{% endif %}>
<datalist id="{{ id }}_list">
{% for choice in choices %}
<option value="{{ choice }}"></option>
{% endfor %}
</datalist>
{% endblock %}
Use your field in FormType
:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('country', DatalistType::class, ['choices' => ['a', 'b']]);
}
Instead of ['a', 'b']
You need to load your choices from DB somehow, I'd suggest passing them in form options as the easiest solution.
choices
option. Datalist doesn't allow values to be different from what a user selects, it's just a way to add autocomplete for the text input. –
Ethelethelbert I spent some time trying to solve this issue, and there is a quite simple solution which solves Konstantin's issue with database access. It is to create a new form type which has EntityType as it's parent.
class DatalistType extends AbstractType
{
public function getParent() {
return EntityType::class;
}
}
You can then create a new template for this widget:
{# views/form/fields.html.twig #}
{% block datalist_widget %}
<input {{ block('widget_attributes') }} list="{{ form.vars.id }}_list" value="{{ form.vars.value }}" />
<datalist id="{{ form.vars.id }}_list">
{% for choice in choices %}
<option>
{{ choice.label }}
</option>
{% endfor %}
</datalist>
{% endblock %}
Finally, in the buildForm function of the form you are building, you can add your form element using the DatalistType, and using the EntityType options.
$builder->add('fieldName', DatalistType::class ,
array('required' => false,
'label' => 'fieldLabel',
'class' => 'AppBundle\Entity\EntityName',
'choice_label' => 'entityField'))
In your formType :
->add('commerciaux', TextType::class,
[
'label' => 'Apporteur d\'affaire*',
'attr' =>
[
'placeholder' => 'Apporteur d\'affaire',
'list' => 'bieres'
]
]
)
In your View :
{{ form_row(formulaire.commerciaux) }}
<datalist id="bieres">
<option value="Meteor">
<option value="Pils">
<option value="Kronenbourg">
<option value="Grimbergen">
</datalist>
In your formType :
->add('commerciaux', TextType::class,
[
'label' => 'Apporteur d\'affaire*',
'attr' =>
[
'placeholder' => 'Apporteur d\'affaire',
'list' => 'bieres'
]
]
)
Declare ( controller or View) 'bieres' => $array_bieres
In your View :
{{ form_row(formulaire.commerciaux) }}
<datalist id="bieres">
{% for biere in bieres %}
<option value="{{ biere }}">
{% endfor %}
</datalist>
© 2022 - 2024 — McMap. All rights reserved.