How to define a custom form type class for html5 datalist in order to handle entityType in Symfony > 3.4

回眸只為那壹抹淺笑 提交于 2021-02-11 12:33:37

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!