Manipulating checkboxes with js & symfony

Viewed 110

I am rendering a form using an EntityType and using a custom template.

I would like to hide the checkbox fields and use JS to add a background color.
If the item is checked or remove it if it is not.
The display works (relatively correctly, still have a problem when I click the checkbox itself when it s displayed) but if I submit an incomplete form multiple times, if I uncheck a box, after submition, the server still shows that the checkbox was checked...

ChallengeType.php

$builder
            ->add('sports', EntityType::class, [
                'class' => Sport::class,
                'expanded' => true,
                'multiple' => true,
                'required' => true,
                'choice_label' => 'name',
                'query_builder' => function (SportRepository $er) {
                    return $er->createQueryBuilder('s')
                        ->orderBy('s.name', 'ASC');
                },
                'choice_attr' => function ($sport) {
                    return ['data-img' => $sport->getGoutte()];
                }
            ])

the template twig

{{ form_start(form, {'attr': {'class': 'form-challenge', 'novalidate':'novaldiate'} }) }}

        <ul class="form-row justify-content-center list-unstyled text-center" id="sports-checkboxes">
            {{ form_errors(form.sports) }}
            {% for sport in form.sports.children %}
                <li
                        class="col-6 col-lg-2 col-md-3 col-sm-4 {{ sport.vars.checked? "bg-warning" : "" }}"
                        onclick="checkBoxClickHandler(event)"
                >
                    <img class="" src="/{{ sport.vars.attr['data-img'] }}" alt="{{ sport.vars.label }}"
                         style="width: 30px; height: auto">
                    <p>
                        <label for="{{ sport.vars.id }}">{{ sport.vars.label }}</label>
                        <input
                                class="d-none"
                                type="checkbox"
                                id="{{ sport.vars.id }}"
                                name="{{ sport.vars.full_name }}"
                                value="{{ sport.vars.value}}"
                                {{ sport.vars.checked? "checked" : "" }}
                        >
                        {#{{ form_widget(sport) }}#}
                    </p>
                </li>
            {% endfor %}
        </ul>

the js code

function checkBoxClickHandler(event){
            event.preventDefault();
            const li = event.target.closest('li');
            const input = li.querySelector('input')
            if (input.checked) {
                input.checked = false;
                input.removeAttribute('checked')
                li.classList.remove('bg-warning')
            } else {
                input.checked = true;
                li.classList.add('bg-warning')
            }
        }

Any idea what I am doing wrong?

1 Answers

Why do you use onclick event in LI element? You should use the onchange event to INPUT element. If you submit the form, the data will be saved?

Related