0

I've a symfony 4 project with my form. In my formType, I've a choiceType like :

->add('momentDebut', ChoiceType::class, [
                'choices' => [
                    "matin" => "matin",
                    "après-midi" => "après-midi",
                    "journée" => "journée"
                ],

In my twig, I have a select :

<select class="browser-default custom-select" id="choiceUser" onchange="choiceDay(this)">
                <option value="" disabled selected>Choisissez la durée de l'absence</option>
                <option value="jour">La journée</option>
                <option value="periode">Du xx au xx</option>
            </select>

with onChange function which display or not some elements. When I select "Du xx au xx", I would like my 'momentDebut'show all the choices except 'day'.

EDIT:

My Twig :

//...
<select class="browser-default custom-select" id="choiceUser" onchange="choiceDay(this)">
                <option value="" disabled selected>Choisissez la durée de l'absence</option>
                <option value="jour">La journée</option>
                <option value="periode">Du xx au xx</option>
            </select>
//...
<div id="momentDebut">
    <div class="row">
        <div class="col">
            {{form_row(form.dateDebut)}}
        </div>
        <div class="col">
            {{form_row(form.momentDebut)}}
        </div>
    </div>
</div>
//...

EDIT2 : My (matin,après-midi,journée) HTML in the source-code:

<div id="absence_momentDebut">
    <div class="form-check">
        <input type="radio" id="absence_momentDebut_0" name="absence[momentDebut]" required="required" class="form-check-input" value="matin">
        <label class="form-check-label required" for="absence_momentDebut_0">matin</label>
    </div>
    <div class="form-check">
        <input type="radio" id="absence_momentDebut_1" name="absence[momentDebut]" required="required" class="form-check-input" value="après-midi">
        <label class="form-check-label required" for="absence_momentDebut_1">après-midi</label>
    </div>
    <div class="form-check">
        <input type="radio" id="absence_momentDebut_2" name="absence[momentDebut]" required="required" class="form-check-input" value="journée">
        <label class="form-check-label required" for="absence_momentDebut_2">journée</label>
    </div>
</div>

I updated my code like this :

function choiceDay(select) {
            var valeur = select.options[select.selectedIndex].value;
            var targetSelect = document.querySelector('[name="absence[momentDebut]"]');
            var targetOption = document.querySelector('[name="absence[momentDebut]"][value="journée"]');
            console.log(targetSelect.value);
            console.log(targetOption);


            // var choice = $('#choiceMomentDebut').text();
            // console.log(choice);

            switch (valeur) {
                case "periode":
                    document.getElementById("absence").style.visibility = "visible";
                    document.getElementById("momentDebut").style.visibility = "visible";
                    document.getElementById("momentFin").style.visibility = "visible";

                    if (targetOption.value == "journée") { // Reset the selection to the default if it's currently selected
                        targetSelect.selectedIndex = 0;
                    }
                    // Disable the selection
                    targetOption.setAttribute('disabled', true);

                    break;

                case "jour":
                    document.getElementById("absence").style.visibility = "visible";
                    document.getElementById("momentDebut").style.visibility = "visible";
                    document.getElementById("momentFin").style.visibility = "hidden";
                    targetOption.removeAttribute('disabled');
                    break;

                default:
                    break;
            }
        }

And it seems work ! The problem was about this line :

targetOption = targetSelect.querySelector('option[value="journée"]');

I replaced it by

var targetOption = document.querySelector('[name="absence[momentDebut]"][value="journée"]');

And now, all is good !

Thanks for your help !!

aynber
  • 22,380
  • 8
  • 50
  • 63
kiuega
  • 141
  • 1
  • 12
  • What's the problem? Targeting the element? You are not showing any javascript, so I'm assuming that's working ? – msg Sep 04 '19 at 18:47
  • Yes I would like in a first time targeting the element value. And remove the last choice. I will add my javascript – kiuega Sep 04 '19 at 20:48
  • Unless you've changed your `form_theme` I don't think your selectors will match any element, and some of them aren't even in the question. But no, you have a syntax error, the `removeAttribute` should be outside the `case "periode"` block and remove the `else`. It would be easier if you added the relevant rendered html to the question instead of the form definition. – msg Sep 04 '19 at 21:33
  • I think that the probem is that in my source code, I haven't any select/option for my (matin,après-midi,journée), I will add what I have before – kiuega Sep 04 '19 at 21:35
  • I updated my first post with final javascript ! I solved the problem. The option is disable and enable when I want. The last problem is that when I select "journée" and I select another option like "Du xx au xx", my 'journée' is disabled, but it is selected, so the if condition doesn't work :s – kiuega Sep 04 '19 at 21:55
  • 1
    Yes, you didn't include `'expanded' => true` in the Type so I assumed it was a regular select. I updated my answer too, but it's mostly the same thing. – msg Sep 04 '19 at 21:59
  • Thank you very much ! ;) – kiuega Sep 04 '19 at 22:10

1 Answers1

1

Although is not exactly removing the option as you ask one possible solution is to just disable it, preventing from being selected, which is a little easier.

function choiceDay(el) {
  targetRadio = document.querySelector('[name="absence[momentDebut]"]:checked');
  targetOption = document.querySelector('[name="absence[momentDebut]"][value="journée"]');

  if (el.value == "periode") {
    if (targetOption == targetRadio) {
      // Uncheck if it's currently selected      
      targetOption.checked = false;
    }
    // Disable the selection
    targetOption.setAttribute('disabled', true);
  } else {
    targetOption.removeAttribute('disabled');
  }
}
<select class="browser-default custom-select" id="choiceUser" onchange="choiceDay(this)">
  <option value="" disabled selected>Choisissez la durée de l'absence</option>
  <option value="jour">La journée</option>
  <option value="periode">Du xx au xx</option>
</select>

<div id="absence_momentDebut">
  <div class="form-check">
    <input type="radio" id="absence_momentDebut_0" name="absence[momentDebut]" required="required" class="form-check-input" value="matin">
    <label class="form-check-label required" for="absence_momentDebut_0">matin</label>
  </div>
  <div class="form-check">
    <input type="radio" id="absence_momentDebut_1" name="absence[momentDebut]" required="required" class="form-check-input" value="après-midi">
    <label class="form-check-label required" for="absence_momentDebut_1">après-midi</label>
  </div>
  <div class="form-check">
    <input type="radio" id="absence_momentDebut_2" name="absence[momentDebut]" required="required" class="form-check-input" value="journée">
    <label class="form-check-label required" for="absence_momentDebut_2">journée</label>
  </div>
</div>

However you end up doing it, you should add some validation in php, since you could submit any value with javascript disabled. You can find several questions about this.

msg
  • 7,863
  • 3
  • 14
  • 33
  • Thanks for your response, I will update my first post with my previous javascript, et my actual Twig file, because I've some question about this code – kiuega Sep 04 '19 at 21:13