Jakob Busk Sørensen
Jakob Busk Sørensen

Reputation: 6081

Using JavaScript to filter a drop down menu

Based on post here on StackOverflow, I am trying to make a drop down menu, which contents depends on the selection of another drop down menu.

Fortunately the solution I found, is very applicable to my problem, although I originally do get my drop down menu options from a database. Less fortunately however, is that I cannot seem to get the solution to work.

Both menus are correctly read from the database, and converted to the correct HTML-code. So what seems to fail is the JavaScript which is used to filter the options in the second drop down menu. My code is as following:

<div id="selection">
    <?php
        // Top level part selection
        echo "<select name='firstLevelParts' id='select1'>";
        foreach ($category_primary as $category_item):
            echo "<option value = '".$category_item['cat_primary_id']."'>".$category_item['cat_primary_name']."</option>";
        endforeach;
        echo "</select>";


        // Second level part selection (This should be updated, based on selection in top level menu)
        echo "<select name='secondLevelParts' id='select2'>";
        foreach ($category_secondary as $cat_sec_item):
             echo "<option value='".$cat_sec_item['cat_secondary_code']."'>".$cat_sec_item['cat_secondary_name']."</option>"; 
        endforeach;
        echo "</select>";
    ?>

</div>


<script>
    $("#select1").change(function() { 
        if(typeof $(this).data('options') === "undefined")){
            /*Taking an array of all options-2 and kind of embedding it on the select1*/
            $(this).data('options',$('#select2 option').clone());
            } 
        var id = $(this).val();
        var options = $(this).data('options').filter('[value=' + id + ']');
        $('#select2').html(options);
    });
</script>

I really hope you can help me locating the flaw in my code, I really annoys the heck out of me...

Update - Per request, here is the resulting HTML-code, I can't really give you the page url, as it lies behind password protection:

<div id="selection">
<select name='firstLevelParts' id='select1'>
 <option value = '1'>Terræn</option>
 <option value = '2'>Fundamentsystem</option>
 <option value = '3'>Vægsystem</option>
 <option value = '4'>Dæksystem</option>
 <option value = '5'>Tagsystem</option>
</select>

<select name='secondLevelParts' id='select2'>
 <option value='1'>Jordprofil</option>
 <option value='2'>Befæstet Areal</option>
 <option value='3'>Beplantning</option>
 <option value='1'>Fundamentkonstruktion</option>
 <option value='2'>Bærelag</option>
 <option value='3'>Åbning</option>
 <option value='4'>Lukning</option>
 <option value='5'>Inddækning</option>
 <option value='6'>Afslutning</option>
 <option value='7'>Afskærmning</option>
 <option value='8'>Fuge</option>
 <option value='9'>Samling</option>
 <option value='10'>Overflade</option>
</select>  
</div>

<script>
    $("#select1").change(function() { 
        if(typeof $(this).data('options') === "undefined")){
            /*Taking an array of all options-2 and kind of embedding it on the select1*/
            $(this).data('options',$('#select2 option').clone());
            } 
        var id = $(this).val();
        var options = $(this).data('options').filter('[value=' + id + ']');
        $('#select2').html(options);
    });
</script> 

Upvotes: 2

Views: 24672

Answers (3)

arendjr
arendjr

Reputation: 719

I hope I'm understanding your question correctly, but it sounds like what you want is actually a use case supported by the Select3 library, though it presents the choices in nested dropdowns rather than separated select boxes.

Just take a look at the fourth example on that page (titled 'Select a city by timezone') and see if it does what you want. If you have any other questions on how to set it up, I'm open for questions!

Upvotes: 0

Wesley Smith
Wesley Smith

Reputation: 19571

Adapted from this solution to a similar problem the below should do what you want:

$(function() {
  $('#select').filterByValues( $('.filterElements') );
  $('.filterElements').change();
});  


jQuery.fn.filterByValues = function(masterSelects) {
  return this.each(function() {
    var select = this;
    var options = [];
    $(select).find('option').each(function() {
      options.push({value: $(this).val(), text: $(this).text()});
    });
    $(select).data('options', options);
    
    masterSelects.bind('change', function() {
      var options = $(select).empty().scrollTop(0).data('options');
      var vals=[];
      $(masterSelects).each(function(i,e){
        vals.push('^'+$.trim($(e).val())+'$' );
       });
      var search = vals.join('|');
      var regex = new RegExp(search,'gi');

      $.each(options, function(i) {
        var option = options[i];
        if(option.value.match(regex) !== null) {
          $(select).append(
             $('<option>').text(option.text).val(option.value)
          );
        }
      });
    });
    
  });
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="selection">
<select name='firstLevelParts' class='filterElements'>
 <option value = '0'>(Select category)</option> <!-- added -->
 <option value = '1'>Terræn</option>
 <option value = '2'>Fundamentsystem</option>
 <option value = '3'>Vægsystem</option>
 <option value = '4'>Dæksystem</option>
 <option value = '5'>Tagsystem</option>
</select>
  
<select name='firstLevelPartsB'  class='filterElements'>
 <option value = '0'>(Select category)</option> <!-- added -->
 <option value = '1'>Terræn</option>
 <option value = '2'>Fundamentsystem</option>
 <option value = '3'>Vægsystem</option>
 <option value = '4'>Dæksystem</option>
 <option value = '5'>Tagsystem</option>
</select>

<select name='secondLevelParts' id='select'>
 <option value='1'>Jordprofil</option>
 <option value='2'>Befæstet Areal</option>
 <option value='3'>Beplantning</option>
 <option value='1'>Fundamentkonstruktion</option>
 <option value='2'>Bærelag</option>
 <option value='3'>Åbning</option>
 <option value='4'>Lukning</option>
 <option value='5'>Inddækning</option>
 <option value='6'>Afslutning</option>
 <option value='7'>Afskærmning</option>
 <option value='8'>Fuge</option>
 <option value='9'>Samling</option>
 <option value='10'>Overflade</option>
</select>  
</div>

Upvotes: 2

rakhmanoff
rakhmanoff

Reputation: 369

I think, that problem is in simple error in your syntax - you have extra ")" in your condition if(typeof $(this).data('options') === "undefined")){

Here is your jsfiddle without this error - it works: http://jsfiddle.net/dn7fLny5/

EDIT: You can attach your hanlders after DOM ready like this:

<script>
    $(document).ready(function() {
        $("#select1").change(function() { 
            // your code
        });
    });
</script>

Upvotes: 0

Related Questions