skip to Main Content

I want to show or hide the "presenceDejeuner" and "participerActivite" fields based on the selection of "presenceEvent" (set to "Oui" or "true"). Symfony waits for form validation to recognize field choices, but I need to conditionally display these fields. I’ve tried using an event listener, but it only works when fields are pre-filled. However, in my case, they’re not. How can I achieve this, and how can I dynamically change the "required" attribute for these fields using JavaScript? I’ve searched extensively but haven’t found a solution. Any suggestions?

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

I tryed everything what says in symfony docs such as PRE_SET_DATA , PRE_SUBMIT , Form Events etc..
Tryed also with Vanilla JS, but it just cannot recognize the choice of first field because it doesn’t change dynamically in HTML

2

Answers


  1. Chosen as BEST ANSWER

    Absolutely no one can help me for that ?


    1. Because the “presenceDejeuner” and “participerActivite” fields (call them “Bar”) are conditionally connected to the “presenceEvent” field (call it “Foo”), the UI needs to change before the page is reloaded. This means Javascript is required (as you correctly guessed).
    2. Since Javascript is involved, the PHP app should always render Bar in the HTML, so that the HTML stays consistent and the JS doesn’t have to create the input from scratch.
    3. Because the visibility of Bar changes based on Foo, you’ll need to listen to Foo for change or input events. See below.
    4. Because Foo’s value is pre-rendered by PHP, you’ll need to check Foo’s value with JS after it loads without waiting for the event above. See below.

    Change the UI

    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');
        }
    }
    

    Check conditions

    function test_conditions() {
        let input = document.querySelector('#id_of_presenceEvent_input');
    
        if (input.checked /* if rendered as checkbox */) {
            enable_inputs();
        } else {
            disable_inputs();
        }
    }
    

    Listen for events

    document.addEventListener('DOMContentLoaded', ()=> {
        test_conditions();
    
        for (const input of get_inputs()) {
            input.addEventListener('change', test_conditions);
        }
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search