Symfony 6:根据第一个字段选择显示条件表单字段

问题描述 投票:0回答:1

我想根据“presenceEvent”的选择(设置为“Oui”或“true”)显示或隐藏“presenceDejeuner”和“participerActivite”字段。 Symfony 等待表单验证来识别字段选择,但我需要有条件地显示这些字段。我尝试过使用事件侦听器,但它仅在预先填充字段时才有效。然而,就我而言,他们不是。我怎样才能实现这一点,以及如何使用 JavaScript 动态更改这些字段的“必需”属性?我进行了广泛的搜索,但没有找到解决方案。有什么建议吗?

public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('presenceEvent', ChoiceType::class, [
                'choices' => [
                    'Oui' => true,
                    'Non' => false,
                ],
                'expanded' => false,
                'multiple' => false,
            ])
            ->add('presenceDejeuner', ChoiceType::class, [
                'choices' => [
                    'Oui' => true,
                    'Non' => false,
                ],
                'expanded' => false,
                'multiple' => false,
                'required' => false
            ])
            ->add('participerActivite', EntityType::class, [
                'mapped' => false,
                'class' => Activite::class,
                'choice_label' => 'activite',
                'multiple' => true,
                'expanded' => true,
                'required' => false
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Inscription::class,
        ]);
    }

enter image description here

我尝试了 symfony 文档中所说的所有内容,例如 PRE_SET_DATA 、 PRE_SUBMIT 、表单事件等。 也尝试过 Vanilla JS,但它无法识别第一个字段的选择,因为它不会在 HTML 中动态更改

编辑/问题已解决:在Javascript中,我必须找到由symfony生成的要显示或隐藏的字段的id,我在开发工具中看到它,这有点奇怪,我没想到这一点。

javascript php symfony twig symfony6
1个回答
0
投票
  1. 由于“presenceDejeuner”和“participerActivite”字段(称为“Bar”)有条件地连接到“presenceEvent”字段(称为“Foo”),因此在重新加载页面之前,UI 需要更改。这意味着需要Javascript(正如您所猜对的那样)。
  2. 由于涉及 Javascript,PHP 应用程序应始终在 HTML 中渲染 Bar,以便 HTML 保持一致,并且 JS 不必从头开始创建输入。
  3. 因为 Bar 的可见性会根据 Foo 发生变化,所以您需要 监听 Foo 的 changeinput 事件。见下文。
  4. 因为 Foo 的值是由 PHP 预先渲染的,所以你需要在加载后用 JS 检查 Foo 的值,而不需要等待上面的事件。见下文。

更改用户界面

function get_inputs() { /* for convenience */
    return document.querySelectorAll(
        '#id_of_presenceDejeuner_input, #id_of_participerActivite_input'
    );
}

function enable_inputs() {
    for (const input of get_inputs()) {
        input.removeAttribute('disabled');
        input.setAttribute('required', '');
    }
}

function disable_inputs() {
    for (const input of get_inputs()) {
        input.setAttribute('disabled', '');
        input.removeAttribute('required');
    }
}

检查条件

function test_conditions() {
    let input = document.querySelector('#id_of_presenceEvent_input');

    if (input.checked /* if rendered as checkbox */) {
        enable_inputs();
    } else {
        disable_inputs();
    }
}

监听事件

document.addEventListener('DOMContentLoaded', ()=> {
    test_conditions();

    for (const input of get_inputs()) {
        input.addEventListener('change', test_conditions);
    }
});
© www.soinside.com 2019 - 2024. All rights reserved.