问题
I'm setting up a custom form type for datalist and it works fine using a preset choices, but I'm unable to set up it in order to let it handle an EntityType.
That's my working code
<?php
// path and filename
// /src/form/type/DatalistType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType; // unused at the moment
class DatalistType extends AbstractType {
private $entityManager;
public function __construct(EntityManagerInterface $entityManager) {
$this->entityManager = $entityManager;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'choices' => [
'Math' => 'Math',
'Physics' => 'Physics',
'Chemistry' => 'Chemistry',
],
]);
}
public function getParent() {
return ChoiceType::class;
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setRequired(['choices']);
}
public function buildView(FormView $view, FormInterface $form, array $options) {
$view->vars['choices'] = $options['choices'];
}
public function getName() {
return 'datalist';
}
}
<?php
// path and filename
// /src/form/DegreeType.php
namespace App\Form;
use App\Entity\Degree;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use App\Form\Type\DatalistType;
class DegreeType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('degree', DatalistType::class, [
'placeholder' => 'Choose a master degree',
])
;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => Degree::class,
]);
}
}
// TWIG TEMPLATE
// path and filename
// templates/form/fields.html.twig
?>
{% block datalist_widget %}
<div class="form-group">
<input list="{{ id }}_list" {{ block('widget_attributes') }} class="form-control">
<datalist id="{{ id }}_list">
{% for choice in choices %}
<option value="{{ choice }}"></option>
{% endfor %}
</datalist>
</div>
{% endblock %}
// config/packages/twig.yaml
twig:
paths: ['%kernel.project_dir%/templates']
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
form_themes: ['form/fields.html.twig']
I changed the getParent() method in order to return an EntityType::class
public function getParent() {
return EntityType::class;
}
Removed the default vaulues for $resolver inside configureOptions() method
public function configureOptions(OptionsResolver $resolver) {
}
then inside the form builder
->add('degree',DatalistType::class , [
'label' => 'Choose an master degree',
'class' => Degree::class
])
I expect it works as for the static values, but it didn't.
I've read any kind of question here like
Symfony Forms: HTML5 datalist
but I think the answers posted wasn't complete or it was for old version of Symfony, not for > 3.4
回答1:
The solution is to remove all methods inside DatalistType and leave just constructor and getParent(): EntityType::class
<?php
// path and filename
// /src/form/type/DatalistType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
class DatalistType extends AbstractType {
private $entityManager;
public function __construct(EntityManagerInterface $entityManager) {
$this->entityManager = $entityManager;
}
public function getParent() {
return EntityType::class;
}
}
Then, change the template
{% block datalist_widget %}
<div class="form-group">
<input {{ block('widget_attributes') }} list="{{ form.vars.id }}_list" value="{{ form.vars.value }}" class="form-control" >
<datalist id="{{ form.vars.id }}_list">
{% for choice in choices %}
<option>
{{ choice.label }}
</option>
{% endfor %}
</datalist>
</div>
{% endblock %}
It works fine!!!
来源:https://stackoverflow.com/questions/55667268/how-to-define-a-custom-form-type-class-for-html5-datalist-in-order-to-handle-ent