Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在提交和验证数据后禁用symfony表单中的字段?_Php_Symfony_Symfony Forms_Symfony 3.4 - Fatal编程技术网

Php 如何在提交和验证数据后禁用symfony表单中的字段?

Php 如何在提交和验证数据后禁用symfony表单中的字段?,php,symfony,symfony-forms,symfony-3.4,Php,Symfony,Symfony Forms,Symfony 3.4,我有以下问题:我创建了一个表单,它有一个选择字段和不同的文本字段。当选择字段具有特定值时,应禁用某些文本字段。因此我有JavaScriptcode,它处理select字段上的onchange事件,然后禁用/启用文本字段。我有一些PHP逻辑,它根据从数据库中检索到的值来禁用文本字段。这一切都有效。问题是,当我验证我的表单时,如果出现验证错误,我不知道如何在再次呈现验证过的表单时禁用文本字段(不使用JavaScript)。因为在验证中,我设置了一个新的空实体,然后基于该实体创建表单,然后处理请求。因

我有以下问题:我创建了一个表单,它有一个选择字段和不同的文本字段。当选择字段具有特定值时,应禁用某些文本字段。因此我有
JavaScript
code,它处理select字段上的
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()]);
}

您需要在提交前根据您获得的请求数据修改表单。这可以在提交期间使用
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;
}


您应该分离表单创建以分离
FormType
Handler
类。

似乎可以工作,但是如果我
remove
add
字段,那么绑定到此字段的值将丢失,并且当我再次呈现表单时,输入字段为空。我更新了示例,它首先从表单字段中获取数据,然后将其设置为Back,从而禁用不再发送的字段。即使表单会发送它,Symfony也会忽略所有禁用的值。您还应该将该实体存储在用户会话中,并在表单中使用该实体,直到它被持久化。