VderKaiser
VderKaiser

Reputation: 127

How to create form when second dropdown depends on the first dropdown selection

How to create form that options on second dropdown depends on the selection of the option on first dropdown? The problem is that I have 4 dropdowns and every dropdown depends on the previous one.

For example:

DROPDOWN #1 Options: England / Spain / Italy

DROPDOWN #2 Options: (if England is selected) Premier League / Championship / League One

(if Italy is selected) Serie A / Serie B

DROPDOWN #3 Options: (if Premier League is selected) Chelsea / Man City / Everton

.... ( I hope you get the point)

I tried using this code from another question, but I couldn't find solution for including third or even fourth dropdown options.

<select id="groups">
<option value='England'>England</option>
<option value='Spain'>Spain</option>
<option value='Italy'>Italy</option>

<select id="sub_groups">
<option data-group='SHOW' value='0'>-- Select --</option>
<option data-group='England' value='Premier'>Premier</option>
<option data-group='England' value='Championship'>Championship</option>
<option data-group='England' value='League One'>League One</option>
<option data-group='Spain' value='La Liga'>La Liga</option>
<option data-group='Spain' value='Second Division'>Second Division</option>
<option data-group='Spain' value='Third Division'>Third Division</option>
<option data-group='Italy' value='Seria A'>Seria A</option>
<option data-group='Italy' value='Seria B'>Seria B</option>

<select id="sub_sub_groups">
    <option data-group='SHOW' value='0'>-- Select --</option>
    <option data-group='Premier' value='Premier'>Chelsea</option>
    <option data-group='La Liga' value='La Liga'>Sevilla</option>
    <option data-group='Seria A' value='Seria A'>Juventus</option>
<select>



$(function(){
$('#groups').on('change', function(){
    var val = $(this).val();
    var sub = $('#sub_groups');
    $('option', sub).filter(function(){
        if (
             $(this).attr('data-group') === val 
          || $(this).attr('data-group') === 'SHOW'
        ) {
          if ($(this).parent('span').length) {
            $(this).unwrap();
          }
        } else {
          if (!$(this).parent('span').length) {
            $(this).wrap( "<span>" ).parent().hide();
          }
        };
    });

});
$('#groups').trigger('change'); {

$('#sub_groups').on('change', function(){

 var subsub = $('#sub_sub_groups');
    $('option', subsub).filter(function(){
        if (
             $(this).attr('data-group') === val 
          || $(this).attr('data-group') === 'SHOW'
        ) {
          if ($(this).parent('span').length) {
            $(this).unwrap();
          }
        } else {
          if (!$(this).parent('span').length) {
            $(this).wrap( "<span>" ).parent().hide();
          }
        }
    });
});
$('#sub_groups').trigger('change');

}

});

Upvotes: 1

Views: 218

Answers (2)

Mark Schultheiss
Mark Schultheiss

Reputation: 34196

Just set the data like you started to, here I use the values you set. Add more.

Hide the values that do not match. Un-select if you change the parent. I will leave it up to you to determine how to handle the case where nothing is selected at first, I did put in the code to trigger it. I will also leave it to you to determine how to handle the sub group when nothing is selected - like at first, it lets you pick from either of the second and third selects - probably disable those and enable when the parent gets a value selected?

$(function() {
  $('#select-container').on('change', '.select-group', function(event) {
    let groupNext = $(this).data("next");
    let next = $(groupNext);
    next.find("option:selected").prop("selected", false);
    next.trigger('change');//clears child when unset
    let options = next.find('option');
    let selectedValue = $(this).find(":selected").val();
    options.hide();
    let nextOptions = options.filter(function() {
      return $(this).data("group") == selectedValue;
    }).show();
  }).first().trigger('change');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="select-container">
  <select class="select-group" id="groups" data-next="#sub_groups">
    <option value='England'>England</option>
    <option value='Spain'>Spain</option>
    <option value='Italy'>Italy</option>
  </select>
  <select class="select-group" id="sub_groups" data-next="#sub_sub_groups">
    <option data-group='SHOW' value='0'>-- Select --</option>
    <option data-group='England' value='Premier'>Premier</option>
    <option data-group='England' value='Championship'>Championship</option>
    <option data-group='England' value='League One'>League One</option>
    <option data-group='Spain' value='La Liga'>La Liga</option>
    <option data-group='Spain' value='Second Division'>Second Division</option>
    <option data-group='Spain' value='Third Division'>Third Division</option>
    <option data-group='Italy' value='Seria A'>Seria A</option>
    <option data-group='Italy' value='Seria B'>Seria B</option>
  </select>
  <select class="select-group" id="sub_sub_groups">
    <option data-group='SHOW' value='0'>-- Select --</option>
    <option data-group='Premier' value='Premier'>Chelsea</option>
    <option data-group='La Liga' value='La Liga'>Sevilla</option>
    <option data-group='Seria A' value='Seria A'>Juventus</option>
  </select>
</div>

Upvotes: 0

Cue
Cue

Reputation: 2759

What about grouping each select with a numeric value in an ascending fashion and filtering by value as reference?

Each select can be grouped in sequential order using data-group="N". This can be targeted by data-target="N" where target is the group number you wish to show next. When each list changes state, the target group is filtered by the group being targeted, furthermore by the data-ref which is referenced by the value of the current list. Thus, the corresponding list is shown.

Here's an example, only I've populated the first tier divisions and clubs out of good will. But you get the gist...

var groups = $("select[data-group]");

$("select[data-target]").on("change", function () {
  var selectedRef = $(this).val();
  if (!selectedRef) {
    groups.hide();
    return;
  }

  var targetGroup = Number($(this).data('target'));
  if (targetGroup) {
    groups.filter(function() {
      var group = Number($(this).data('group'));
      return (group === targetGroup || group > targetGroup);
    }).hide();
    
    groups.filter(`[data-ref="${selectedRef}"]`).show();
  }
});
[data-group="1"],
[data-group="2"] {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<select data-target="1">
  <option value="">-- Select --</option>
  <option value="England">England</option>
  <option value="Spain">Spain</option>
  <option value="Italy">Italy</option>
</select>

<!-- Tiers by country -->
<select data-group="1" data-target="2" data-ref="England">
  <option value="">-- Select --</option>
  <option value="PremierLeague">Premier League</option>
  <option value="Championship">Championship</option>
  <option value="LeagueOne">League One</option>
  <option value="LeagueTwo">League One</option>
</select>
<select data-group="1" data-target="2" data-ref="Spain">
  <option value="">-- Select --</option>
  <option value="LaLiga">La Liga</option>
  <option value="SegundaDivision">Segunda División</option>
  <option value="SegundaDivision B">Segunda División B</option>
  <option value="TerceraDivision">Tercera División</option>
</select>
<select data-group="1" data-target="2" data-ref="Italy">
  <option value="">-- Select --</option>
  <option value="SerieA">Serie A</option>
  <option value="SerieB">Serie B</option>
  <option value="SerieC">Serie C</option>
</select>

<!-- Teams by tier -->
<select data-group="2" data-ref="PremierLeague">
  <option value="">-- Select --</option>
  <option>Arsenal</option>
  <option>Aston Villa</option>
  <option>Barnsley</option>
  <option>...</option>
</select>
<select data-group="2" data-ref="LaLiga">
  <option value="">-- Select --</option>
  <option>Alavés</option>
  <option>Athletic Bilbao</option>
  <option>Atlético Madrid</option>
  <option>...</option>
</select>
<select data-group="2" data-ref="SerieA">
  <option value="">-- Select --</option>
  <option>Atalanta</option>
  <option>Bologna</option>
  <option>Brescia</option>
  <option>...</option>
</select>

Upvotes: 1

Related Questions