如何在Symfony2中设置表单字段的默认值?

时间:2022-10-16 18:01:23

Is there an easy way to set a default value for text form field?

是否有一个简单的方法来设置文本表单字段的默认值?

21 个解决方案

#1


100  

Can be use during the creation easily with :

在创作过程中容易使用:

->add('myfield', 'text', array(
     'label' => 'Field',
     'data' => 'Default value'
))

#2


104  

you can set the default value with empty_data

您可以使用empty_data设置默认值。

$builder->add('myField', 'number', ['empty_data' => 'Default value'])

#3


56  

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解决方案。

Constructor In 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('默认值');但是每次加载实体(db或not)时,都会调用这个函数,并且有点混乱。但是,它确实适用于每个字段类型,因为您可以创建日期或其他您需要的其他类型。

If statements within get's I wouldn't, but you could.

如果在得到的情况下,我不会,但是你可以。

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.

如果你添加了额外的字段,你将不得不维护这个函数,但它确实意味着你要分离数据setter /默认值和由db生成的数据。类似地,如果需要不同的默认数据,也可以有多个getfactory。

Extended / Reflection entities Create 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扩展Foo),它在创建时(通过构造函数)提供默认数据。类似于工厂/实例的想法只是一个不同的方法——我个人更喜欢静态方法。

Set Data before build form In 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.

在构造函数/服务的构建形式之前设置数据,您知道如果您有一个新实体,或者它是由db填充的。因此,当您获取一个新实体时,调用在不同字段上的set数据是合理的。如。

if( ! $entity->isFromDB() ) {
     $entity->setBar('default');
     $entity->setDate( date('Y-m-d');
     ...
}
$form = $this->createForm(...)

Form Events When 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.

在创建字段时,创建表单时设置默认数据。您可以覆盖这个use PreSetData事件监听器。这样做的问题是,您正在复制表单工作负载/复制代码,使其更难维护/理解。

Extended forms Similar 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.

扩展的表单类似于表单事件,但如果是db / new实体,则调用不同类型。我的意思是,你有一个FooType定义了你的编辑表单,BarType扩展了FooType,并将所有数据设置为字段。在您的控制器中,您只需选择要发起的表单类型。如果您有一个定制的主题,并且喜欢事件,这就很糟糕了,因为我喜欢的东西太多了。

Twig You 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可以创建自己的主题,并在每个字段的基础上使用值选项来默认数据。没有什么可以阻止您将它包装成一个表单主题,或者您希望保持模板的整洁和表单可重用。如。

form_widget(form.foo, {attr: { value : default } });

JS It'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函数填充表单是很简单的。例如,你可以用占位符做一些事情。这是个坏主意。

Forms as a service For 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.

形式作为最大的基于表单的服务项目,我创建了一个服务产生的所有形式,做了所有处理等。这是因为表单要使用多个控制器在多个环境中,而表单生成/以同样的方式处理,他们显示/与不同(例如,错误处理,重定向等)。这种方法的好处是可以默认数据,做你需要的一切,处理错误,等等,这些都封装在一个地方。

Conclusion As 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?
  • 如果您将它存储在db/doctrine级别,如果您不希望每次都存储默认值,会发生什么情况呢?
  • 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...
  • 如果您将其存储在实体级别并添加一个新字段,那么您是否希望在编辑时使用以前的版本具有该默认值?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)
  • 如果你把它推到JS级别,那么你就做得太过了——数据不应该在视图中,而不是JS(我们忽略了兼容性、渲染错误等)
  • 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...
  • 如果你像我一样在多个地方使用它,那么这个服务很好,但是在一个网站上添加/编辑表单就太过了……

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”(getFactory),以创建所需的it元素。

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 ;)

好运!我希望我已经给了你一些可以考虑的食物,而且没有太多的漫谈;

#4


39  

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将被设置为默认值,而不是从实体获取值。

#5


19  

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# usinga-withouta -class。

#6


16  

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

#7


11  

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,以及在Symfony2中如何设置表单字段的默认值的方法(不是接受的)。

Add the default value to the data attribute when adding the field with the FormBuilder, adapted from Dmitriy's answer.

在将字段添加到FormBuilder时,将默认值添加到数据属性中,并根据Dmitriy的答案进行修改。

Note that this assumes that the property will and will only have the value null when it's a new, and not an existing, entity.

请注意,这假定属性将并且只在它是一个新实体时才具有值为空,而不是现有的实体。

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

#8


9  

You can set a default value, e.g. for the form message, like this:

您可以设置一个默认值,例如:表单消息:

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

#9


9  

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:

在此之后,我们可以在任何表单字段中使用默认选项:

$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));

#10


5  

->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
     $form = $event->getForm(); 
     $data = $event->getData(); 

     if ($data == null) {
         $form->add('position', IntegerType::class, array('data' => 0));
     }

});

#11


4  

Just so I understand the problem.

所以我理解了这个问题。

You want to adjust the way the form is built based on data in your entity. If the entity is being created then use some default value. If the entity is existing use the database value.

您需要根据实体中的数据来调整表单的构建方式。如果正在创建实体,则使用一些默认值。如果实体存在,则使用数据库值。

Personally, I think @MolecularMans's solution is the way to go. I would actually set the default values in the constructor or in the property statement. But you don't seem to like that approach.

就我个人而言,我认为@ ularmans的解决方案是可行的。实际上,我将在构造函数或属性语句中设置默认值。但你似乎不喜欢这种方式。

Instead you can follow this: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

相反,您可以这样做:http://symfony.com/doc/current/cookbook/form/dynamic_form_modific.html。

You hang a listener on your form type and you can then examine your entity and adjust the builder->add statements accordingly based on havine a new or existing entity. You still need to specify your default values somewhere though you could just code them in your listener. Or pass them into the form type.

您将一个侦听器挂在窗体类型上,然后您可以检查您的实体并调整构建器->根据havine一个新的或现有的实体来相应地添加语句。您仍然需要在某处指定默认值,尽管您可以将它们编码到您的侦听器中。或者将它们传递到表单类型中。

Seems like a lot of work though. Better to just pass the entity to the form with it's default values already set.

但似乎有很多工作要做。最好只是将实体传递给表单,而默认值已经设置好了。

#12


4  

If you're using a FormBuilder in symfony 2.7 to generate the form, you can also pass the initial data to the createFormBuilder method of the Controler

如果您使用symfony 2.7中的FormBuilder生成表单,您也可以将初始数据传递给Controler的createFormBuilder方法。

$values = array(
    'name' => "Bob"
);

$formBuilder = $this->createFormBuilder($values);
$formBuilder->add('name', 'text');

#13


3  

My solution:

我的解决方案:

$defaultvalue = $options['data']->getMyField();
$builder->add('myField', 'number', array(
            'data' => !empty($defaultvalue) ? $options['data']->getMyField() : 0
        )) ;

#14


3  

Often, for init default values of form i use fixtures. Of cause this way is not easiest, but very comfortable.

通常,对于init的默认值,我使用固定格式。这样做并不容易,但很舒服。

Example:

例子:

class LoadSurgeonPlanData implements FixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $surgeonPlan = new SurgeonPlan();

        $surgeonPlan->setName('Free trial');
        $surgeonPlan->setPrice(0);
        $surgeonPlan->setDelayWorkHours(0);
        $surgeonPlan->setSlug('free');

        $manager->persist($surgeonPlan);
        $manager->flush();        
    }   
}

Yet, symfony type field have the option data.

然而,symfony类型字段具有选项数据。

Example

例子

$builder->add('token', 'hidden', array(
    'data' => 'abcdef',
));

#15


3  

There is a very simple way, you can set defaults as here :

有一个很简单的方法,你可以设置默认值

$defaults = array('sortby' => $sortby,'category' => $category,'page' => 1);

$form = $this->formfactory->createBuilder('form', $defaults)
->add('sortby','choice')
->add('category','choice')
->add('page','hidden')
->getForm();

#16


2  

If you set 'data' in your creation form, this value will be not modified when edit your entity.

如果您在创建表单中设置了“data”,那么在编辑您的实体时,这个值将不会被修改。

My solution is :

我的解决方案是:

public function buildForm(FormBuilderInterface $builder, array $options) {
    // In my example, data is an associated array
    $data = $builder->getData();

    $builder->add('myfield', 'text', array(
     'label' => 'Field',
     'data' => array_key_exits('myfield', $data) ? $data['myfield'] : 'Default value',
    ));
}

Bye.

再见。

#17


2  

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数据

"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."

“数据选项总是覆盖在呈现时从域数据(对象)获取的值。这意味着当表单编辑一个已经存在的对象时,对象值也是overriden,导致它在表单提交时丢失其持久值。


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())) $data->setActive(true);
        }
   );
}
public function configureOptions( OptionsResolver $resolver )
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle:Foo',
    ));
}

#18


1  

Default values are set by configuring corresponding entity. Before binding the entity to form set its color field to "#0000FF":

默认值是通过配置相应的实体来设置的。在绑定实体之前,将其颜色字段设置为“#0000FF”:

// controller action
$project = new Project();
$project->setColor('#0000FF');
$form = $this->createForm(new ProjectType(), $project);

#19


1  

If that field is bound to an entity (is a property of that entity) you can just set a default value for it.

如果该字段绑定到实体(是该实体的属性),则可以为其设置默认值。

An example:

一个例子:

public function getMyField() {
    if (is_null($this->MyField)) {
        $this->setMyField('my default value');
    }
    return $this->MyField;
}

#20


1  

I usually just set the default value for specific field in my entity:

我通常只是为实体中的特定字段设置默认值:

/**
 * @var int
 * @ORM\Column(type="integer", nullable=true)
 */
protected $development_time = 0;

This will work for new records or if just updating existing ones.

这将用于新记录,或者只是更新现有记录。

#21


1  

As Brian asked:

布莱恩问:

empty_data appears to only set the field to 1 when it is submitted with no value. What about when you want the form to default to displaying 1 in the input when no value is present?

empty_data似乎只在没有值的情况下将字段设置为1。如果您希望表单在没有任何值的情况下显示1,那该怎么办呢?

you can set the default value with empty_value

您可以使用empty_value设置默认值。

$builder->add('myField', 'number', ['empty_value' => 'Default value'])

#1


100  

Can be use during the creation easily with :

在创作过程中容易使用:

->add('myfield', 'text', array(
     'label' => 'Field',
     'data' => 'Default value'
))

#2


104  

you can set the default value with empty_data

您可以使用empty_data设置默认值。

$builder->add('myField', 'number', ['empty_data' => 'Default value'])

#3


56  

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解决方案。

Constructor In 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('默认值');但是每次加载实体(db或not)时,都会调用这个函数,并且有点混乱。但是,它确实适用于每个字段类型,因为您可以创建日期或其他您需要的其他类型。

If statements within get's I wouldn't, but you could.

如果在得到的情况下,我不会,但是你可以。

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.

如果你添加了额外的字段,你将不得不维护这个函数,但它确实意味着你要分离数据setter /默认值和由db生成的数据。类似地,如果需要不同的默认数据,也可以有多个getfactory。

Extended / Reflection entities Create 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扩展Foo),它在创建时(通过构造函数)提供默认数据。类似于工厂/实例的想法只是一个不同的方法——我个人更喜欢静态方法。

Set Data before build form In 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.

在构造函数/服务的构建形式之前设置数据,您知道如果您有一个新实体,或者它是由db填充的。因此,当您获取一个新实体时,调用在不同字段上的set数据是合理的。如。

if( ! $entity->isFromDB() ) {
     $entity->setBar('default');
     $entity->setDate( date('Y-m-d');
     ...
}
$form = $this->createForm(...)

Form Events When 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.

在创建字段时,创建表单时设置默认数据。您可以覆盖这个use PreSetData事件监听器。这样做的问题是,您正在复制表单工作负载/复制代码,使其更难维护/理解。

Extended forms Similar 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.

扩展的表单类似于表单事件,但如果是db / new实体,则调用不同类型。我的意思是,你有一个FooType定义了你的编辑表单,BarType扩展了FooType,并将所有数据设置为字段。在您的控制器中,您只需选择要发起的表单类型。如果您有一个定制的主题,并且喜欢事件,这就很糟糕了,因为我喜欢的东西太多了。

Twig You 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可以创建自己的主题,并在每个字段的基础上使用值选项来默认数据。没有什么可以阻止您将它包装成一个表单主题,或者您希望保持模板的整洁和表单可重用。如。

form_widget(form.foo, {attr: { value : default } });

JS It'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函数填充表单是很简单的。例如,你可以用占位符做一些事情。这是个坏主意。

Forms as a service For 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.

形式作为最大的基于表单的服务项目,我创建了一个服务产生的所有形式,做了所有处理等。这是因为表单要使用多个控制器在多个环境中,而表单生成/以同样的方式处理,他们显示/与不同(例如,错误处理,重定向等)。这种方法的好处是可以默认数据,做你需要的一切,处理错误,等等,这些都封装在一个地方。

Conclusion As 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?
  • 如果您将它存储在db/doctrine级别,如果您不希望每次都存储默认值,会发生什么情况呢?
  • 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...
  • 如果您将其存储在实体级别并添加一个新字段,那么您是否希望在编辑时使用以前的版本具有该默认值?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)
  • 如果你把它推到JS级别,那么你就做得太过了——数据不应该在视图中,而不是JS(我们忽略了兼容性、渲染错误等)
  • 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...
  • 如果你像我一样在多个地方使用它,那么这个服务很好,但是在一个网站上添加/编辑表单就太过了……

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”(getFactory),以创建所需的it元素。

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 ;)

好运!我希望我已经给了你一些可以考虑的食物,而且没有太多的漫谈;

#4


39  

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将被设置为默认值,而不是从实体获取值。

#5


19  

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# usinga-withouta -class。

#6


16  

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

#7


11  

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,以及在Symfony2中如何设置表单字段的默认值的方法(不是接受的)。

Add the default value to the data attribute when adding the field with the FormBuilder, adapted from Dmitriy's answer.

在将字段添加到FormBuilder时,将默认值添加到数据属性中,并根据Dmitriy的答案进行修改。

Note that this assumes that the property will and will only have the value null when it's a new, and not an existing, entity.

请注意,这假定属性将并且只在它是一个新实体时才具有值为空,而不是现有的实体。

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

#8


9  

You can set a default value, e.g. for the form message, like this:

您可以设置一个默认值,例如:表单消息:

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

#9


9  

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:

在此之后,我们可以在任何表单字段中使用默认选项:

$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));

#10


5  

->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
     $form = $event->getForm(); 
     $data = $event->getData(); 

     if ($data == null) {
         $form->add('position', IntegerType::class, array('data' => 0));
     }

});

#11


4  

Just so I understand the problem.

所以我理解了这个问题。

You want to adjust the way the form is built based on data in your entity. If the entity is being created then use some default value. If the entity is existing use the database value.

您需要根据实体中的数据来调整表单的构建方式。如果正在创建实体,则使用一些默认值。如果实体存在,则使用数据库值。

Personally, I think @MolecularMans's solution is the way to go. I would actually set the default values in the constructor or in the property statement. But you don't seem to like that approach.

就我个人而言,我认为@ ularmans的解决方案是可行的。实际上,我将在构造函数或属性语句中设置默认值。但你似乎不喜欢这种方式。

Instead you can follow this: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

相反,您可以这样做:http://symfony.com/doc/current/cookbook/form/dynamic_form_modific.html。

You hang a listener on your form type and you can then examine your entity and adjust the builder->add statements accordingly based on havine a new or existing entity. You still need to specify your default values somewhere though you could just code them in your listener. Or pass them into the form type.

您将一个侦听器挂在窗体类型上,然后您可以检查您的实体并调整构建器->根据havine一个新的或现有的实体来相应地添加语句。您仍然需要在某处指定默认值,尽管您可以将它们编码到您的侦听器中。或者将它们传递到表单类型中。

Seems like a lot of work though. Better to just pass the entity to the form with it's default values already set.

但似乎有很多工作要做。最好只是将实体传递给表单,而默认值已经设置好了。

#12


4  

If you're using a FormBuilder in symfony 2.7 to generate the form, you can also pass the initial data to the createFormBuilder method of the Controler

如果您使用symfony 2.7中的FormBuilder生成表单,您也可以将初始数据传递给Controler的createFormBuilder方法。

$values = array(
    'name' => "Bob"
);

$formBuilder = $this->createFormBuilder($values);
$formBuilder->add('name', 'text');

#13


3  

My solution:

我的解决方案:

$defaultvalue = $options['data']->getMyField();
$builder->add('myField', 'number', array(
            'data' => !empty($defaultvalue) ? $options['data']->getMyField() : 0
        )) ;

#14


3  

Often, for init default values of form i use fixtures. Of cause this way is not easiest, but very comfortable.

通常,对于init的默认值,我使用固定格式。这样做并不容易,但很舒服。

Example:

例子:

class LoadSurgeonPlanData implements FixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $surgeonPlan = new SurgeonPlan();

        $surgeonPlan->setName('Free trial');
        $surgeonPlan->setPrice(0);
        $surgeonPlan->setDelayWorkHours(0);
        $surgeonPlan->setSlug('free');

        $manager->persist($surgeonPlan);
        $manager->flush();        
    }   
}

Yet, symfony type field have the option data.

然而,symfony类型字段具有选项数据。

Example

例子

$builder->add('token', 'hidden', array(
    'data' => 'abcdef',
));

#15


3  

There is a very simple way, you can set defaults as here :

有一个很简单的方法,你可以设置默认值

$defaults = array('sortby' => $sortby,'category' => $category,'page' => 1);

$form = $this->formfactory->createBuilder('form', $defaults)
->add('sortby','choice')
->add('category','choice')
->add('page','hidden')
->getForm();

#16


2  

If you set 'data' in your creation form, this value will be not modified when edit your entity.

如果您在创建表单中设置了“data”,那么在编辑您的实体时,这个值将不会被修改。

My solution is :

我的解决方案是:

public function buildForm(FormBuilderInterface $builder, array $options) {
    // In my example, data is an associated array
    $data = $builder->getData();

    $builder->add('myfield', 'text', array(
     'label' => 'Field',
     'data' => array_key_exits('myfield', $data) ? $data['myfield'] : 'Default value',
    ));
}

Bye.

再见。

#17


2  

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数据

"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."

“数据选项总是覆盖在呈现时从域数据(对象)获取的值。这意味着当表单编辑一个已经存在的对象时,对象值也是overriden,导致它在表单提交时丢失其持久值。


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())) $data->setActive(true);
        }
   );
}
public function configureOptions( OptionsResolver $resolver )
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle:Foo',
    ));
}

#18


1  

Default values are set by configuring corresponding entity. Before binding the entity to form set its color field to "#0000FF":

默认值是通过配置相应的实体来设置的。在绑定实体之前,将其颜色字段设置为“#0000FF”:

// controller action
$project = new Project();
$project->setColor('#0000FF');
$form = $this->createForm(new ProjectType(), $project);

#19


1  

If that field is bound to an entity (is a property of that entity) you can just set a default value for it.

如果该字段绑定到实体(是该实体的属性),则可以为其设置默认值。

An example:

一个例子:

public function getMyField() {
    if (is_null($this->MyField)) {
        $this->setMyField('my default value');
    }
    return $this->MyField;
}

#20


1  

I usually just set the default value for specific field in my entity:

我通常只是为实体中的特定字段设置默认值:

/**
 * @var int
 * @ORM\Column(type="integer", nullable=true)
 */
protected $development_time = 0;

This will work for new records or if just updating existing ones.

这将用于新记录,或者只是更新现有记录。

#21


1  

As Brian asked:

布莱恩问:

empty_data appears to only set the field to 1 when it is submitted with no value. What about when you want the form to default to displaying 1 in the input when no value is present?

empty_data似乎只在没有值的情况下将字段设置为1。如果您希望表单在没有任何值的情况下显示1,那该怎么办呢?

you can set the default value with empty_value

您可以使用empty_value设置默认值。

$builder->add('myField', 'number', ['empty_value' => 'Default value'])