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

有没有简单的方法来设置文本表单字段的默认值?

在创build过程中可以轻松使用:

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

您可以使用empty_data设置默认值

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

过去我已经考虑了几次,所以我想记下我曾经使用过的不同想法。 有些东西可能是有用的,但没有一个是“完美”的Symfony2解决scheme。

构造函数在实体中,您可以执行$ this-> setBar('default value'); 但是每当你加载实体(db或不)时都会调用它,而且有点麻烦。 但是,它确实适用于每种字段types,因为您可以创builddate或其他任何您需要的内容。

如果得到的内容我不会,但你可以。

 return ( ! $this->hasFoo() ) ? 'default' : $this->foo; 

工厂/实例 。 调用一个静态函数/辅助类,为您提供一个预先填充了数据的默认实体。 例如

 function getFactory() { $obj = new static(); $obj->setBar('foo'); $obj->setFoo('bar'); return $obj; } 

如果你添加额外的字段,你不得不维护这个函数,但是这确实意味着你正在分离数据设置器/默认值和从db生成的值。 同样,如果你想要不同的默认数据,你可以有多个getFactories。

扩展/reflection实体创build一个扩展实体(例如FooCreate extends Foo),它在创build时(通过构造函数)为您提供默认数据。 类似工厂/实例的想法只是一个不同的方法 – 我个人更喜欢静态方法。

在构build表单前设置数据在构造函数/服务中,您知道是否有新的实体或者是否从数据库中填充数据。 因此,当您抓住一个新的实体时,在不同的字段上调用set数据是合理的。 例如

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

表单事件创build表单时,您可以在创build字段时设置默认数据。 您可以覆盖此使用PreSetData事件侦听器。 这个问题是,你复制表单工作量/重复代码,并使其难以维护/理解。

扩展表单与表单事件类似,但根据是否是db / new实体,调用不同的types。 通过这个我的意思是你有FooType定义你的编辑forms,BarType扩展FooType这个,并设置所有的数据到字段。 在你的控制器中,你只需select哪种表单types来煽动。 这很糟糕,如果你有一个自定义的主题,但喜欢事件,创造了太多的维护,我喜欢。

小枝您可以创build自己的主题,并在每个字段的基础上使用值选项默认数据。 没有什么能阻止你把这个包装成一个表单主题,要么你希望保持你的模板清洁和表单可重用。 例如

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

JS如果字段是空的,用JS函数填充表单是很简单的。 例如,你可以用占位符做些事情。 这是一个糟糕的主意。

表单作为服务对于我做的一个基于大表单的项目,我创build了一个生成所有表单的服务,完成了所有的处理等。这是因为表单在多个环境中跨多个控制器使用,而表单以相同的方式生成/处理,它们以不同的方式显示/交互(例如error handling,redirect等)。 这种方法的优点是,你可以默认数据,做你需要的一切,一般处理错误等,它都封装在一个地方。

结论正如我所看到的那样,您会一次又一次遇到同样的问题 – 缺省数据在哪里生存?

  • 如果将它存储在db / doctrine级别,如果不想每次都存储默认值,会发生什么情况?
  • 如果将其存储在实体级别,如果您要在其他位置重新使用该实体而没有任何数据,会发生什么情况?
  • 如果将其存储在实体级别并添加一个新字段,那么是否希望在编辑时以前的版本具有该默认值? 数据库中的默认值也一样
  • 如果你将它存储在表单级别,那么当你稍后维护代码时,这一点是显而易见的吗?
  • 如果在构造函数中,如果在多个位置使用表单,会发生什么情况?
  • 如果你把它推到JS级别,那么你已经走得太远 – 数据不应该在视图中,不要介意JS(我们忽略兼容性,渲染错误等)
  • 如果像我这样的服务在多个地方使用它,服务是非常棒的,但是在一个站点上使用一个简单的添加/编辑表单就太过分了…

为此,我每次都以不同的方式处理这个问题。 例如,在创build表单之前,registry单“newsletter”选项很容易(也是逻辑上)在构造函数中设置。 当我build立链接在一起的表单集合(例如,链接在一起的不同表单types的单选button)时,我使用了事件侦听器。 当我构build了一个更复杂的实体(比如一个需要孩子或者很多默认数据的实体)时,我使用了一个函数(例如'getFactory')来创build它。

我不认为有一个“正确”的方法,因为每次我有这个要求,它有一点点不同。

祝你好运! 我希望我无论如何也给了你一些想法,而且没有太多赘述;)

如果您需要设置默认值,并且您的表单与实体相关,那么您应该使用以下方法:

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

您可以在模型类中设置相关字段的默认值(在映射定义中或者自己设置值)。

此外,FormBuilder为您提供了使用setData()方法设置初始值的机会。 表单构build器被传递给表单类的createForm()方法。

此外,请检查此链接: http : //symfony.com/doc/current/book/forms.html#using-a-form-without-a-class

如果表单绑定到实体,只需使用构造方法在实体本身上设置默认值:

 public function __construct() { $this->field = 'default value'; } 

方法1(来自http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms/

只需在variables声明或构造函数中设置实体的默认值即可:

 class Entity { private $color = '#0000FF'; ... } 

要么

 class Entity { private $color; public function __construct(){ $this->color = '#0000FF'; ... } ... } 

从上面的链接评论方法2,也是德米特里的答案(而不是接受的)从如何设置表单字段在Symfony2的默认值?

当添加字段与FormBuilder,从德米特里的答案改编的数据属性添加默认值。

请注意,这是假设属性将只有值为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' ) ); } 

您可以设置一个默认值,例如表单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(); 

任何情况/方法的一般解决scheme,主要是使用一个没有类的表单,或者当我们需要访问任何服务来获得默认值时:

 class FormTypeExtension 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; } } 

并registry单扩展名:

 app.form_type_extension: class: AdminBundle\Form\Extension\BootstrapAdminFormTypeExtension 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')); 
 ->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)); } }); 

就这样我理解这个问题。

您希望根据实体中的数据调整表单的构build方式。 如果实体正在被创build,那么使用一些默认值。 如果实体存在,则使用数据库值。

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

相反,你可以按照这个: http : //symfony.com/doc/currentbook/form/dynamic_form_modification.html

你可以在你的表单types上挂一个监听器,然后你可以检查你的实体并调整builder->相应地添加一个新的或现有的实体。 您仍然需要在某处指定您的默认值,尽pipe您可以将它们编码到侦听器中。 或者将它们传递给表单types。

看起来像很多工作,虽然。 最好只是将实体传递给已经设置了默认值的表单。

如果您在symfony 2.7中使用FormBuilder来生成表单,则还可以将初始数据传递给控制器​​的createFormBuilder方法

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

我的解决scheme

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

通常,对于表单i的init默认值使用fixtures。 因为这种方式不是最简单的,但很舒服。

例:

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

然而,symfonytypes字段有选项数据 。

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

有一个非常简单的方法,你可以在这里设置默认值:

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

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

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

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

一个例子:

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

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

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

这将适用于新logging或者只是更新现有的logging。

如果您在创build表单中设置了“数据”,则在编辑您的实体时,此值不会被修改。

我的解决scheme是:

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

再见。

Brian问道:

当提交没有值时,empty_data似乎只将字段设置为1。 那么当你希望表单默认在没有值的情况下在input中显示1时呢?

您可以使用empty_value设置默认值

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