Symfony 自定义字段或动态表单?
Symfony Custom Field or Dynamic Form?
我想请您提供一些关于在 Symfony 3 中创建特定表单的小建议。
阅读 Symfony 文档后,我想到了一些解决方案,但我要求您分享实现此目的的最佳方法。
我需要这样的输出形式: link for expected example form
如您所见,我需要制作一个由一个复选框和一种输入类型组成的字段。它应该像用户勾选复选框一样工作,输入将被激活。
是否应该是使用 FormType 的 getParent() 方法作为父级的自定义字段?也许应该使用事件侦听器和一些 Javascript 动态创建此表单?或者它应该是 CollectionType 字段(但它如何存储两种不同的表单字段类型?)或者您可能知道不同的解决方案?
基本上一个字段应该由两种不同的字段类型组成。
非常欢迎任何帮助、分享知识或一些代码示例。
首先,您必须构建一个由 CheckboxType 和 TextType 组成的自定义 FormType。这是服务器端表单部分。
但是,为了 enable/disable 文本字段在运行时,您必须使用 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('');
}
}
我想请您提供一些关于在 Symfony 3 中创建特定表单的小建议。
阅读 Symfony 文档后,我想到了一些解决方案,但我要求您分享实现此目的的最佳方法。
我需要这样的输出形式: link for expected example form
如您所见,我需要制作一个由一个复选框和一种输入类型组成的字段。它应该像用户勾选复选框一样工作,输入将被激活。
是否应该是使用 FormType 的 getParent() 方法作为父级的自定义字段?也许应该使用事件侦听器和一些 Javascript 动态创建此表单?或者它应该是 CollectionType 字段(但它如何存储两种不同的表单字段类型?)或者您可能知道不同的解决方案?
基本上一个字段应该由两种不同的字段类型组成。
非常欢迎任何帮助、分享知识或一些代码示例。
首先,您必须构建一个由 CheckboxType 和 TextType 组成的自定义 FormType。这是服务器端表单部分。
但是,为了 enable/disable 文本字段在运行时,您必须使用 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('');
}
}