【问题标题】:Symfony Custom Field or Dynamic Form?Symfony 自定义字段还是动态表单?
【发布时间】:2017-08-17 07:06:57
【问题描述】:

我想请你提供一些关于在 Symfony 3 中创建特定表单的小建议。

阅读 Symfony 文档后,我想到了一些解决方案,但我希望您分享实现此目的的最佳方法。

我需要得到这样的输出形式: link for expected example form

如您所见,我需要制作一个包含一个复选框和一种输入类型的单个字段。它应该像用户勾选复选框一样工作,输入将处于活动状态。

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

基本上一个字段应该由两个相互依赖的不同字段类型组成。

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

【问题讨论】:

    标签: php forms symfony symfony-forms


    【解决方案1】:

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

    但是,为了即时启用/禁用文本字段,您必须使用 Javascript。

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

    我们来看一种 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 %}
    

    最后,一堆处理前端交互的 JS 行:

    $(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('');
        }
    }
    

    【讨论】:

    • 很好的答案!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多