Php Symfony自定义字段还是动态表单?

Php Symfony自定义字段还是动态表单?,php,forms,symfony,symfony-forms,Php,Forms,Symfony,Symfony Forms,我想问你一些关于在Symfony 3中创建特定表单的建议 在阅读了Symfony文档之后,我想到了一些解决方案,但我请求您分享实现这一点的最佳方法 我需要得到如下输出形式: 正如你们所看到的,我需要将一个复选框和一个输入类型组成一个字段。它应该像用户勾选复选框一样工作,输入将处于活动状态 它应该是以FormType中的getParent()方法作为父项的自定义字段吗?也许这个表单应该用事件监听器和一些Javascript动态创建?或者应该是CollectionType字段(但它如何存储两种不同的

我想问你一些关于在Symfony 3中创建特定表单的建议

在阅读了Symfony文档之后,我想到了一些解决方案,但我请求您分享实现这一点的最佳方法

我需要得到如下输出形式:

正如你们所看到的,我需要将一个复选框和一个输入类型组成一个字段。它应该像用户勾选复选框一样工作,输入将处于活动状态

它应该是以FormType中的getParent()方法作为父项的自定义字段吗?也许这个表单应该用事件监听器和一些Javascript动态创建?或者应该是CollectionType字段(但它如何存储两种不同的表单字段类型?),或者您知道不同的解决方案

基本上,一个字段应该由两种不同的字段类型组成,这两种字段类型彼此不同


欢迎提供任何帮助、分享知识或一些代码示例。

首先,您必须构建一个由CheckboxType和TextType组成的自定义FormType。这是服务器端表单部件

但是,为了动态启用/禁用文本字段,必须使用Javascript

最后,如果希望将结果信息存储在单个可为空的文本字段(如可为空的varchar)中,则需要DataTransformer将数据从persistece层转换为视图

让我们看一种FormType:

<?php

namespace Form\Type;

use Form\DataTransformer\NullableTextTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;

class NullableTextType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('isNotNull', CheckboxType::class)
            ->add('text', TextType::class, array('required' => false))
        ;

        $builder->addModelTransformer(new NullableTextTransformer());
    }
}

回答得好!非常感谢。
<?php

namespace Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;

class NullableTextTransformer implements DataTransformerInterface
{
    public function transform($value)
    {
        $nullableText = ['isNotNull' => false, 'text' => null];

        if (null !== $value) {
            $nullableText['isNotNull'] = true;
            $nullableText['text'] = (string) $value;
        }

        return $nullableText;
    }

    public function reverseTransform($array)
    {
        if (!is_array($array) || empty($array) || !isset($array['isNotNull']) || !isset($array['text'])) {
            return;
        }

        if ($array['isNotNull']) {
            return (string) $array['text'];
        } else {
            return;
        }
    }
}
{% block nullable_text_widget %}
{% spaceless %}
  <div class="input-group nullable-text-widget">
    <div class="input-group-addon">
      {{ form_widget(form.isNotNull, {attr: {class: 'is-not-null-widget'}}) }}
    </div>
    {{ form_widget(form.text, {attr: {class: 'text-widget'}}) }}
  </div>
{% endspaceless %}
{% endblock nullable_text_widget %}
$(document).ready(function() {
    $.each($('body').find('.nullable-text-widget'), function () {
        syncNullableTextWidget($(this));
    });
});

$(document).on('click', '.nullable-text-widget .is-not-null-widget', function (e) {
    var $nullableTextWidget = $(e.currentTarget).parents('.nullable-text-widget');
    syncNullableTextWidget($nullableTextWidget);
});

function syncNullableTextWidget($widget)
{
    if ($widget.find('.is-not-null-widget').prop('checked')) {
        $widget.find('.text-widget').prop('disabled', false);
    } else {
        $widget.find('.text-widget').prop('disabled', true);
        $widget.find('.text-widget').val('');
    }
}