提交并验证数据后,如何禁用symfony表单中的字段?

时间:2019-06-06 07:21:52

标签: php symfony symfony-forms symfony-3.4

我遇到以下问题:我创建一个表单,该表单具有一个选择字段和不同的文本字段。当选择字段具有特定值时,应禁用某些文本字段。因此,我有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 :(得分:0)

您需要根据获取的请求数据来修改表单,然后再提交。这可以在使用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

您应该将表单创建分隔为FormTypeHandler类。