0

I have a two drop down menus in a form, and I want the options in the second drop down to change based on the selection in the first. Eventually I will also add a 3rd select based on the 2nd, and a 4th based on the 3rd.

I stored the options in an array and have written a long if statement to pull in the corresponding array based on the first selection, but seems like there has to be a better way to do this rather than repeating all the code. This does the job but I would like to improve the code.

I have looked at tutorials online which refer to databases and JSON data, and I can't quite wrap my head around it. I do have access to a database on a different server/domain than this form will live on but am not very familiar with databases so this was an easier path for me to go down. There are a few posts I've seen on this site too but they're very specific (like mine) and don't help me.

Hope this makes sense. This is my first time using arrays or trying to do anything like this so thanks in advance for helping me learn!

JSfiddle: http://jsfiddle.net/QhBLq/

Here is my code:

    $(document).ready(function() {
        $('div' + '.menu').hide();
        $('a').click(function ()
        {
            $('#' + $(this).attr('class')).show().siblings('div').hide();
        });
        var cookwareProds = [ "Round French Oven", "Oval French Oven", "Braiser", "Skillet", "Fry Pan", "Grill Pan", "Saute Pan", "Saucepan", "Saucier", "Griddle", "Roaster", "Stockpot", "Speciality Cookware", "Other"];
        var bakewareProds = [ "Covered Casserole", "Baking Dish", "Stoneware Gratin", "Speciality Bakeware", "Individual Bakeware", "Metal Bakeware", "Other"];
        var kitchenToolProds = [ "Utensils", "Kitchen Accessories", "Cutlery", "Wine Tools", "Textiles", "Other"];
        var dineEntertainProds = [ "Dinnerware", "Serveware", "Tabletop Accessories", "Glassware", "Kettles", "Tea Collection", "Café Collection", "Other"];
        var prodSelect = $('select');
        prodSelect.change(function () {
            var catSelected = $(this).val();
            $('#subCats').fadeIn('fast');       
            $(this).parent("li").next().find("select > option").remove(); /*Prevents previous options from persisting in menu if parent category selection is changed*/             
            if (catSelected == 'Cookware') {
                $.each(cookwareProds, function(key, value) {   
                 $('#product-type')
                     .append($("<option></option>")
                     .attr("value",value)
                     .text(value)); 
            }); 
            } 
            if (catSelected == 'Bakeware') {
                $.each(bakewareProds, function(key, value) {   
                 $('#product-type')
                     .append($("<option></option>")
                     .attr("value",value)
                     .text(value)); 
            }); 
            } 
            if (catSelected == 'Kitchen Tools') {
                $.each(kitchenToolProds, function(key, value) {   
                 $('#product-type')
                     .append($("<option></option>")
                     .attr("value",value)
                     .text(value)); 
            }); 
            } 
            if (catSelected == 'Dine & Entertain') {
                $.each(dineEntertainProds, function(key, value) {   
                 $('#product-type')
                     .append($("<option></option>")
                     .attr("value",value)
                     .text(value)); 
            }); 
            }               
            if (catSelected == 'Other') {
                $(this).next('.other').show();
            } else $(this).next('.other').hide();
        });         
    });

2 Answers 2

1

Simplified code using an object, otherwise unchanged from your fiddle:

$(document).ready(function () {
    $('div' + '.menu').hide();
    $('a').click(function () {
        $('#' + $(this).attr('class')).show().siblings('div').hide();
    });

    prods = {
        Cookware: ["Round French Oven", "Oval French Oven", "Braiser", "Skillet", "Fry Pan", "Grill Pan", "Saute Pan", "Saucepan", "Saucier", "Griddle", "Roaster", "Stockpot", "Speciality Cookware", "Other"],
        Bakeware: ["Covered Casserole", "Baking Dish", "Stoneware Gratin", "Speciality Bakeware", "Individual Bakeware", "Metal Bakeware", "Other"],
        "Kitchen Tools": ["Utensils", "Kitchen Accessories", "Cutlery", "Wine Tools", "Textiles", "Other"],
        "Dine & Entertain": ["Dinnerware", "Serveware", "Tabletop Accessories", "Glassware", "Kettles", "Tea Collection", "Café Collection", "Other"]
    };
    var prodSelect = $('select');
    prodSelect.change(function () {
        var catSelected = $(this).val();
        $('#subCats').fadeIn('fast');
        $(this).parent("li").next().find("select > option").remove(); /*Prevents previous options from persisting in menu if parent category selection is changed*/
        $.each(prods[catSelected], function (key, value) {
            $('#product-type')
                .append($("<option></option>")
                .attr("value", value)
                .text(value));
        });
    });
});
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, this is close to what I need! When I apply this, I get a type error upon making a selection in the second drop down. In FF it says "e is undefined" chrome tells me "Uncaught TypeError: Cannot read property 'length' of undefined". Any ideas? Also, the hidden field for Other is not working now...
I figured this out, your answer is great. I was getting the error because I the object did not apply to the options in the second drop down. Created another following your model and works perfectly. Thanks for your help.
Awesome, I was just about to see if I could recreate the problem, but no need then ;) -You can expand the model a bit and make child-objects for each product as well (instead of just a string, make each item another object like label:'KitchenWare', children: {[...]}), that way you can store an unlimited number of choices and sub choices inside a single variable, while maintaining a relatively easy-to-read syntax... But seems like you're learning, so I figured better to start slow and not rewrite your entire code.
0

This is called a "Cascading Dropdown", for example http://jquery-plugins.net/jquery-cascading-dropdown-plugin, or take your choice of many other similar plugins

$('#example1').cascadingDropdown({
    selectBoxes: [
        {
            selector: '.step1',
            selected: '4.3'
        },
        {
            selector: '.step2',
            requires: ['.step1']
        },
        {
            selector: '.step3',
            requires: ['.step1', '.step2'],
            onChange: function(event, value, requiredValues) {
                // do stuff

                // event is the change event object for the current dropdown
                // value is the current dropdown value
                // requiredValues is an object with required dropdown values
                // requirementsMet is a boolean value to indicate if all requirements (including current dropdown having a value) have been met
            }
        }
    ]
});

1 Comment

Thanks for the suggestion! I would prefer not to do this with a plugin but if I can't figure this out on my own will definitely use this as a resource.

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.