简体   繁体   English

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

[英]Symfony Custom Field or Dynamic Form?

I'm asking you for a litte advice in creating specific form in Symfony 3. 我要求您提供一些关于在Symfony 3中创建特定表格的建议。

After reading Symfony Docs I have some solution in mind, but I'm asking you for sharing best aproach to achieve this. 阅读Symfony Docs之后,我想到了一些解决方案,但我要求您分享实现此目标的最佳方法。

I need to get output form like this: link for expected example form 我需要获得如下输出形式: 预期示例形式的链接

As you see i need to make single field constiting of one checkbox and one input type. 如您所见,我需要将一个复选框和一种输入类型设置为单一字段。 It should work like if user ticks the checkbox, the input will be active. 它应该像用户勾选复选框一样起作用,输入将处于活动状态。

Should it be custom field with getParent() method from FormType as parent? 它应该是FormType的getParent()方法作为父项的自定义字段吗? Maybe this form should be created dynamically with event listener and some Javascript? 也许应该使用事件监听器和一些Javascript动态创建此表单? Or it should be CollectionType field (but how it can store two different form field types?) or maybe you know different solution? 还是应该是CollectionType字段(但是如何存储两种不同的表单字段类型?),或者您知道不同的解决方案?

Basically one field should consist of two different field type depending from each other. 基本上,一个字段应该由彼此不同的两个不同的字段类型组成。

Any help, sharing knowledge or some code examples will be very welcome. 任何帮助,分享知识或一些代码示例都将受到欢迎。

First, you have to build a custom FormType that composes a CheckboxType and a TextType. 首先,您必须构建一个由CheckboxType和TextType组成的自定义FormType。 This is the server-side form part. 这是服务器端表单的一部分。

But, in order to enable/disable the text field on the fly, you'll have to use Javascript. 但是,为了即时启用/禁用文本字段,您必须使用Javascript。

Finally, if you want to store the result information a single nullable text field (like a nullable varchar), you need a DataTransformer to convert data from persistece layer to view. 最后,如果要将结果信息存储在单个可为空的文本字段(如可为空的varchar)中,则需要一个DataTransformer来将数据从持久层转换为视图。

Let's see a kind of FormType : 让我们来看看一种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());
    }
}

And now the transformer : 现在是变压器:

<?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;
        }
    }
}

Some twig for the form theming of the custom field : 有关自定义字段的表单主题设置的一些提示:

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

And finally, a bunch of JS lines to handle the front interactions : 最后,有一堆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('');
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM