Cascading Dropdown

Cascading dropdown in jQuery. Debugging extra firing of change events.

by goodeye

HTML

<script src="http://www.quicksource.com/projects/jsfiddle/js/jquery.selectboxes.min.js"></script>
<div class="chooseSteps">
    <select class="ddStep1">
        <option value="-">-- Step1 --</option>
        <option value="1">v11</option>
        <option value="2">v12</option>
        <option value="5">v15</option>
        <option value="6">v16</option>
    </select>
      
    <select class="ddStep2">
      <option value="-">-- Step2 --</option>
    </select>

    <select class="ddStep3">
      <option value="-">-- Step3 --</option>
    </select>

    <select name="ddStep4" class="ddStep4">
      <option value="-">-- Step4 --</option>
    </select>
</div>

<div id="divDebug">
</div>

JavaScript

//----------------------------------------
  // Cascading Dropdown
  //----------------------------------------
  // Basic idea from www.mikesdotnetting.com/Article/97/Cascading-DropDownLists-with-jQuery-and-ASP.NET
  // [... json/ajax comments omitted...]
  // Handle two sets of dropdowns on the page, using classes for identification.
  // If single value, pre-select it and fire the change event to load the next dropdown. 

  $('.ddStep1').change(getStep2);
  $('.ddStep2').attr('disabled', true);
  $('.ddStep3').attr('disabled', true);
  $('.ddStep4').attr('disabled', true);


  // Step 2: Get step2 for given step1.
  function getStep2() {

    $('#divDebug').append("getStep2<br />");
      
    // Get the steps for this group.
    //  This re-finds the current step, but the logic is the same for all this way.
    var chooseSteps = $(this).closest('.chooseSteps')
    var ddStep1 = chooseSteps.find('.ddStep1');
    var ddStep2 = chooseSteps.find('.ddStep2');
    var ddStep3 = chooseSteps.find('.ddStep3');
    var ddStep4 = chooseSteps.find('.ddStep4');

    // Reset and disable the remaining dropdowns (this dropdown is below).
    //  Keep the first default option; now a single hyphen due to Chrome not selecting an empty option (see below).
    //    For not-first jquery selector, see stackoverflow.com/questions/2259393/jquery-select-all-except-first/2259397#2259397
    //    gt(0) or :not(:first)
    //  Formerly used the selectboxes plugin, but it didn't have a simple starting-from-n argument.
    //    The default was formerly empty; keeping it worked with the plugin example's /./ actually removing only not-empty. Need /.*/ for clear all.
    ddStep3.attr('disabled', true).find('option:gt(0)').remove();
    ddStep4.attr('disabled', true).find('option:gt(0)').remove();

    // Check in case reselected the default.
    //  Reset and disable this step.
    if (ddStep1.val() == "-") {
      ddStep2.attr('disabled', true).find('option:gt(0)').remove();
     ...