lundi 5 octobre 2020

Radio button and checkbox switching options

if you can help, I'm new to jQuery and JS in general.

I need to write the logic for displaying different sets of checkboxes or radio buttons depending on the previous selection. It is kinda like a questionnaire. So the checkboxes and radio buttons have data-validFor attribute which contains the id of some of the previous options we selected. So if we chose radio button in the first block, second block will show only the options (radio buttons or checkboxes) which are valid for this radio button/checkbox, and so on through out of couple of blocks. One input can have more than one validFor value. If the next block only contains one valid option, it will be preselected and the next block will be shown. Of course if the chose of previous selection is changed I want for the rest of the blocks to hide again and deselect and start from the new option selected.

Dummy HTML:

<div class="block">

<div class="form-group">

<span>
  <input id="radio-1-1" name="fruite" type="radio">
  <lable for="radio-1-1">Apple</lable>
</span>
<span>
  <input id="radio-1-2" name="fruite" type="radio">
  <lable for="radio-1-2">Grape</lable>
</span>
<span>
  <input id="dummy" name="fruite" type="radio">
  <lable for="dummy">Mango</lable>
</span>

<span>
  <input id="radio-1-4" name="fruite" type="radio">
  <lable for="radio-1-4">Melon</lable>
</span>

</div>

</div>

<div class="block">

<div class="form-group">

<span class="js-option">
  <input id="radio-2-1" name="vege" type="radio" data-validFor="radio-1-1">
  <lable for="radio-2-1">Potato</lable>
</span>
<span class="js-option">
  <input id="radio-2-2" name="vege" type="radio" data-validFor="radio-1-1">
  <lable for="radio-2-2">Cucumber</lable>
</span>
<span class="js-option">
  <input id="radio-2-3" name="vege" type="radio" data-validFor="radio-1-2">
  <lable for="radio-2-3">Onion</lable>
</span>

<span class="js-option">
  <input id="radio-2-3" name="vege" type="radio" data-validFor="dummy">
  <lable for="radio-2-3">Garlic</lable>
</span>

<span class="js-option">
  <input id="radio-2-4" name="vege" type="radio" data-validFor="radio-1-4">
  <lable for="radio-2-4">Broccoli</lable>
</span>

</div>

</div>

<div class="block">

<div class="form-group">

<span class="js-option">
  <input id="radio-3-1" name="names" type="radio" data-validFor="radio-2-1">
  <lable for="radio-3-1">John</lable>
</span>
<span class="js-option">
  <input id="radio-3-2" name="names" type="radio" data-validFor="radio-2-1">
  <lable for="radio-3-2">James</lable>
</span>
<span class="js-option">
  <input id="radio-3-3" name="names" type="radio" data-validFor="radio-2-2">
  <lable for="radio-3-3">Rebeca</lable>
</span>

<span class="js-option">
  <input id="radio-3-3" name="names" type="radio" data-validFor="radio-2-3">
  <lable for="radio-3-3">Tim</lable>
</span>

<span class="js-option">
  <input id="radio-3-4" name="imena" type="radio" data-validFor="radio-2-4">
  <lable for="radio-3-4">Rob</lable>
</span>

</div>

</div>

JS:

            // hide all the blocks except the fist one
            $('.block').not(':eq(0)').hide();

            $("input").on("change", function() {
              var optionId = $(this).prop('id');
              var $tab = $(this).parents(".block").next();
              var $options = $tab.find('.js-option');
              var $nextTabs = $tab.nextAll(".block");

              var $validOptions = $tab.find('input').filter(function(){
                var dataToCheck = $(this).data('validfor').replace(/[\[\]']+/g,'').split(',');
                return dataToCheck.indexOf(optionId) !== -1;
              })
              
              // here I'm trying to reset the selection if the new option is checked
              $nextTabs.hide();
              $nextTabs.find('input[type="checkbox"]').removeAttr('checked');
              $nextTabs.find('input[type="radio"]').prop('checked', false);
              $options.hide();
              $tab.show();
              
              //if there is only one valid option do the logic of preselecting and, showing it and showing next valid options
              if($validOptions.length == 1) {
                $validOptions.prop("checked", true);
                $validOptions.attr('checked');

                var $nextOptions = $tab.next().find('input');
                var $nextValidOptions = $nextOptions.filter(function(){
                  var dataToCheck = ($(this).data('validfor').replace(/[\[\]']+/g,'')).split(',');
                  return dataToCheck.indexOf(optionId) !== -1;
                })

                $tab.next().show();
                $nextValidOptions.parent().show();

              }

              $validOptions.parent().show();  
            })

In this dummy HTML there are no checkbox, but one block can contain the set of them and you can select couple. My code works to some extent. But I dont want to do all of this only on change event. When we fill out this questionnaire we proceed and if we are back I want for all the blocks to be still visible and the options we selected present. And for now, the case is that only first selection is visible and other blocks are hidden (because the change event is not triggered yet).

Hopefully I explained the scenarios well and I know my code is not optimised but I'm very new to this thing. So if anybody have some ideas I would be vary thankful




Aucun commentaire:

Enregistrer un commentaire