Zigu
Zigu

Reputation: 1665

How to make multiple dependent dropdowns using jquery + ajax

I'm trying to build a page where users can give worksheets to each other.

I am trying to do it with dependent dropdowns. Not sure if that is the right term for it so I will provide an example.

Roughly the set categorizations is as follows: Types > Categories > Topics > Sheets

Roughly my idea is:

  1. Page loads json for types and displays type dropdown
  2. User sees Math, Science, English as Types and Picks Math
  3. Page uses ajax to query database and populates Topics with grade 1, 2, 3, etc.
  4. User picks grade 4
  5. Page uses ajax to query database and populates with appropriate grade 4 topics
  6. ... and so on until the bottom of the chain

In the javascript section:

<script type="text/javascript" language="javascript">
    var types;
    var categories;
    var topics;
    var sheets;

    //load the first types
    $(document).ready(function(){
        $.ajax({
            async: false,
            url: "base_url/json_get_all_wstypes",
            type: 'POST',
            dataType: 'json',
            success: function(output_string){
                types = output_string;
            }
        });
    });

    //by default - intialize types
    $(document).ready(function(){
        var t_choices = "<select name=\"type_id\" id=\"type_picker\" >";
        t_choices += "<option value=\"\" selected=\"selected\">Select a Type</option>";

        $.each(types, function(){
            t_choices += "<option value=\"" + this.type_id.toString() + "\">";
            t_choices += this.type_name.toString();
            t_choices += "</option>";
        });

        t_choices += "</select>";

        $('#type_choices').text('');
        $(t_choices).appendTo('#type_choices');
    });

    //reaction to picking a type 
    $(document).ready(function(){
        $('#type_picker').change(function(){
            var url_arg = $('#type_picker').val().toString();
            var full_url = "base_url/json_get_wscategories_by_type/" + url_arg;

            $.ajax({
                async: false,
                url: full_url,
                type: 'POST',
                dataType: 'json',
                success: function(output_string){
                    categories = output_string;
                }
            });

            var choices = "<select name=\"category_id\" id=\"category_picker\" >"; 
            choices += "<option value=\"\" selected=\"selected\">Select a category</option>";

            $.each( categories, function() {
                choices += "<option value=\"" + this.category_id.toString() + "\">";
                choices += this.category_name.toString();
                choices += "</option>";
            });

            choices += "</select>";

            alert(choices.toString());

            $('#category_choices').text('');
            $(choices).appendTo('#category_choices');

        });
    }); 

    //reaction to picking a category (initialize topic)     
    $(document).ready(function(){
        $('#category_picker').change(function(){
            var url_arg = $('#category_picker').val().toString();
            var full_url = "base_url/json_get_wstopics_by_category/" + url_arg;

            $.ajax({
                async: false,
                url: full_url,
                type: 'POST',
                dataType: 'json',
                success: function(output_string){
                    topics = output_string;
                }
            });

            var choices = "<select name=\"topic_id\" id=\"topic_picker\" >"; 
            choices += "<option value=\"\" selected=\"selected\">Topic a category</option>";

            $.each( topics, function() {
                choices += "<option value=\"" + this.topic_id.toString() + "\">";
                choices += this.topic_name.toString();
                choices += "</option>";
            });

            choices += "</select>";

            alert(choices.toString());

            $('#topic_choices').text('');
            $(choices).appendTo('#topic_choices');

        });
    }); 

    //reaction to picking a topic (initialize sheet)
    similar code pattern as method before it...

    //reaction to picking a sheet (intialize page)
    similar code pattern as the method before...
</script>

In the webform section:

<p>
<label for="type_id">Pick a sheet type:</label>
<div id="type_choices">
</div>
</p>


<p>
<label for="categories_id">Pick a category:</label>
<div id="category_choices">
</div>
</p>

<p>
<label for="topic_id">Pick a topic:</label>
<div id="topic_choices">

</div>
</p>

<p>
<label for="worksheet_id">Pick a worksheet:</label>
<div id="sheet_choices">
Please select a topic first to activate this section
</div>
</p>

This works for selecting the types and loads up the display for categories but once I select categories nothing happens. Also, if anyone could point me to what is called in the web world, I would be quite thankful. Dynamic dependent dropdown weren't that helpful and I'm not sure what else to call this.

Upvotes: 3

Views: 5785

Answers (1)

Orbiting Eden
Orbiting Eden

Reputation: 1512

Your code is unnecessarily dependent on jQuery and doesn't re-use code effectively. This solution may require a subtle rewrite of your server side code, but that should be more abstracted anyway. Try something more like this:

<html>
<body>
<select id="type" onchange="updateNext(this, 'category')">
    <option value="a">A</option>
    <option value="b">B</option>
    <option value="c">C</option>
</select>
<select id="category" onchange="updateNext(this, 'topic')">
</select>
<select id="topic" onchange="updateNext(this, 'worksheet')">
</select>
<script>
    function updateNext(el, nextName) {
        var url_arg = el.value;
        var full_url = "base_url/json_get_wstopics_by_category/" + url_arg;
        var options, txtStrng;
        //grab ajax data
        $.ajax({
            async: false,
            url: full_url,
            type: 'POST',
            dataType: 'json',
            success: function(output_string){
                options= output_string;
            }
        });
        //create the option list
        $.each( options, function() {
            txtStrng += "<option value=\"" + this.option_id.toString() + "\">";
            txtStrng += this.option_name.toString();
            txtStrng += "</option>";
        });
        //clear the option list
        $('#'+nextName).text('');
        //attach the option list
        $(txtStrng).appendTo('#'+nextName);
    }
</script>

Upvotes: 3

Related Questions