Sunday, 11 December 2022

Sorting into arrays based on radio button choices giving mixed results

I have two radio button groups:

  1. For attendance and have values of "yes" and "no"
  2. For dietary choice and has the values of "Vegetarian / Vegan" and "Non-vegetarian"

The fields for dietary only show if the user has selected "yes" for attendance.

I'm sorting those who have accepted, declined, chose veg or non-veg into their own arrays (so 4 arrays exist). The values for these 4 arrays are passed onto a hidden field which is then posted to DB.

I have successfully managed to sort who has accepted or declined into their own arrays. However, since I've added another change function to sort the diet options also, I get mixed results. Steps to recreate in the demo:

  1. For "John", click yes for attendance
  2. John is added to the attending list (console log)
  3. For "John", click "Non-vegetarian"
  4. John is added to the non veg list
  5. For Alex, click yes for attendance
  6. Alex is added to the attending list alongside John
  7. For Alex, click "Vegetarian / Vegan"
  8. Alex is added to the "veg list", but John is removed from the "Non veg list"

Also, if a user clicks yes to attendance initially, then selects a diet option and then clicks "no" to attendance after, their name from the diet arrays should be removed (since they're not attending). I've tried to address this with if ( attendance_radio.val() == "yes" ) { } but no luck.

Demo below:

(function ($) {
  var attendance_radio = $(".input-radio-attendance");
  var diet_radio = $(".input-radio-diet");

  var accepted_array = [];
  var declined_array = [];

  var veg_array = [];
  var nonveg_array = [];

  /* sort accepted and declined into arrays */
  attendance_radio.on('change', function() {
    var $this = $(this);
    var name = $this.data("name");
    var checkedVal = $this.val();

    if (checkedVal == "yes") {
      accepted_array.push(name);
      declined_array.splice($.inArray(name, declined_array), 1);
    } 
    else {
      declined_array.push(name);
      accepted_array.splice($.inArray(name, accepted_array), 1);
    }

    var accepted_list = accepted_array.join(",");
    var declined_list = declined_array.join(",");

    console.log("attending list: " + accepted_list);
    console.log("declined list: " + declined_list);
  });

  /* get count of veg and non veg numbers */
  diet_radio.on('change', function() {
    var $this = $(this);
    var name = $this.data("name");
    var checkedVal = $this.val();
  
    // only add to array if user is attending
    if ( attendance_radio.val() == "yes" ) {
      if (checkedVal == "veg") {
        veg_array.push(name);
        nonveg_array.splice($.inArray(name, nonveg_array), 1);
      } 
      else {
        nonveg_array.push(name);
        veg_array.splice($.inArray(name, veg_array), 1);
      }
    }
  
    var veg_list = veg_array.join(",");
    var nonveg_list = nonveg_array.join(",");
  
    console.log("veg list: " + veg_list);
    console.log("non veg list: " + nonveg_list);
  });

  /* showing dietary fields if yes is selected */
  attendance_radio.each(function(index) {
    $(this).on("click", function() {
      var $this = $(this);
      var checkedVal = $this.val();

      if( checkedVal == "yes" ) {
        $this.closest(".guest").find(".dietary").addClass("d-flex");
        diet_radio.prop('required',true);
      } 
      else {
        $this.closest(".guest").find(".dietary").removeClass("d-flex");
        diet_radio.prop('required',false);
      }
    });
  });
}) (jQuery);
.group,
.group__inner{
  display: flex;
}

.group{
  padding: 30px;
  flex-direction: column;
}

span{
  display: block;
  margin-bottom: 20px;
}

.dietary{
  display: none;
}

.attendance{
  display: flex;
}

.d-flex{
  display: flex;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<div class="group">

  <!------------->
  <!-- guest 1 -->
  <!------------->

  <div class="guest">
    <span class="guest__name">John</span>
    
    <div class="guest__options">
      <!-- attendace -->
      <div class="attendance">
        <span>Attending?</span>
        
        <div class="group__inner">
          <div class="guest__options-group">
            <input class="input-radio-attendance" id="attending-yes-0" type="radio" name="attendance-0" value="yes" data-name="John" required />
            <label for="attending-yes-0">Yes</label>
          </div>
          
          <div class="guest__options-group">
            <input class="input-radio-attendance" id="attending-no-0" type="radio" name="attendance-0" value="no" data-name="John" required />
            <label for="attending-no-0">No</label>
          </div>
        </div>
      </div>
      
      <!-- show dietary options when attendace is yes -->
      <div class="dietary">
        <span>Dietary preference</span>
        
        <div class="group__inner">
          <div class="guest__options-group">
            <input class="input-radio-diet" id="diet-veg-0" type="radio" name="diet-0" value="veg" data-name="John" required />
            <label for="diet-veg-0">Vegetarian / Vegan</label>
          </div>
          
          <div class="guest__options-group">
            <input class="input-radio-diet" id="diet-nonveg-0" type="radio" name="diet-0" value="nonveg" data-name="John" required />
            <label for="diet-nonveg-0">Non-vegetarian</label>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!------------->
  <!-- guest 2 -->
  <!------------->

  <div class="guest">
    <span class="guest__name">Alex</span>
    
    <div class="guest__options">
      <!-- attendace -->
      <div class="attendance">
        <span>Attending?</span>
        
        <div class="group__inner">
          <div class="guest__options-group">
            <input class="input-radio-attendance" id="attending-yes-1" type="radio" name="attendance-1" value="yes" data-name="Alex" required />
            <label for="attending-yes-0">Yes</label>
          </div>
          
          <div class="guest__options-group">
            <input class="input-radio-attendance" id="attending-no-1" type="radio" name="attendance-1" value="no" data-name="Alex" required />
            <label for="attending-no-1">No</label>
          </div>
        </div>
      </div>
      
      <!-- show dietary options when attendace is yes -->
      <div class="dietary">
        <span>Dietary preference</span>
        
        <div class="group__inner">
          <div class="guest__options-group">
            <input class="input-radio-diet" id="diet-veg-1" type="radio" name="diet-1" value="veg" data-name="Alex" required />
            <label for="diet-veg-1">Vegetarian / Vegan</label>
          </div>
          
          <div class="guest__options-group">
            <input class="input-radio-diet" id="diet-nonveg-1" type="radio" name="diet-1" value="nonveg" data-name="Alex" required />
            <label for="diet-nonveg-1">Non-vegetarian</label>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Also tried

  diet_radio.on('change', function() {
    var $this = $(this);
    var name = $this.data("name");
    var checkedVal = $this.val();

    // only add to diet arrays if user is attending
    if ( $(this).closest(".guest").find(".input-radio-attendance:checked").val() == "yes" ) {
      if (checkedVal == "veg") {
        veg_array.push(name);
        nonveg_array.splice($.inArray(name, nonveg_array), 1);
      } else {
        nonveg_array.push(name);
        veg_array.splice($.inArray(name, veg_array), 1);
      }
    }

    // if user selects yes to attendance, then selects a diet option, then changes atendance to no, remove them from diet arrays
    if( accepted_list.includes(name) ){
      veg_array.splice( $.inArray(name, veg_array), 1 );
      nonveg_array.splice( $.inArray(name, nonveg_array), 1 );
    }

    var veg_list = veg_array.join(",");
    var nonveg_list = nonveg_array.join(",");

    veg_field.val(veg_list);
    nonveg_field.val(nonveg_list);

    console.log("veg list: " + veg_list);
    console.log("non veg list: " + nonveg_list);

  });

Edit @Lajos Arpad

enter image description here



from Sorting into arrays based on radio button choices giving mixed results

No comments:

Post a Comment