有没有一种简单的方法可以为文本表单字段设置默认值?
有没有一种简单的方法可以为文本表单字段设置默认值?
Answers:
可以在创建过程中轻松使用:
->add('myfield', 'text', array(
'label' => 'Field',
'empty_data' => 'Default value'
))
'data'
密钥更改为'value'
empty_data
data
没有用-它会覆盖保存的值。empty_data
不显示该值,而是将其用于空值提交,并且无法保存未经检查的选择。
您可以使用设置默认值 empty_data
$builder->add('myField', 'number', ['empty_data' => 'Default value'])
我过去曾多次考虑过这一点,因此以为我记下了我曾经/曾经使用过的不同想法。可能有用,但是没有一个是“完美的” Symfony2解决方案。
构造函数 在Entity中,您可以执行$ this-> setBar('default value');。但这在每次加载实体(无论是否加载db)时都会调用,并且有点混乱。但是,它确实适用于每种字段类型,因为您可以创建日期或其他所需的内容。
如果get中的语句 不是,但可以。
return ( ! $this->hasFoo() ) ? 'default' : $this->foo;
工厂/实例。调用静态函数/辅助类,该类为您提供一个预填充了数据的默认实体。例如
function getFactory() {
$obj = new static();
$obj->setBar('foo');
$obj->setFoo('bar');
return $obj;
}
如果添加额外的字段,您必须维护此功能,这并不是很理想,但这确实意味着您要分隔数据设置器/默认值和从数据库生成的值。同样,如果您需要不同的默认数据,则可以有多个getFactories。
扩展/反射实体 创建一个扩展实体(例如FooCreate扩展Foo),该实体在创建时(通过构造函数)为您提供默认数据。与工厂/实例的想法类似,只是一种不同的方法-我个人更喜欢静态方法。
在构建表单之前设置数据在 构造函数/服务中,您知道是否有新实体,或者是否从数据库中填充了它。因此,当您获取一个新实体时,在不同的字段上调用集合数据是合理的。例如
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函数填充表单很简单。例如,您可以使用占位符。但是,这是一个坏主意。
表单即服务 对于我所做的基于大型表单的项目之一,我创建了一个服务,该服务生成所有表单,进行所有处理等。这是因为表单要在多个环境中的多个控制器之间使用,而表单以相同的方式生成/处理,它们以不同的方式显示/交互(例如错误处理,重定向等)。这种方法的优点在于,您可以默认数据,执行所需的所有操作,一般性地处理错误等,并且都封装在一个地方。
结论 正如我所看到的,您会一次又一次遇到相同的问题-默认数据存放在哪里?
为此,我每次都以不同的方式处理该问题。例如,在创建表单之前,可以轻松(逻辑上)在构造函数中设置注册表单的“新闻简报”选项。当我建立链接在一起的表单集合(例如,不同表单类型的单选按钮链接在一起)时,我使用了事件监听器。当我建立了一个更复杂的实体(例如,一个需要子对象或大量默认数据的实体)时,我就根据需要使用了一个函数(例如,“ 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']
empty_data
:此选项确定当提交的值为空时字段将返回什么值。它没有设置初始值
您可以在模型类中为关联字段设置默认值(在映射定义中或自行设置值)。
此外,FormBuilder使您有机会使用setData()方法设置初始值。表单构建器将传递到表单类的createForm()方法。
另外,请检查以下链接:http : //symfony.com/doc/current/book/forms.html#using-a-form-without-a-class
如果您的表单绑定到实体,则只需使用Construct方法在实体本身上设置默认值:
public function __construct()
{
$this->field = 'default value';
}
'mapped' => false
)。使用setData(...)
这些。
方法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中为表单字段设置默认值的 Dmitriy的答案(不是公认的答案)?
在使用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'
)
);
}
您可以为表单设置默认值,例如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();
任何情况/方法的通用解决方案,主要是通过使用不带类的表单或当我们需要访问任何服务来设置默认值时:
// 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
在任何表单字段中使用option:
$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));
不要使用:
'data' => 'Default value'
在这里阅读:https : //symfony.com/doc/current/reference/forms/types/form.html#data
“数据选项在呈现时始终会覆盖从域数据(对象)获取的值。这意味着当表单编辑一个已保留的对象时,该对象的值也会被覆盖,从而在提交表单时会丢失其保留的值。”
使用以下内容:
可以说,在此示例中,您有一个Entity 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'] ?? 'Default value'
->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));
}
});
$event->setData()
而不是读取字段可能会更好。
只是我了解问题所在。
您想根据实体中的数据调整构建表单的方式。如果正在创建实体,则使用一些默认值。如果实体存在,请使用数据库值。
就我个人而言,我认为@MolecularMans的解决方案是必经之路。我实际上将在构造函数或属性语句中设置默认值。但是您似乎不喜欢这种方法。
相反,您可以按照以下步骤操作:http : //symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
您可以在表单类型上挂起一个侦听器,然后可以检查您的实体,并根据希望新建或现有的实体来相应地调整builder-> add语句。尽管您可以只在侦听器中对它们进行编码,但仍需要在某个地方指定默认值。或将它们传递给表单类型。
似乎需要做很多工作。最好仅将实体传递给表单并设置其默认值。
通常,对于表单的初始默认值,我使用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',
));
如果您在创建表单中设置“数据”,则在编辑实体时不会修改此值。
我的解决方案是:
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' => $data['myfield'] ?? 'Default value',
通过配置相应的实体来设置默认值。在将实体绑定为表单之前,将其颜色字段设置为“#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;
}