php 如何使用 Symfony 2 FormBuilder 在编辑视图中禁用字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18274953/
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 disable a field in edit view using Symfony 2 FormBuilder
提问by viarnes
I created a form with Symfony2 FormBuilder and I want to disabled one of the fields in the edit view. I'm actually hiding it with a wrapper (display:none
) but I was wondering if there's a better way to do this. My code looks like the following:
我用 Symfony2 FormBuilder 创建了一个表单,我想禁用编辑视图中的一个字段。我实际上是用包装器 ( display:none
)隐藏它,但我想知道是否有更好的方法来做到这一点。我的代码如下所示:
EntityType
实体类型
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('fieldToDisabledInEditView');
// ...
EntityController
实体控制器
public function newAction() {
$entity = new Entity;
$form = $this->createForm(new EntityType, $entity);
// ...
}
public function editAction() {
$entity = new Entity;
$form = $this->createForm(new EntityType, $entity);
// ...
}
New (twig) Template
新建(树枝)模板
<form>
{{ form_row(form.fieldToDisabledInEditView) }}
{# ... #}
Edit (twig) Template
编辑(树枝)模板
<form>
<span class="theValueOfTheHiddenField">{{ entity.fieldToDisabledInEditView }}</span>
<div style="display:none">
{{ form_row(form.fieldToDisabledInEditView) }}
</div>
{# ... #}
回答by Cerad
I think you will find that you will have other differences between create and edit, especially validation groups. Since your controller knows which operation is being done then consider creating two form types EditEntity and CreateEntity and then using a common base to minimize duplicate code. @cheesemackfly shows how to add a disabled attribute to an element.
我想您会发现在创建和编辑之间会有其他差异,尤其是验证组。由于您的控制器知道正在执行哪个操作,因此可以考虑创建两种表单类型 EditEntity 和 CreateEntity,然后使用公共基础来最小化重复代码。@cheesemackfly 展示了如何向元素添加禁用属性。
But of course you probably feel that having two forms is a waste for such a simple difference. In which case, add a intention flag to your class and set it in the controller
但是当然,您可能会觉得拥有两种形式对于如此简单的区别来说是一种浪费。在这种情况下,向您的班级添加一个意图标志并将其设置在控制器中
class EntityType
{
public function __construct($intention)
{
$this->intention = $intention;
...
// Use $this->intention to tweak the form
}
}
// controller
$form = $this->createForm(new EntityType('create'), $entity);
OR
$form = $this->createForm(new EntityType('edit'), $entity);
If you really want to get into it then use di to inject the intention.
如果你真的想进入它,那么使用 di 注入意图。
// controller
$formType = $this->get('entity.create.formtype');
OR
$formType = $this->get('entity.edit.formtype');
By using services you can start with just the one formtype and then when you end up splitting it into two (which you will) your controllers will still work as before.
通过使用服务,您可以从一种表单类型开始,然后当您最终将其拆分为两个(您会这样做)时,您的控制器仍将像以前一样工作。
And one more thing, you can actually set the disabled attribute directly in twig assuming you are using different templates for edit/create. So no code changes at all.
还有一件事,假设您使用不同的模板进行编辑/创建,您实际上可以直接在 twig 中设置禁用属性。所以根本没有代码改变。
{{ form_row(form.yourField, { 'attr':{'disabled':'disabled'} }) }}
======================================================================== Update: 03 March 2016
================================================== ====================== 更新:2016 年 3 月 3 日
Just in case anybody stumbles across this, be aware the Symfony 3 no longer supports having one class implement multiple form types. You basically have to have individual form type classes even if they are almost identical. And never add instance data to your form types.
以防万一有人偶然发现这一点,请注意 Symfony 3 不再支持让一个类实现多种表单类型。即使它们几乎相同,您基本上也必须拥有单独的表单类型类。并且永远不要将实例数据添加到您的表单类型中。
回答by cheesemacfly
This is the typical case where you can use an event subscriber to a form class.
In your case, it should be as:
这是您可以使用表单类的事件订阅者的典型情况。
在你的情况下,它应该是:
// src/Acme/DemoBundle/Form/EventListener/AddfieldToDisabledInEditViewSubscriber.php
namespace Acme\DemoBundle\Form\EventListener;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class AddfieldToDisabledInEditViewSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
// Tells the dispatcher that you want to listen on the form.pre_set_data
// event and that the preSetData method should be called.
return array(FormEvents::PRE_SET_DATA => 'preSetData');
}
public function preSetData(FormEvent $event)
{
$data = $event->getData();
$form = $event->getForm();
// check if the object is "new"
// If you didn't pass any data to the form, the data is "null".
// This should be considered a new object
if (!$data || !$data->getId()) {
$form->add('fieldToDisabledInEditView');
}
else
{
$form->add('fieldToDisabledInEditView', null, array('disabled' => true));
//If PHP >= 5.4
//$form->add('fieldToDisabledInEditView', null, ['disabled' => true]);
}
}
}
And in your form type:
并在您的表单中输入:
// src/Acme/DemoBundle/Form/Type/EntityType.php
namespace Acme\DemoBundle\Form\Type;
// ...
use Acme\DemoBundle\Form\EventListener\AddfieldToDisabledInEditViewSubscriber;
class EntityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('your_field');
//...
$builder->addEventSubscriber(new AddfieldToDisabledInEditViewSubscriber());
}
// ...
}
http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
回答by cheesemacfly
This approach is not elegant at all but I use it because is simple:
这种方法一点也不优雅,但我使用它是因为它很简单:
EntityController
实体控制器
public function newAction() {
$entity = new Entity;
$form = $this->createForm(new EntityType, $entity);
// ...
}
public function editAction() {
$entity = new Entity;
$form = $this->createForm(new EntityType, $entity);
$form->remove('fieldToDisabledInEditView');
// ...
}
回答by Egon Olieux
For those looking for a solution in Symfony 3 without creating separate form type classes (for both add and edit) and without using form events, you can define a custom option and pass it to the form on creation:
对于那些在 Symfony 3 中寻找解决方案而不创建单独的表单类型类(用于添加和编辑)并且不使用表单事件的人,您可以定义一个自定义选项并在创建时将其传递给表单:
I created an is_edit
option with default value false
in the form type class:
我在表单类型类中创建了一个is_edit
具有默认值的选项false
:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => SomeEntity::class,
'is_edit' => false
));
}
You can access this option using the $options
array in the buildForm
method of the same class:
您可以使用同一类$options
的buildForm
方法中的数组访问此选项:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('someField', TextType::class, array(
'disabled' => $options['is_edit']
))
}
Finally, you can override the default value by passing it on form creation:
最后,您可以通过在表单创建时传递默认值来覆盖默认值:
$someForm = $this->createForm(
SomeEntityType::class,
$someEntity,
array('is_edit' => true)
);
回答by ivn
New (twig) TemplateDont forget {{ form_row(form._token) }} when rendering form fields individualy
新的(树枝)模板在单独呈现表单字段时不要忘记 {{ form_row(form._token) }}
<form>
{{ form_row(form.fieldToDisabledInEditView) }}
{{ form_row(form.field2) }}
{{ form_row(form.field3) }}
{# ... #}
{{ form_row(form._token) }}
Edit (twig) TemplateJust don't render {{ form_row(form.fieldToDisabledInEditView) }} and again don't forget token.
编辑(树枝)模板只是不要呈现 {{ form_row(form.fieldToDisabledInEditView) }} 并且再次不要忘记令牌。
<form>
{{ form_row(form.field2) }}
{{ form_row(form.field3) }}
{# ... #}
{{ form_row(form._token) }}