Как отключить поля в symfony-форме после отправки и проверки данных? - PullRequest
0 голосов
/ 06 июня 2019

У меня следующая проблема: я создаю форму, в которой есть поле выбора и разные текстовые поля.Когда поле выбора имеет определенное значение, некоторые текстовые поля должны быть отключены.Итак, у меня есть код JavaScript, который обрабатывает событие onchange в моем поле выбора, а затем отключает / включает текстовые поля.И у меня есть некоторая логика PHP, которая отключает текстовые поля изначально в зависимости от значения, полученного из базы данных.Это все работает.Проблема в том, что когда я проверяю свою форму и у меня появляется ошибка проверки, я не знаю, как отключить мои текстовые поля (без использования JavaScript) при повторной визуализации проверенной формы.Потому что в моей проверке я устанавливаю новую и пустую сущность, затем я создаю форму, основанную на этой сущности, а затем обрабатываю запрос.Так что в момент создания формы у меня нет значений, которые мне нужны, чтобы определить, следует ли отключать или включать текстовые поля изначально.

Итак, вопрос в том, как отключить некоторую формуполя после обработки проверки?

Вот некоторый псевдокод с проблемой, указанной в комментариях

// create the form object depending on the form entity
private function createForm($formEntity) {
    $attributes = [];
    if ($formEntity->getType() === 'x') {
        // disable fields if type === 'x'
        $attributes = ['disabled' => 'disabled'];
    }

    $form = $this->createFormBuilder($task)
        ->add('type', ChoiceType::class)
        ->add('fieldA', TextType::class, ['attr' => $attributes])
        ->add('fieldB', TextType::class, ['attr' => $attributes])
        ->add('save', SubmitType::class, ['label' => 'Create Task'])
        ->getForm();

    return $form;
}

// action to just view the form
public function detailsAction($id) {
    $databaseEntity = $service->get(id);
    $formEntity = FormEntity::fromDatabaseEntity();

    // in this case, the $formEntity has the values from the database
    // so inside the createForm, the fields can be disabled/enabled
    $form = $this->createForm($formEntity);

    // when I render the form, the fields are disabled initially
    return render('views/details.twig.html', ['form' => $form->createView()]);
}

// action which handles the submit of the form, and render the form with validation constraints, if there are some
public function handleSubmitAction($id) {
    $formEntity = new FormEntity();

    // in this case, the $formEntity is empty
    // so inside the createForm, the fields can not be disabled/enabled
    $form = $this->createForm($formEntity);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        return $this->redirectToRoute('task_success');
    }

    // when I render the form, the fields are not disabled initially
    return render('views/details.twig.html', ['form' => $form->createView()]);
}

1 Ответ

0 голосов
/ 06 июня 2019

Вам необходимо изменить свою форму перед отправкой, основываясь на полученных вами данных запроса.Это можно сделать до того, как данные запроса будут применены к форме во время отправки, используя метод PRE_SUBMIT.

private function createForm($formEntity) {
    $attributes = [];
    if ($formEntity->getType() === 'x') {
        // disable fields if type === 'x'
        $attributes = ['disabled' => 'disabled'];
    }

    $form = $this->createFormBuilder($formEntity)
        ->add('type', ChoiceType::class)
        ->add('save', SubmitType::class, ['label' => 'Create Task'])
        ->add('fieldA', TextType::class, ['attr' => $attributes]);
        ->add('fieldB', TextType::class, ['attr' => $attributes]);
        ->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
            $attributes = [];
            if ($event->getData()['type'] === 'x') {
              $attributes = ['disabled' => 'disabled'];
            }
            $form = $event->getForm();

            $dataA = $form->get('fieldA')->getData();
            $dataB = $form->get('fieldB')->getData();
            $form->remove('fieldA');
            $form->remove('fieldB');
            $form->add('fieldA', TextType::class, ['attr' => $attributes]);
            $form->add('fieldB', TextType::class, ['attr' => $attributes]);
            $form->get('fieldA')->setData($dataA);
            $form->get('fieldB')->setData($dataB);
        })
        ->getForm();

    return $form;
}

https://symfony.com/doc/current/form/events.html

И вы должны разделить создание формы на отдельные FormType и Handler классы.

...