php 如何在 Symfony2 中为表单字段设置默认值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7913086/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set default value for form field in Symfony2?
提问by Ondrej Slinták
Is there an easy way to set a default value for text form field?
有没有一种简单的方法可以为文本表单字段设置默认值?
采纳答案by webda2l
Can be use during the creation easily with :
可以在创建过程中轻松使用:
->add('myfield', 'text', array(
'label' => 'Field',
'empty_data' => 'Default value'
))
回答by rkmax
you can set the default value with empty_data
您可以设置默认值 empty_data
$builder->add('myField', 'number', ['empty_data' => 'Default value'])
回答by stefancarlton
I've contemplated this a few times in the past so thought I'd jot down the different ideas I've had / used. Something might be of use, but none are "perfect" Symfony2 solutions.
过去我已经考虑过几次,所以我想记下我曾经/使用过的不同想法。有些东西可能有用,但没有一个是“完美的”Symfony2 解决方案。
ConstructorIn the Entity you can do $this->setBar('default value'); but this is called every time you load the entity (db or not) and is a bit messy. It does however work for every field type as you can create dates or whatever else you need.
构造函数在实体中你可以做 $this->setBar('default value'); 但是每次加载实体(db 与否)时都会调用它,这有点混乱。然而,它确实适用于每种字段类型,因为您可以创建日期或其他任何您需要的内容。
If statements within get'sI wouldn't, but you could.
如果 get 中的语句我不会,但你可以。
return ( ! $this->hasFoo() ) ? 'default' : $this->foo;
Factory / instance. Call a static function / secondary class which provides you a default Entity pre-populated with data. E.g.
工厂/实例。调用一个静态函数/辅助类,它为您提供一个预填充数据的默认实体。例如
function getFactory() {
$obj = new static();
$obj->setBar('foo');
$obj->setFoo('bar');
return $obj;
}
Not really ideal given you'll have to maintain this function if you add extra fields, but it does mean you're separating the data setters / default and that which is generated from the db. Similarly you can have multiple getFactories should you want different defaulted data.
如果您添加额外的字段,则必须维护此功能,这并不理想,但这确实意味着您将数据设置器/默认值与从数据库生成的数据集。同样,如果您想要不同的默认数据,您可以拥有多个 getFactories。
Extended / Reflection entitiesCreate a extending Entity (e.g. FooCreate extends Foo) which gives you the defaulted data at create time (through the constructor). Similar to the Factory / instance idea just a different approach - I prefer static methods personally.
扩展/反射实体创建一个扩展实体(例如 FooCreate extends Foo),它在创建时(通过构造函数)为您提供默认数据。类似于工厂/实例的想法只是一种不同的方法 - 我个人更喜欢静态方法。
Set Data before build formIn the constructors / service, you know if you have a new entity or if it was populated from the db. It's plausible therefore to call set data on the different fields when you grab a new entity. E.g.
在构建表单之前设置数据在构造函数/服务中,您知道是否有一个新实体或者它是否是从数据库填充的。因此,当您获取新实体时,在不同字段上调用设置数据是合理的。例如
if( ! $entity->isFromDB() ) {
$entity->setBar('default');
$entity->setDate( date('Y-m-d');
...
}
$form = $this->createForm(...)
Form EventsWhen you create the form you set default data when creating the fields. You override this use PreSetData event listener. The problem with this is that you're duplicating the form workload / duplicating code and making it harder to maintain / understand.
表单事件创建表单时,您会在创建字段时设置默认数据。您覆盖此使用 PreSetData 事件侦听器。这样做的问题是您正在复制表单工作负载/复制代码,并使维护/理解变得更加困难。
Extended formsSimilar to Form events, but you call the different type depending on if it's a db / new entity. By this I mean you have FooType which defines your edit form, BarType extends FooType this and sets all the data to the fields. In your controller you then simply choose which form type to instigate. This sucks if you have a custom theme though and like events, creates too much maintenance for my liking.
扩展形式类似于 Form 事件,但你调用不同的类型取决于它是否是一个 db / new 实体。我的意思是你有 FooType 来定义你的编辑表单,BarType 扩展了 FooType 并将所有数据设置到字段中。在您的控制器中,您只需选择要启动的表单类型。如果您有自定义主题并且喜欢活动,这会很糟糕,这会为我的喜好创建过多的维护。
TwigYou can create your own theme and default the data using the value option too when you do it on a per-field basis. There is nothing stopping you wrapping this into a form theme either should you wish to keep your templates clean and the form reusable. e.g.
Twig您可以创建自己的主题,并在按字段执行时也使用 value 选项默认数据。如果您希望保持模板干净并且表单可重用,没有什么可以阻止您将其包装到表单主题中。例如
form_widget(form.foo, {attr: { value : default } });
JSIt'd be trivial to populate the form with a JS function if the fields are empty. You could do something with placeholders for example. This is a bad, bad idea though.
JS如果字段为空,用 JS 函数填充表单将是微不足道的。例如,您可以使用占位符做一些事情。不过,这是一个坏主意。
Forms as a serviceFor one of the big form based projects I did, I created a service which generated all the forms, did all the processing etc. This was because the forms were to be used across multiple controllers in multiple environments and whilst the forms were generated / handled in the same way, they were displayed / interacted with differently (e.g. error handling, redirections etc). The beauty of this approach was that you can default data, do everything you need, handle errors generically etc and it's all encapsulated in one place.
表单即服务对于我所做的一个基于表单的大型项目,我创建了一个服务来生成所有表单,完成所有处理等。这是因为表单将在多个环境中的多个控制器之间使用,而表单以相同的方式生成/处理,它们以不同的方式显示/交互(例如错误处理、重定向等)。这种方法的美妙之处在于你可以默认数据,做你需要的一切,一般地处理错误等,并且所有这些都封装在一个地方。
ConclusionAs I see it, you'll run into the same issue time and time again - where is the defaulted data to live?
结论正如我所见,您会一次又一次地遇到同样的问题——默认数据在哪里?
- If you store it at db/doctrine level what happens if you don't want to store the default every time?
- If you store it at Entity level what happens if you want to re-use that entity elsewhere without any data in it?
- If you store it at Entity Level and add a new field, do you want the previous versions to have that default value upon editing? Same goes for the default in the DB...
- If you store it at the form level, is that obvious when you come to maintain the code later?
- If it's in the constructor what happens if you use the form in multiple places?
- If you push it to JS level then you've gone too far - the data shouldn't be in the view never mind JS (and we're ignoring compatibility, rendering errors etc)
- The service is great if like me you're using it in multiple places, but it's overkill for a simple add / edit form on one site...
- 如果您将它存储在 db/doctrine 级别,如果您不想每次都存储默认值会发生什么?
- 如果您将它存储在实体级别,如果您想在没有任何数据的情况下在其他地方重用该实体,会发生什么?
- 如果您将它存储在实体级别并添加一个新字段,您是否希望以前的版本在编辑时具有该默认值?数据库中的默认设置也是如此......
- 如果将其存储在表单级别,那么在以后维护代码时会很明显吗?
- 如果它在构造函数中,如果在多个地方使用表单会发生什么?
- 如果你把它推到 JS 级别,那么你就走得太远了——数据不应该在视图中,不管 JS(我们忽略了兼容性、渲染错误等)
- 如果您像我一样在多个地方使用它,那么该服务很棒,但是对于一个站点上的简单添加/编辑表单来说,它是多余的...
To that end, I've approached the problem differently each time. For example, a signup form "newsletter" option is easily (and logically) set in the constructor just before creating the form. When I was building forms collections which were linked together (e.g. which radio buttons in different form types linked together) then I've used Event Listeners. When I've built a more complicated entity (e.g. one which required children or lots of defaulted data) I've used a function (e.g. 'getFactory') to create it element as I need it.
为此,我每次都以不同的方式处理这个问题。例如,在创建表单之前,可以在构造函数中轻松(且逻辑地)设置注册表单“新闻通讯”选项。当我构建链接在一起的表单集合(例如,不同表单类型中的哪些单选按钮链接在一起)时,我使用了事件侦听器。当我构建了一个更复杂的实体(例如,需要子项或大量默认数据的实体)时,我使用了一个函数(例如“getFactory”)来根据需要创建它的元素。
I don't think there is one "right" approach as every time I've had this requirement it's been slightly different.
我不认为有一种“正确”的方法,因为每次我有这个要求时都会略有不同。
Good luck! I hope I've given you some food for thought at any rate and didn't ramble too much ;)
祝你好运!无论如何,我希望我已经给了你一些值得深思的东西,并且没有啰嗦太多;)
回答by Dmitriy
If you need to set default value and your form relates to the entity, then you should use following approach:
如果您需要设置默认值并且您的表单与实体相关,那么您应该使用以下方法:
// buildForm() method
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
...
->add(
'myField',
'text',
array(
'data' => isset($options['data']) ? $options['data']->getMyField() : 'my default value'
)
);
}
Otherwise, myField
always will be set to default value, instead of getting value from entity.
否则,myField
始终将设置为默认值,而不是从实体中获取值。
回答by Jakub Zalas
You can set the default for related field in your model class (in mapping definition or set the value yourself).
您可以为模型类中的相关字段设置默认值(在映射定义中或自己设置值)。
Furthermore, FormBuilder gives you a chance to set initial values with setData()method. Form builder is passed to the createForm()method of your form class.
此外,FormBuilder 为您提供了使用setData()方法设置初始值的机会。表单构建器被传递给表单类的createForm()方法。
Also, check this link: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class
另外,请检查此链接:http: //symfony.com/doc/current/book/forms.html#using-a-form-without-a-class
回答by Hubert Perron
If your form is bound to an entity, just set the default value on the entity itself using the construct method:
如果您的表单绑定到一个实体,只需使用构造方法在实体本身上设置默认值:
public function __construct()
{
$this->field = 'default value';
}
回答by crysallus
Approach 1 (from http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms/)
方法 1(来自http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms/)
Simply set the default value in your entity, either in the variable declaration or the constructor:
只需在您的实体中设置默认值,无论是在变量声明中还是在构造函数中:
class Entity {
private $color = '#0000FF';
...
}
or
或者
class Entity {
private $color;
public function __construct(){
$this->color = '#0000FF';
...
}
...
}
Approach 2 from a comment in the above link, and also Dmitriy's answer (not the accepted one) from How to set default value for form field in Symfony2?
来自上述链接中的评论的方法 2,以及来自How to set default value for form field in Symfony2?
Add the default value to the data attribute when adding the field with the FormBuilder, adapted from Dmitriy's answer.
使用 FormBuilder 添加字段时,将默认值添加到 data 属性,改编自 Dmitriy 的回答。
Note that this assumes that the property will and will only havethe value null when it's a new, and not an existing, entity.
请注意,这假设该属性将并且仅在它是新实体而非现有实体时才具有null 值。
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'
)
);
}
回答by Gottlieb Notschnabel
You can set a default value, e.g. for the form message
, like this:
您可以设置默认值,例如为 form 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();
In case your form is mapped to an Entity, you can go like this (e.g. default username):
如果你的表单被映射到一个实体,你可以这样(例如默认用户名):
$user = new User();
$user->setUsername('John Doe');
$form = $this->createFormBuilder($user)
->add('username')
->getForm();
回答by yceruto
A general solution for any case/approach, mainly by using a form without a class or when we need access to any services to set the default value:
任何情况/方法的通用解决方案,主要是通过使用没有类的表单或当我们需要访问任何服务来设置默认值时:
// 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;
}
}
and register the form extension:
并注册表单扩展名:
app.form_type_extension:
class: App\Form\Extension\DefaultFormTypeExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }
After that, we can use default
option in any form field:
之后,我们可以default
在任何表单字段中使用选项:
$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));
回答by cure85
Don't use:
不要使用:
'data' => 'Default value'
Read here: https://symfony.com/doc/current/reference/forms/types/form.html#data
在这里阅读:https: //symfony.com/doc/current/reference/forms/types/form.html#data
"The data option always overrides the value taken from the domain data (object) when rendering. This means the object value is also overriden when the form edits an already persisted object, causing it to lose its persisted value when the form is submitted."
“数据选项在渲染时总是覆盖从域数据(对象)中获取的值。这意味着当表单编辑一个已经持久化的对象时,对象值也会被覆盖,导致它在提交表单时丢失其持久化值。”
Use the following:
使用以下内容:
Lets say, for this example, you have an Entity Foo, and there is a field "active" (in this example is CheckBoxType, but process is the same to every other type), which you want to be checked by default
比方说,对于这个例子,你有一个实体 Foo,有一个字段“active”(在这个例子中是 CheckBoxType,但过程与其他所有类型相同),你希望默认选中它
In your FooFormType class add:
在您的 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',
));
}