如何为html5数据列表定义自定义表单类型类,以处理Symfony> 3.4

时间:2019-04-13 15:52:54

标签: symfony

我正在为数据列表设置自定义表单类型,使用预设选项可以很好地工作,但是我无法对其进行设置以使其能够处理EntityType。

那是我的工作代码

<?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']

我更改了getParent()方法以返回EntityType :: class

public function getParent() {
        return EntityType::class;
    }

删除了configureOptions()方法中$ resolver的默认值

public function configureOptions(OptionsResolver $resolver) {

    }

然后在表单生成器中

->add('degree',DatalistType::class , [
       'label' => 'Choose an master degree',
       'class' => Degree::class
  ])

我希望它可以用于静态值,但不能。

我在这里读过任何类型的问题

Symfony Forms: HTML5 datalist

但是我认为发布的答案不完整,或者是针对旧版本的Symfony,而不是针对3.4以上版本

1 个答案:

答案 0 :(得分:0)

解决方案是在DatalistType中删除所有方法 并只保留构造函数和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;
    }
}

然后,更改模板


{% 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 %}

它工作正常!!!