Symfony2: как отключить поле формы при редактировании

1

Как я могу отключить поле имени формы, если имя объекта, например, "По умолчанию"? Таким образом, пользователи не могут изменить имя для объекта "По умолчанию", но могут ли для любого другого объекта?

Это то, что у меня уже есть:

ObjectType

     public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name','text', array('required' => true))
        ->add('description', 'textarea', array('required' => false))
        ->add('type', 'choice', array('choices' => array(
            Object::TYPE_PUBLIC => 'Public',
            Object::TYPE_PRIVATE => 'Private',
        ),
        ));
}

Изменить действие

/**
 * @Route("/edit/{id}", name="edit_object")
 * @ParamConverter("object", class="ObjectBundle:Object")
 * @Template()
 */
public function editAction(Object $object, Request $request)
{
    $form = $this->createForm(new ObjectType(), $object, array(
        'action' => $this->generateUrl('edit_object',['id' => $object->getId()]),
        'method' => 'POST'));

    $form->handleRequest($request);

    if ($form->isValid() && $form->isSubmitted()) {

        $em = $this->getDoctrine()->getManager();
        $em->persist($object);
        $em->flush();

        return $this->render('@Object/Object/list.html.twig', array(
            'object' => $object));
    }
    return array('collection'=>$collection, 'form' => $form->createView());
}
  • 0
    В ObjectType обычно самый быстрый способ - проверить, имеет ли базовый объект идентификатор или нет, и удалить поле, если оно есть; Например: if (null !== $builder->getData()->getId()) { $builder->remove('name'); }
Теги:
forms

1 ответ

2

Реальный простой способ - передать значение конструктору формы с флагом, если вы редактируете. Таким образом, ваш тип формы будет:

class ObjectType extends AbstractType
{
    private $isEdit;

    public function __construct($isEdit = false)
    {
        $this->isEdit = $isEdit;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('description', 'textarea', array('required' => false))
            ->add('type', 'choice', array('choices' => array(
                Object::TYPE_PUBLIC => 'Public',
                Object::TYPE_PRIVATE => 'Private',
            ),
        ));

        if (!$editMode) {
            $builder->add('name','text', array('required' => true));
        }
    }
}

Затем в вашем контроллере:

public function editAction(Object $object, Request $request)
{
    $form = $this->createForm(new ObjectType($isEdit = true), $object, array(
        'action' => $this->generateUrl('edit_object',['id' => $object->getId()]),
        'method' => 'POST'
    ));
    //...
}

Для createForm при создании нового вы можете просто передать new ObjectType() и new ObjectType() параметр, поскольку в этом случае по умолчанию он равен false.


Другим методом будет создание вашей формы на основе объекта, к которому вы переходите, например, FormEvents. Если он уже содержит значение для id, вы просто не можете добавить поле имени в форму:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('description', 'textarea', array('required' => false))
        ->add('type', 'choice', array('choices' => array(
            Object::TYPE_PUBLIC => 'Public',
            Object::TYPE_PRIVATE => 'Private',
        ),
    ));

    $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
        $object= $event->getData();
        $form = $event->getForm();

        if (!$object || null === $object->getId()) {
            $form->add('name','text', array('required' => true));
        }
    });

Точный вариант использования, который я только что дал, специально задокументирован в книге Symfony

  • 0
    Недостаток первого подхода заключается в том, что он больше не будет работать с Symfony 3.0, где вы не можете создавать экземпляры классов типов форм при построении форм (передача аргументов конструктора будет работать только при регистрации типов форм в качестве службы). Второй подход (с использованием событий формы) является более разумным.
  • 0
    Очень интересно - и регистрация его как службы означает, что вы все равно не будете передавать динамические значения в конструктор. В прошлом я использовал третий подход, в котором я регистрирую ключ в configureOptions / setDefaultOptions и затем setDefaultOptions свое значение в array $options при создании формы - будет ли это работать в Symfony3?
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню