php - component - Cómo deshabilitar un campo en la vista de edición usando Symfony 2 FormBuilder
symfony form post (5)
Creo que encontrará que tendrá otras diferencias entre crear y editar, especialmente los grupos de validación. Ya que su controlador sabe qué operación se está realizando, considere crear dos tipos de formulario, EditEntity y CreateEntity, y luego usar una base común para minimizar el código duplicado. @cheesemackfly muestra cómo agregar un atributo deshabilitado a un elemento.
Pero, por supuesto, probablemente sienta que tener dos formas es un desperdicio por una diferencia tan simple. En cuyo caso, agregue un indicador de intención a su clase y configúrelo en el controlador
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);
Si realmente quieres entrar en él, utiliza di para inyectar la intención.
// controller
$formType = $this->get(''entity.create.formtype'');
OR
$formType = $this->get(''entity.edit.formtype'');
Al usar los servicios, puede comenzar con un solo tipo de formulario y luego, cuando termine dividiéndolo en dos (lo que hará), sus controladores seguirán funcionando como antes.
Y una cosa más, puede configurar el atributo deshabilitado directamente en ramita, suponiendo que esté usando diferentes plantillas para editar / crear. Así que no hay cambios de código en absoluto.
{{ form_row(form.yourField, { ''attr'':{''disabled'':''disabled''} }) }}
================================================== ====================== Actualización: 03 de marzo de 2016
En caso de que alguien tropiece con esto, ten en cuenta que Symfony 3 ya no admite que una clase implemente varios tipos de formularios. Básicamente, debe tener clases de tipo de formulario individuales, incluso si son casi idénticas. Y nunca agregue datos de instancia a sus tipos de formulario.
He creado un formulario con Symfony2 FormBuilder y quiero deshabilitar uno de los campos en la vista de edición. De hecho, lo estoy ocultando con una envoltura ( display:none
) pero me preguntaba si hay una mejor manera de hacerlo. Mi código se parece a lo siguiente:
Tipo de entidad
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);
// ...
}
Nueva plantilla (ramita)
<form>
{{ form_row(form.fieldToDisabledInEditView) }}
{# ... #}
Editar plantilla (ramita)
<form>
<span class="theValueOfTheHiddenField">{{ entity.fieldToDisabledInEditView }}</span>
<div style="display:none">
{{ form_row(form.fieldToDisabledInEditView) }}
</div>
{# ... #}
Este enfoque no es elegante en absoluto, pero lo uso porque es 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'');
// ...
}
Este es el caso típico en el que puede usar un suscriptor de eventos para una clase de formulario.
En tu caso, debería ser como:
// 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]);
}
}
}
Y en su forma de formulario:
// 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
Para aquellos que buscan una solución en Symfony 3 sin crear clases de tipo de formulario separadas (para agregar y editar) y sin usar eventos de formulario, puedes definir una opción personalizada y pasarla al formulario en el momento de la creación:
is_edit
una opción is_edit
con el valor predeterminado false
en la clase de tipo de formulario:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
''data_class'' => SomeEntity::class,
''is_edit'' => false
));
}
Puede acceder a esta opción utilizando la matriz $options
en el método buildForm
de la misma clase:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(''someField'', TextType::class, array(
''disabled'' => $options[''is_edit'']
))
}
Finalmente, puede anular el valor predeterminado pasándolo en la creación del formulario:
$someForm = $this->createForm(
SomeEntityType::class,
$someEntity,
array(''is_edit'' => true)
);
Nueva plantilla (ramita) No olvide {{form_row (form._token)}} al representar campos de formulario individualmente
<form>
{{ form_row(form.fieldToDisabledInEditView) }}
{{ form_row(form.field2) }}
{{ form_row(form.field3) }}
{# ... #}
{{ form_row(form._token) }}
Editar plantilla (ramita) Simplemente no renderice {{form_row (form.fieldToDisabledInEditView)}} y nuevamente no olvide el token.
<form>
{{ form_row(form.field2) }}
{{ form_row(form.field3) }}
{# ... #}
{{ form_row(form._token) }}