tags:

views:

50

answers:

2

I have a form that looks like:

<form action="search.php" method="post">
        <fieldset>
          <label for="level_one">Main category</label>
          <select name="level_one" id="level_one">
            <option value="0">All main categories</option>
                        <option value="7">Health</option>
                        <option value="11">Life</option>
                        <option value="8">Mind</option>
                        <option value="16">Relationships</option>
                      </select>
          <label for="level_two">Sub category</label>
          <select name="level_two" id="level_two">
            <option value="0" class="no_parent">All categories</option>
                        <option value="36" class="parent_id_7">Swine flu</option>
                        <option value="34" class="parent_id_7">Therapies</option>
                        <option value="40" class="parent_id_11">Bullying</option>
                        <option value="28" class="parent_id_11">Volunteering</option>
                        <option value="19" class="parent_id_8">Depression</option>
                        <option value="29" class="parent_id_16">Relationship problems</option>
                        <option value="37" class="parent_id_16">Separation and divorce</option>
                      </select>

          <input type="submit" value="Search" />
        </fieldset>
      </form>

With JQuery I hide the second select, then when the first select changes JQuery looks at the selection and shows the second select with only the relevant items in it. The JQuery:

$(document).ready(function () {
  $('#level_two').hide()
  $('#level_one').change(function(){
   var current = $(this).val();
   if(current == 0) {
     $('#level_two').hide()
   } else {
     $('#level_two option').not('.no_parent').hide()
     $('.parent_id_'+current).show();
     $('#level_two').val("no_parent");  //gert g's addition :)
     $('#level_two').show()
   }
  });
});

This works fine except for a small issue. If I select "Health" in select 1, select 2 shows "swine flu" and "Therapies", then I select "Therapies", now if I select life in select 1, select 2 shows the correct options except the default text in select 2 still says "Therapies" even though the therapies option is hidden.

Is there a way to refresh the text to stop this happening.

Regards

Luke

UPDATE: I have updated the code to working order thanks to @Gert G for the solution

UPDATE: The current solution only works in FireFox :(

UPDATE: I have used a slightly modified version of @Paolo Bergantino's solution that works for sure on chrome and FF, yet to finish testing all browsers.

jQuery.fn.filterOn = function(radio, values) {
        return this.each(function() {
          var select = this;
          var options = [];
          $(select).find('option').each(function() {
            options.push({value: $(this).val(), text: $(this).text()});
          });
          $('#level_two').data('options', options);
          $('#level_one').change(function() {
            var options = $(select).empty().data('options');
            var haystack = values[$(this).val()];
            if($(this).val()==0){
              $('#level_two').hide().siblings('label[for="level_two"]').hide();
            } else $('#level_two').show().siblings('label[for="level_two"]').show();
            $.each(options, function(i) {
              var option = options[i];
              if($.inArray(option.value, haystack) !== -1) {
                $(select).append(
                $('<option>').text(option.text).val(option.value)
              );
              }
            });
          });
        });
      };
      $(document).ready(function () {
        $('#level_two').hide().siblings('label[for="level_two"]').hide();
        $(function() {
          $('#level_two').filterOn('#level_one', {
                        '7': ["35","12","17","32","33","46","30","31","15","36","34"],
                        '11': ["40","25","27","41","22","26","44","28"],
                        '8': ["19","21","20"],
                        '16': ["29","37","23"],
                        '10': ["14","43","45","39"],
                      }); //note there are way more values in these arrays as I did not enter the full form that I am using above just a short example
        });
      });
A: 

Just thought, you are not reselecting an option when you change the first dropdown for the second time. So it may just be a simple "selected" problem.
Try something like this at the end of your change event;

$('#level_two option.parent_id_'+current+':first').attr("selected", "selected").siblings().removeAttr("selected");

or maybe this will do too;

$('#level_two option').removeAttr("selected");
danrichardson
+2  A: 

-- New and improved version --

jQuery

<script type="text/javascript">
  $(document).ready(function() {
    var LevelTwoData=[];
    LevelTwoData["7"]= { "36":"Swine flu",
                         "34":"Therapies" };
    LevelTwoData["11"]={ "40":"Bullying",
                         "28":"Volunteering" };
    LevelTwoData["8"]= { "19":"Depression" };
    LevelTwoData["16"]={ "29":"Relationship problems",
                         "37":"Separation and divorce" };

    $("#level_one").change(function() {
      $('#level_two').val("0");  // Set "All categories" as the selected option
      $('#level_two option:not(:first)').remove();  // Remove all previous values

      var LevelOneVal=$("#level_one").val();  // Grab main category value

      if(LevelTwoData[LevelOneVal]!=undefined) {  // If the category has subcategories
        $.each(LevelTwoData[LevelOneVal],function(Value,Text) {  // Loop through the subcateries and add them as options
          $('#level_two').append(
            $('<option></option>').val(Value).html(Text)
          );
        });

        $('#level_two').show();
      } else {
        $('#level_two').hide();
      }
    });
  });
</script>

HTML

<form action="search.php" method="post">
  <fieldset>
    <label for="level_one">Main category</label>
    <select name="level_one" id="level_one">
      <option value="0">All main categories</option>
      <option value="7">Health</option>
      <option value="11">Life</option>
      <option value="8">Mind</option>
      <option value="16">Relationships</option>
    </select>
    <label for="level_two">Sub category</label>
    <select name="level_two" id="level_two">
      <option value="0">All categories</option>
    </select>

    <input type="submit" value="Search" />
  </fieldset>
</form>

-- Original (works as originally asked by Luke, but classes only works in Firefox) --

jQuery

<script type="text/javascript">
  $(document).ready(function () {
    $('#level_two').hide()
    $('#level_one').change(function(){
     var current = $(this).val();
     if(current == 0) {
       $('#level_two').hide()
     } else {
       $('#level_two option:not(.s0)').hide()
       $('#level_two').val("s0"); // Reset the option
       $('.s'+current).show();
       $('#level_two').show()
     }
    });
  });
</script>

HTML

<form action="search.php" method="post">
  <fieldset>
    <label for="level_one">Main category</label>
    <select name="level_one" id="level_one">
      <option value="0">All main categories</option>
      <option value="7">Health</option>
      <option value="11">Life</option>
      <option value="8">Mind</option>
      <option value="16">Relationships</option>
    </select>
    <label for="level_two">Sub category</label>
    <select name="level_two" id="level_two">
      <option value="0" class="s0">All categories</option>
      <option value="36" class="s7">Swine flu</option>
      <option value="34" class="s7">Therapies</option>
      <option value="40" class="s11">Bullying</option>
      <option value="28" class="s11">Volunteering</option>
      <option value="19" class="s8">Depression</option>
      <option value="29" class="s16">Relationship problems</option>
      <option value="37" class="s16">Separation and divorce</option>
    </select>

    <input type="submit" value="Search" />
  </fieldset>
</form>

Essentially you need to reset the option for the second upon the refresh of the first select.

Gert G
Thanks Gert G thats perfect. Cheers Luke
Luke
No problem. :) It's an interesting approach to updating a select box.
Gert G
Gert - How interesting is it when the *only* browser it works in is Firefox?
patrick dw
@patrick - As I wrote... it's an interesting approach. Perhaps it's an internal app in a company that only support Firefox?
Gert G
Gert - Sure. It is an interesting solution in Firefox. In (apparently) all other browsers it is a broken solution. Hope future readers take the time to read comments.
patrick dw
@patrick I updated the question to say that the solution only works in FireFox
Luke
@Luke - If you need it to work cross browser, you'll need to choose a non-hide/show solution. I.e. update the options on the fly.
Gert G