DatalistType
How implement Html5 DataList with Symfony 3.4 and 4.x
Datalist
An input element with pre-defined values in a datalist.
The datalist tag specifies a list of pre-defined options for an input element.
The datalist tag is used to provide an "autocomplete" feature on input elements. Users will see a drop-down list of pre-defined options as they input data.
Use the input element's list attribute to bind it together with a datalist element.
Html5 Datalist
<!DOCTYPE html>
<html>
<body>
<form action="controller.php" method="POST">
<input list="languages" name="languages">
<datalist id="languages">
<option value="Java">
<option value="PHP">
<option value="C#">
<option value="Python">
<option value="C">
</datalist>
<input type="submit">
</form>
</body>
</html>
Unfortunately, Symfony Form Types References doesn't provide immediate support for HTML5 Datalist
Official Documentation
So, we need to create a custom data type form and embed it for general purpose into a project.
First step: Create a template to render
# Create a directory "form" inside your templates directory
# And create a file called datalist.html.twig
OURPROJECT/templates/form/datalist.html.twig
{% block datalist_widget %}
<div class="form-group">
<input {{ block("widget_attributes") }} list="{{ id }}_list" class="form-control" />
<datalist id="{{ id }}_list">
{% for choice in form.vars.choices %}
<option value="{{ choice.value }}">{{ choice.label }}</option>
{% endfor %}
</datalist>
</div>
{% endblock %}
Second step: Load the new template inside the twig configuration file
# Edit your twig config file
OURPROJECT/config/packages
twig:
paths: ['%kernel.project_dir%/templates']
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
form_themes: ['bootstrap_4_layout.html.twig']
twig:
paths: ['%kernel.project_dir%/templates']
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
form_themes: ['bootstrap_4_layout.html.twig', 'form/datalist.html.twig'] # new element for array form_themes must be loaded
Third step: Create the FormType Model
# Create a directory "Type" inside your directory Form of the project and a PHP Class DatalistType.php
OURPROJECT/src/Form/Type/DatalistType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
class DatalistType extends AbstractType {
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => \Doctrine\ORM\Mapping\Entity::class,
]);
}
public function getParent() {
return EntityType::class;
}
}
Usage: Now we can use datalist inside a FormType
namespace App\Form;
use App\Entity\Computer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use App\Form\Type\DatalistType; // Do not forget the use statement
class ComputerOwnerType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('nameOfComputer', null, [
'required => true',
'trim => true'
])
->add('owner', DatalistType::class, [
'required' => true,
'label' => 'User',
'class' => 'App\Entity\User',
])
;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => Computer::class,
]);
}
}