有没有一种简单的方法为文本表单字段设置默认值?
有没有一种简单的方法为文本表单字段设置默认值?
你可以使用empty_data
设置默认值。
$builder->add('myField', 'number', ['empty_data' => 'Default value'])
可以在创建过程中轻松使用:
->add('myfield', 'text', array(
'label' => 'Field',
'empty_data' => 'Default value'
))
'data'
键更改为'value'
。 - Eddempty_data
。 - Pierre de LESPINAY我之前思考过几次这个问题,所以想记录一下我所想到/使用的不同方法。其中可能有些有用,但都不是Symfony2的“完美”解决方案。
构造函数 在实体中,你可以使用 $this->setBar('默认值');但这将在每次加载实体时(无论是否来自数据库)调用,有点混乱。不过它适用于各种字段类型,因为你可以创建日期或其他需要的内容。
在 get 函数内使用 if 语句 我不会这样做,但你可以这样做。
return ( ! $this->hasFoo() ) ? 'default' : $this->foo;
工厂/实例。调用一个静态函数/辅助类,它会为你提供一个预先填充了数据的默认实体。例如:
function getFactory() {
$obj = new static();
$obj->setBar('foo');
$obj->setFoo('bar');
return $obj;
}
这种方法并不是理想的,因为如果您添加额外的字段,则需要维护此函数,但它确实意味着您正在分离数据设置器/默认值和从数据库生成的内容。类似地,如果您想要不同的默认数据,则可以拥有多个getFactories。
扩展/反射实体 创建一个扩展实体(例如FooCreate extends Foo),在创建时通过构造函数获取默认数据。与Factory / instance思想类似,只是一种不同的方法 - 我个人更喜欢静态方法。
在构建表单之前设置数据 在构造函数/服务中,您知道是否有新实体或者它是从数据库中填充的。因此,在获取新实体时调用不同字段上的setData是可能的。例如:
if( ! $entity->isFromDB() ) {
$entity->setBar('default');
$entity->setDate( date('Y-m-d');
...
}
$form = $this->createForm(...)
表单事件 在创建表单时,您可以设置字段的默认数据。如果您想覆盖默认数据,可以使用PreSetData事件侦听器。但这样做会导致表单工作负担增加、代码重复,同时也会使代码难以维护和理解。
扩展表单 与表单事件类似,但是根据是否为数据库/新实体调用不同类型。我的意思是,您可以定义FooType来定义编辑表单,然后BarType扩展FooType并将所有数据设置到字段中。在控制器中,您只需选择要实例化的表单类型即可。这种方法对于自定义主题来说不够理想,并且与事件一样会增加过多的代码维护成本。
Twig 您可以基于每个字段使用value选项创建自己的主题并设置默认数据。如果希望保持模板整洁并且使表单可重用,则可以将此包装到表单主题中。例如:
form_widget(form.foo, {attr: { value : default } });
JS 如果字段为空,用JS函数填充表单很容易。例如,您可以使用占位符。但是这是一个非常糟糕的想法。
表单作为服务 对于我做过的一个大型基于表单的项目,我创建了一个生成所有表单、执行所有处理等任务的服务。这是因为这些表单将在多个控制器和多个环境中使用,虽然这些表单以相同的方式生成/处理,但它们的显示/交互方式不同(例如,错误处理、重定向等)。这种方法的美妙之处在于,您可以设置默认数据,执行所需的所有操作,以及通用处理错误等,而所有内容都封装在一个地方。
结论 在我看来,你会一次又一次地遇到相同的问题——默认数据应存放在哪里?
为此,我每次都会以不同的方式解决问题。例如,在创建表单之前,可以在构造函数中轻松(并且逻辑清晰地)设置注册表单的“新闻通讯”选项。当我构建链接在一起的表单集合时(例如,不同表单类型中的哪些单选按钮链接在一起),我使用事件监听器。当我构建更复杂的实体(例如,需要子项或大量默认数据的实体)时,我使用函数(例如,“getFactory”)根据需要创建元素。
我认为没有一个“正确”的方法,因为每次遇到此要求时情况略有不同。
祝你好运!希望我的回答能给你提供一些思路,而且希望我没有说得太多。
如果您需要设置默认值并且表单与实体相关,则应使用以下方法:
// buildForm() method
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
...
->add(
'myField',
'text',
array(
'data' => isset($options['data']) ? $options['data']->getMyField() : 'my default value'
)
);
}
否则,myField
将始终被设置为默认值,而不是从实体获取值。$options['data']->getMyField()
替换为$option['data']['myField']
。 - gggempty_data
:此选项确定字段在提交值为空时将返回什么值。它不设置初始值。 - Vincent Decauxpublic function __construct()
{
$this->field = 'default value';
}
'mapped' => false
)。对于这些字段,请使用 setData(...)
。 - Dizzley方法1(来源于http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms/)
只需在实体中设置默认值,可以在变量声明或构造函数中进行设置:
class Entity {
private $color = '#0000FF';
...
}
或者class Entity {
private $color;
public function __construct(){
$this->color = '#0000FF';
...
}
...
}
从上面链接的评论中采用方法2,还要根据 Dmitriy 在 How to set default value for form field in Symfony2? 中的回答(不是被接受的答案),在使用FormBuilder添加字段时将默认值添加到数据属性中。public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('color', 'text', array(
'label' => 'Color:',
'data' => (isset($options['data']) && $options['data']->getColor() !== null) ? $options['data']->getColor() : '#0000FF'
)
);
}
不要使用:
'data' => 'Default value'
阅读这里:https://symfony.com/doc/current/reference/forms/types/form.html#data
"当渲染表单时,数据选项始终覆盖从域数据(对象)获取的值。这意味着,当表单编辑已经持久化的对象时,对象值也会被覆盖,导致在提交表单时失去其持久化的值。"
使用以下代码:
假设有一个实体Foo,并且有一个字段“active”(在此示例中是CheckBoxType,但处理方式与其他类型相同),您想要默认选中该字段。
在您的FooFormType类中添加:
...
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
...
public function buildForm( FormBuilderInterface $builder, array $options )
{
...
$builder->add('active', CheckboxType::class, array(
'label' => 'Active',
));
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event){
$foo = $event->getData();
// Set Active to true (checked) if form is "create new" ($foo->active = null)
if(is_null($foo->getActive())) $foo->setActive(true);
}
);
}
public function configureOptions( OptionsResolver $resolver )
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle:Foo',
));
}
'data' => $data['myfield'] ?? '默认值'
- xarlymg89通过使用没有类的表单或者在需要访问任何服务来设置默认值的情况下,可以为任何案例/方法提供通用解决方案:
// src/Form/Extension/DefaultFormTypeExtension.php
class DefaultFormTypeExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
if (null !== $options['default']) {
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($options) {
if (null === $event->getData()) {
$event->setData($options['default']);
}
}
);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('default', null);
}
public function getExtendedType()
{
return FormType::class;
}
}
并注册表单扩展:
app.form_type_extension:
class: App\Form\Extension\DefaultFormTypeExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }
之后,我们可以在任何表单字段中使用default
选项:
$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));
message
的默认值:$defaultData = array('message' => 'Type your message here');
$form = $this->createFormBuilder($defaultData)
->add('name', 'text')
->add('email', 'email')
->add('message', 'textarea')
->add('send', 'submit')
->getForm();
$user = new User();
$user->setUsername('John Doe');
$form = $this->createFormBuilder($user)
->add('username')
->getForm();