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

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

227883 次浏览

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

此外,FormBuilder 还提供了使用 SetData ()方法设置初始值的机会。表单生成器被传递给表单类的 CreateForm ()方法。

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

Can be use during the creation easily with :

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

如果你需要设定预设值,而你的表格与实体有关,你应采用以下方法:

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

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

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

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

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

进场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,也是德米特里的答案(不是接受的答案)从 如何在 Symfony2中设置表单字段的默认值?

在使用 FormBuilder 添加字段时,将默认值添加到 data 属性,这是根据 Dmitriy 的答案改编的。

请注意,当属性 将来也只会有是一个新实体而不是一个现有实体时,它假定值为 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'
)
);
}

这样我才能明白问题所在。

您希望根据实体中的数据调整窗体的生成方式。如果正在创建实体,那么使用一些默认值。如果实体存在,则使用数据库值。

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

相反,您可以遵循以下步骤: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

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

不过看起来工作量很大。最好只是将实体传递给已经设置了默认值的窗体。

在过去,我已经考虑过这个问题好几次了,所以我想我应该记下我已经有过或者使用过的不同的想法。有些东西可能是有用的,但没有一个是“完美的”Symfony2解决方案。

构造函数 在 Entity 中,您可以执行 $this-> setBar (‘ default value’) ; 但是每次加载实体(db 或者不加载)时都会调用这个命令,这有点麻烦。但是,它适用于每种字段类型,因为您可以创建日期或其他任何您需要的内容。

如果 get 中的语句 我不会,但你可以。

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

Factory/instance . 调用一个静态函数/辅助类,它为您提供了一个预填充了 data 的默认实体。

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


return $obj;
}

考虑到如果添加额外的字段就必须维护这个函数,这并不是很理想,但这确实意味着要将数据设置器/默认值与从数据库生成的数据分离开来。类似地,如果需要不同的默认数据,可以有多个 getFactory。

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

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

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

表格活动 创建表单时,在创建字段时设置默认数据。可以重写此命令,使用 PreSetData 事件侦听器。这样做的问题在于,您正在复制表单工作负载/复制代码,并使其更难维护/理解。

扩展表格 类似于 Form 事件,但是根据是否为 db/new 实体调用不同的类型。我的意思是,FooType 定义了编辑表单,BarType 扩展了 FooType,并将所有数据设置为字段。然后在控制器中简单地选择要启动的窗体类型。如果你有一个自定义的主题和喜欢的事件,这是糟糕的,但创建太多的维护我的喜好。

小树枝 您可以创建自己的主题,也可以使用 value 选项在每个字段的基础上创建数据。如果您希望保持模板的整洁和表单的可重用性,那么没有什么可以阻止您将其封装到表单主题中。例如:。

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

JS 如果字段为空,那么使用 JS 函数填充表单就很简单了。例如,您可以对占位符进行处理。这是个非常非常糟糕的主意。

表单作为服务 对于我做的一个基于表单的大型项目,我创建了一个服务来生成所有的表单,进行所有的处理等等。这是因为表单要在多个环境中的多个控制器之间使用,虽然表单的生成/处理方式相同,但显示/交互方式不同(如错误处理、重定向等)。这种方法的优点是,您可以默认数据,做所有您需要的事情,通用地处理错误等,并且它们都封装在一个地方。

结论 在我看来,您将一次又一次地遇到同样的问题——默认的数据存放在哪里?

  • 如果将它存储在 db/主义级别,如果不想每次都存储默认值,会发生什么情况?
  • 如果您将它存储在实体级别,那么如果您想在其他地方重用该实体而不在其中使用任何数据,会发生什么情况?
  • 如果将其存储在实体级并添加一个新字段,是否希望以前的版本在编辑时具有该默认值?数据库的默认设置也是如此..。
  • 如果您将它存储在表单级别,那么在以后维护代码时,这一点是否明显?
  • 如果它在构造函数中,那么如果在多个位置使用表单会发生什么?
  • 如果你把它推到 JS 级别,那么你已经走得太远了——数据不应该在视图中,更不用说 JS 了(我们忽略了兼容性,呈现错误等)
  • 这项服务是伟大的,如果像我一样,你正在使用它在多个地方,但它是一个简单的添加/编辑形式在一个网站杀伤力..。

为此,我每次都以不同的方式处理这个问题。例如,在创建表单之前,在构造函数中很容易(并且逻辑上)设置注册表单“新闻通讯”选项。当我构建被链接在一起的表单集合时(例如,链接在一起的不同表单类型的单选按钮) ,我使用了事件监听器。当我构建了一个更复杂的实体(例如需要子实体或大量默认数据的实体)时,我会使用一个函数(例如‘ getFactory’)根据需要创建它的元素。

我不认为有一个“正确”的方法,因为每次我有这个需求的时候,它都略有不同。

祝你好运! 我希望我已经给了你一些值得思考的东西,而且没有说得太多;)

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

我的解决办法是:

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

可以使用 empty_data设置默认值

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

如果该字段绑定到一个实体(是该实体的属性) ,只需为其设置默认值。

举个例子:

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

通常,对于表单的 init 默认值,我使用 fixture。

例如:

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

然而,symfony 类型字段有选项 资料

例子

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

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

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

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

如果在 symfony 2.7中使用 FormBuilder生成表单,还可以将初始数据传递给 Controller 的 createFormBuilder方法

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


$formBuilder = $this->createFormBuilder($values);
$formBuilder->add('name', 'text');
->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));
}


});

任何情况/方法的通用解决方案,主要是通过使用没有类的表单,或者当我们需要访问任何服务来设置默认值时:

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

正如布莱恩所问:

当提交的字段没有值时,似乎只将该字段设置为1。 如果希望窗体默认显示为在 当没有值的时候输入?

可以使用 empty_value设置默认值

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

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

我的解决办法是:

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

再见。

不要使用:

'data' => 'Default value'

阅读此处: https://symfony.com/doc/current/reference/forms/types/form.html#data

”数据选项在呈现时总是重写从域数据(对象)获取的值。这意味着当表单编辑一个已经持久化的对象时,对象值也会被重写,导致在提交表单时它失去其持久化值。”


使用以下方法:

假设在这个示例中,您有一个 Entity Foo,并且有一个字段“ active”(在这个示例中是 CheckBoxType,但是 process 对于其他所有类型都是相同的) ,您希望在默认情况下检查该字段

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

我通过在 攻击中加入 价值解决了这个问题:

->add('projectDeliveringInDays', null, [
'attr' => [
'min'=>'1',
'value'=>'1'
]
])