Have an idea?

Visit Sawtooth Software Feedback to share your ideas on how we can improve our products.

Dropdown Menu options dependent on previous question

My company wants to build an online database of what types of vehicles people have in the household.  I'm trying to use Free Format to include drop down menus so first a person will specify what make of vehicle they own then the model (i.e. if they choose "Ford" as "make" then the options under "model" will be "F-150", "Explorer", "Taurus", etc.).  This is what I'm using right now but its not working out:

<label for="req_make">Make</label>
<select id="req_make" name="make">
    <option disabled="disabled" selected="selected" value="">Choose Make</option>
    <option class="BMW" value="BMW">BMW</option>
    <option class="Audi" value="Audi">Audi</option>
    <option class="VW" value="VW">VW</option>
</select>

<label for="req_model">Model</label>
<select id="req_model" name="model">
    <option disabled="disabled" selected="selected" value="">Choose model</option>
    <option class="BMW" value="1er">1er</option>
    <option class="BMW" value="3er">3er</option>
    <option class="BMW" value="5er">5er</option>
    <option class="BMW" value="7er">7er</option>
    <option class="Audi" value="A4">A4</option>
    <option class="Audi" value="A8">A8</option>
    <option class="Audi" value="Q7">Q7</option>
    <option class="VW" value="Golf">Golf</option>
    <option class="VW" value="Touran">Touran</option>
</select>


<script type="text/javascript">
$(function(){
    $("#req_make").on("change",function(){
        var levelClass = $('#req_make').find('option:selected').attr('value');
        console.log(levelClass);
        $('#req_model option').each(function () {
            var self = $(this);
            if (self.hasClass(levelClass) || typeof(levelClass) == "undefined") {
                self.show();
            } else {
                self.hide();
            }
        });
    });
});
</script>

Any help would be greatly appreciated
asked Nov 30, 2017 by anonymous
I would recommend against using show / hide on the select options.  Won't work on any version of IE, even IE 11.

Dynamically adding and removing the "hidden" attribute on the select options is better, but still only supported in IE 11.  Fails in older versions of IE.

<option hidden value="1er">1er</option>


For more true browser compatibility, I would recommend instead taking one of these two approaches:

1) Create multiple selects, one for BMW, one for Audi, and one for VW.  Instead of showing and hiding options, you can just show / hide whole selects.

2) Store the dropdown options in JavaScript.  Instead of showing or hiding options, delete and re-add the options as needed to the select element.

If you could use a hand in programming up one of those options, I'd be happy to help.
Thanks for quick response.  Is there any one of those options that you think would work better than the other with what I'm trying to do.  Option 2 sounds like the best bet for me.

I'm fairly new to the whole programming game, but trying to learn as much as I can.  Something like this would not only be a big help for this project but also for future surveys that my company conducts.  So I would really appreciate a hand with the programming of this even if its just a small outline to guide me in the right direction and boost up my knowledge a little more.
Looks like there might be an example of this in the community question library: https://www.sawtoothsoftware.com/community-question-library/1767-drilldown-dropdowns
Drilldowns seems like exactly what is required for this project.
I noticed that this was done in Lighthouse, will this work in V 8.4.8 thats what I'm running off of now.  We haven't made the jump to Lighthouse just yet over here because we use our own server for web hosting.

1 Answer

0 votes
Here is the code you can add to your free format question in SSI Web:

<style>
.drilldown_clone {
    display: none;
}
</style>

<script>
$(document).ready(function(){
    var drilldownSettings = {
        empty: 1,
        disabled: 2,
        hidden: 3
    }

    AddDrilldown('FreeFormatQ_combo1', 'FreeFormatQ_combo2', drilldownSettings.disabled, // when Drilldown1 is unanswered, disable Drilldown2
        { // when Drilldown1 = 1, show the first three options of Drilldown2
            when: 1,
            then: [1, 2, 3]
        }, { // when Drilldown1 = 2, show the middle three options of Drilldown2
            when: 2,
            then: [4, 5, 6]
        }, { // when Drilldown1 = 3, show the last three options of Drilldown2
            when: 3,
            then: [7, 8, 9]
        });
    AddDrilldown('FreeFormatQ_combo2', 'FreeFormatQ_combo3', drilldownSettings.disabled,
        { when: 1, then: [1, 2] },
        { when: 2, then: [3, 4] },
        { when: 3, then: [5, 6] },
        { when: 4, then: [7, 8] },
        { when: 5, then: [9, 10] },
        { when: 6, then: [11, 12] },
        { when: 7, then: [13, 14] },
        { when: 8, then: [15, 16] },
        { when: 9, then: [17, 18] });
})

function AddDrilldown(independentDropdown, dependentDropdown) {
    // Move dependent dropdown
    $('#' + independentDropdown).after($('#' + dependentDropdown));
    
    // Clone
    var clone = $('#' + dependentDropdown).clone();
    $(clone).attr('id', '');
    $(clone).attr('name', '');
    $(clone).addClass('drilldown_clone');
    $(clone).attr('data-cloneof', dependentDropdown);
    $(clone).children('option').removeAttr('selected');
    $('#' + dependentDropdown).after(clone);
    
    // CSS
    $('#' + independentDropdown + ', #' + dependentDropdown).css('margin', '4px');
    $('#' + dependentDropdown).css('width', $(clone).css('width'));
    
    // Change
    var args = arguments;
    $('#' + independentDropdown).change(function(){
        var independentValue = SSI_GetValue(independentDropdown);
        var dependentValue = SSI_GetValue(dependentDropdown);
        var clone = $('#' + dependentDropdown).siblings('.drilldown_clone[data-cloneof="' + dependentDropdown + '"]');
        
        $('#' + dependentDropdown + ' > option:not(:first-child)').remove();
        if (independentValue) {
            $('#' + dependentDropdown).prop('disabled', false);
            $('#' + dependentDropdown).show();
            
            for (var i = 3; i < args.length; i++) {
                var arg = args[i];
                if (arg.when == independentValue) {
                    arg.then.forEach(function(t) {
                        $('#' + dependentDropdown).append($(clone).children('option[value="' + t + '"]').clone());
                        if (t == dependentValue) {
                            $('#' + dependentDropdown).val(t);
                        }
                    });
                    break;
                }
            }
        }
        else {
            switch (args[2]) {
                case 2:
                    $('#' + dependentDropdown).prop('disabled', true);
                    break;
                case 3:
                    $('#' + dependentDropdown).hide();
                    break;
            }
        }
        
        $('#' + dependentDropdown).change();
    });
    
    $('#' + independentDropdown).change();
}
</script>


Be sure to follow the instructions in the link in the comments to make the changes necessary for your situation.
answered Nov 30, 2017 by Zachary Platinum Sawtooth Software, Inc. (96,175 points)
That worked out perfectly thanks for your help
...