2

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> 
2
  • 1
    can we see the resultant html. If the boxes have many options you can shorten it but it'd be good to see what the result is Commented Feb 8, 2015 at 10:57
  • It is now added to the original post... Commented Feb 8, 2015 at 11:40

3 Answers 3

2

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>

Sign up to request clarification or add additional context in comments.

6 Comments

This actually seems to work. Does it have any advangtes/disadvantages compared to my original solution? (Besides the obvious fact that it actually works...)
@Noceo it should be more efficient and it's basically a plug-in so it's extremely re-usable, just call $('#select2').filterByValue($('#select1'), true); and supply the elements to filter by and on.
Thanks, one last question if I might... I am trying to add an option called "(Select category)" in menu one, which have value zero, and should allow only one option (of the same name) to be shown in menu two. Should this not be possible just by having them use value="0" ?
Yes, you can do this, just make sure to call $('#select1').change(); right after you call the plugin, that way it will clear the options that are visible when the page loads, I updated my answer to show this
More problems :-). Is it possible to have two set of values for menu two? One which matches menu one values (as in what you posted) and a second set of values which is related to a third menu?
|
0

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>

3 Comments

Just noticed that myself, however removing it did not seem to change anything, which makes me wonder if it even tries to run the script...
Did you use $(document).ready(function() {...}) for attach your handlers?
No, and now I have the feeling that I should have... Where does this go? Found something about in on this page: learn.jquery.com/using-jquery-core/document-ready - but I am still kinda new to JavaScript.
0

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!

1 Comment

Not sure if it is exactly what I was looking for, but its definitely something I can use for other parts of the projects, so thanks. The issue right now is that I have a 3 layer category system, where you first need to select the top category, then the middle and then the bottom. And the options of the middle category depends on top and the options of bottom depends on the middle. So its sort of like a 3 layer dependency system...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.