Search code examples
javascriptjqueryformsdropdown

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');

}

});


Solution

  • 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>