Symfony Forms: HTML5 datalist
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.
Symfony 4, add a text input field inside a ChoiceType
What you are looking for is an HTML datalist element, currently not supported by Symfony forms, but you can create your own:
Symfony Forms: HTML5 datalist
How to get form data with session in Symfony Form
Yes you can use $form->getData()
but to do that you need to do this according to the doc here with using if ($form->isSubmitted() && $form->isValid()) {
among others.
Symfony 5 - Custom ChoiceType with TextType
It's not easy to do, but you can do it with a customs form type field and a Twig theme:
1.Create a new field type like ChoiceInputType
. That class should contain two field types, ChoiceType and TextType.
/**
* Class ChoiceInputType
*/
class ChoiceInputType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add(
'choiceType',
ChoiceType::class,
[
'required' => false,
'choices' => $options['choices'],
'label' => 'Make your choice...',
]
)
->add(
'choiceInput',
TextType::class,
[
'required' => false,
'label' => false,
'attr' => [
'placeholder' => 'Other choice...',
],
]
);
}
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$view->vars['choices'] = $options['choices'];
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setRequired(['choices']);
$resolver->setDefaults(
[
'choices' => [],
]
);
}
/**
* {@inheritdoc}
*/
public function getName(): string
{
return 'choiceInputType';
}
}
2.Create a twig theme on your new custom field type and organize it as you want.
{% block choiceInputType_widget %}
... custom here ...
{% endblock %}
3.Use your new ChoiceInputType
inside your form.
$builder->add(
'choiceInputType',
ChoiceInputType::class,
[
'mapped' => false,
'block_prefix' => 'choiceInputType',
'label' => false,
'choices' => [
'test 1' => 1,
'test 2' => 2,
'test 3' => 3,
]
]
);
Here some links to other questions similar to this thread that can help you:
- Symfony Forms: HTML5 datalist
- Customize the rendering of a choice/entity field in Symfony2
Symfony form type extension for custom types
FormType inheritance is built on method getParent(). Probably, you should not extend MyBaseType
but return it in getParent()
getParent()
When returning a (fully-qualified) class name here, Symfony will call each method of that type (i.e. buildForm(), buildView(), etc.)
and all its type extensions, before calling the corresponding method
of your custom type.
https://symfony.com/doc/current/form/create_custom_field_type.html#creating-form-types-created-from-scratch
class MyBaseType extends AbstractType
{
}
class MySubType1 extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('blahblahblah', TextType::class, [
'label' => 'blahblahblah',
])
(etc.)
;
}
public function getParent()
{
return MyBaseType::class;
}
}
Related Topics
Ie Offsetting and Ignoring Height/Width of Anchor Focus Outlines
How to Change Font Size in a Textbox in HTML
Overlaying a Div on Top of HTML 5 Video
How to Get The Bullet Points of a <Ul> to Center with The Text
Table Columns, Setting Both Min and Max Width with CSS
Ring-Shaped Process Spinner with Fading Gradient Effect Around The Ring
<Ol> with Numbers Another Color
The Ajax Response: Data (JSON, Xml) or HTML Snippet
How to Avoid a Page Break Immediately After a Heading
Video Tag Src Not Picking Ftp Url as a Source
How to Create a Round Arrow with Only HTML and CSS
Horizontal Line and Right Way to Code It in HTML, CSS
How to Reuse HTML Like a Template on Multiple Pages