【问题标题】:How to define a custom form type class for html5 datalist in order to handle entityType in Symfony > 3.4如何为 html5 datalist 定义自定义表单类型类以便在 Symfony > 3.4 中处理 entityType
【发布时间】:2019-09-04 03:24:35
【问题描述】:

我正在为 datalist 设置自定义表单类型,使用预设选项可以正常工作,但我无法设置它以便让它处理 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

【问题讨论】:

    标签: symfony


    【解决方案1】:

    解决办法是删除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 %}
    

    效果很好!!!

    【讨论】:

      猜你喜欢
      • 2013-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多