Search code examples
javascriptjqueryselectioncascadingdropdown

Cascade Select with Existing Multiple Select Form


I'm working with a PHP output form that works in conjunction with JavaScript to create a composite file name that becomes a download.

I have implemented this post as well:

Three Select Boxes Interacting to Yield One Result - HTML, JavaScript or jQuery

So now I have an existing multiple selection form:

<select id="one">
    <option value="default">Select Product</option>
    <option class="s" value="1">product1</option>
    <option class="q" value="2">product2</option>
    <option class="q" value="3">product3</option>
</select>

<select id="two">
    <option value="default">Select Version</option>
    <option class="l" value="4">product4</option>
    <option class="l" value="5">product5</option>
    <option class="c" value="6">product6</option>
</select>

<select id="three">
    <option value="default">Select OS</option>
    <option class="o" value="7">product7</option>
    <option class="o" value="8">product8</option>
    <option class="o" value="9">product9</option>
</select>

<select id="three">
    <option value="default">Select Architecture</option>
    <option class="a" value="10">product10</option>
    <option class="a" value="11">product11</option>
    <option class="a" value="12">product12</option>
</select>

When the button is clicked it concatenates the strings and creates an URL that is a download installer. This works fine and in most cases yields a valid file to download.

But there are several options that are invalid. I added the classes above just for this post, because it's clear they are in the corresponding groups.

Now, the question here is, how do I get the cascading affect with this existing form? The PHP and JavaScript I'm using is:

From the PHP file:

$output .=  '<div><p class="download-button"><a id="viewer-dl"';
$output .=  ' onclick="download_file(document.getElementById(';
$output .=  "'" . $product_id . "'" . ').value, document.getElementById(';
$output .=  "'" . $version_id . "'" . ').value, document.getElementById(';
$output .=  "'" . $os_id      . "'" . ').value, document.getElementById(';
$output .=  "'" . $arch_id    . "'" . ')"></a></p></div>';

From the JavaScript file:

$(function() {
    $("#viewer-dl").click(function() {
        download_viewer( $('#product_id').val(), $('#version_id').val(), 
            $('#os_id').val(), $('#arch_id').val());
    });
});

function download_file(version_id, os_id, arch_id) {

    if (product_id == 'default' && version_id == 'default' && 
        os_id == 'default' && arch_id == 'default') {
        return;
    }

    else if (product_id != 'default') {
        window.location = 'mysite.com/download/Install_' +
            product_id + '_' + version_id + '_' + arch_id + '.exe';
    }
}

What I'm trying to do is when the s class is selected, I want the the l and c classes selected for the next selection, but when the q class is selected, I only want the c class selected. The OS, Architecture selections I want to be there for all choices, hence the classes are the same for these.


Solution

  • I created small demo what you can do to JSFiddle: http://jsfiddle.net/nx6yF/

    Basically what I did that I hided all other selects but first, then if first select changes you have to check the selection and show second select

    $("#one").change(function() {
            var val = $(this).val();
            if (val != "default") {
                $("#two").show();
            }
    });
    

    You also need to decide which options to show in second select. Maybe class is not the most practical thing to handle this, but it could be something like this:

     var is_q = $("#one > option[value="+val+"]").hasClass("q");
     $("#two > option").each(function() {
          if (!$(this).hasClass("c") && $(this).val() != "default") {
              if (is_q) {
                  $(this).attr("disabled",true);
              }
              else{
                  $(this).attr("disabled",false);
              }
          }
     });
    

    I used here disabling options but as well it would be possible to hide them. Anyway disabled / hided selection should be also changed to default if selected, in order to make form work correctly with multiple selects

    After this you can check if selection two is selected and then show select three. Of course, is some select has value default, then next selects should be hided.

    I'm not sure is there any easy answer, how to create cascading effect - it just needs coding to do it.