Dependent Dropdown Demo dependent-dropdown   Tips

Thankful to Krajee!
to get more out of us.

NOTE: The plugins on this site, strive to use a lot of CSS3 and HTML5 features in addition to JQuery. Hence, one may find either CSS3, HTML5 or a mix of both to achieve a plugin's requirements in many implementations.

A multi level dependent dropdown JQuery plugin that allows nested dependencies. The plugin allows you to convert normal select inputs, whose options are derived based on value selected in another input/or a group of inputs. It works both with normal select options and select with optgroups as well.

Tip

Not seeing the updated content on this page! Hard refresh your browser to clean cache for this page (e.g. SHIFT-F5 on Windows Chrome).

A 3-level nested dependency example. The dependent dropdowns generate will generate a linear list of options.

Note: You must generate a JSON encoded output from server with an array format like below:

$json_output = {
    output: [
        {id: 'id-1', name: 'name-1'],
        {id: 'id-2', name: 'name-2'],
        {id: 'id-3', name: 'name-3']
    ],
    selected: 'default_id'
};
<!-- HTML Markup (Parent) -->
<select id="cat-id">
    <option id="">Select ...</option>
    <!-- other options -->
</select>

<!-- HTML Markup (Child # 1) -->
<select id="subcat-id">
    <option id="">Select ...</option>
    <!-- other options -->
</select>

<!-- HTML Markup (Child # 2) -->
<select id="prod-id">
    <option id="">Select ...</option>
    <!-- other options -->
</select>

<!-- Javascript call on document ready -->
<script>
    // Child # 1
    $("#subcat-id").depdrop({
        url: '/server/getSubcat.php',
        depends: ['cat-id']
    });

    // Child # 2
    $("#prod-id").depdrop({
        url: '/server/getProd.php',
        depends: ['cat-id', 'subcat-id']
    });
</script>

<!-- PHP example: /server/getSubCat.php -->
<?php
    $out = [];
    if (isset($_POST['depdrop_parents'])) {
        $parents = $_POST['depdrop_parents'];
        if ($parents != null) {
            $cat_id = $parents[0];
            $out = self::getSubCatList($cat_id); 
            // the getSubCatList function will query the database based on the
            // cat_id and return an array like below:
            // [
            //    ['id'=>'<sub-cat-id-1>', 'name'=>'<sub-cat-name1>'],
            //    ['id'=>'<sub-cat-id-2>', 'name'=>'<sub-cat-name2>']
            // ]
            echo json_encode(['output'=>$out, 'selected'=>'']);
            return;
        }
    }
    echo json_encode(['output'=>'', 'selected'=>'']);
?>

<!-- PHP example: /server/getProd.php -->
<?php
    $out = [];
    if (isset($_POST['depdrop_parents'])) {
        $ids = $_POST['depdrop_parents'];
        $cat_id = empty($ids[0]) ? null : $ids[0];
        $subcat_id = empty($ids[1]) ? null : $ids[1];
        if ($cat_id != null) {
           $data = self::getProdList($cat_id, $subcat_id);
            /**
             * the getProdList function will query the database based on the
             * cat_id and sub_cat_id and return an array like below:
             *  [
             *      'out'=>[
             *          ['id'=>'<prod-id-1>', 'name'=>'<prod-name1>'],
             *          ['id'=>'<prod-id-2>', 'name'=>'<prod-name2>']
             *       ],
             *       'selected'=>'<prod-id-1>'
             *  ]
             */
           
           echo json_encode(['output'=>$data['out'], 'selected'=>$data['selected']]);
           return;
        }
    }
    echo json_encode(['output'=>'', 'selected'=>'']);
?>

A 2-level dependency with optgroups generated in dependent dropdown list. The dependent dropdowns will generate a list of options grouped by optgroup. In addition, this also includes additional params where additional form input identifiers are passed

.

Note: You must generate a JSON encoded output from server with an array format like below:

$json_output = {
    output: {
        group-1: {
            {id: 'id-1', name: 'name-1'],
            {id: 'id-2', name: 'name-2'],
            {id: 'id-3', name: 'name-3']
        },
        group-2: {
            {id: 'id-4', name: 'name-4'],
            {id: 'id-5', name: 'name-5'],
            {id: 'id-6', name: 'name-6']
        },
    },
    selected: 'default_id'
};
<!-- HTML Markup (Parent) -->
<select id="cat-id">
    <option id="">Select ...</option>
    <!-- other options -->
</select>

<!-- HTML Markup (Child # 1) -->
<select id="subcat-id">
    <option id="">Select ...</option>
    <!-- other options -->
</select>

<!-- HTML Markup (Additional Inputs) -->
<input type="hidden" id="hidden-1" value="input-val-1">
<input type="hidden" id="hidden-2" value="input-val-2">

<!-- Javascript call on document ready -->
<script>
    // Child # 1
    $("#subcat-id").depdrop({
        url: '/server/getSubcat',
        depends: ['cat-id'], /* dependent parent */
        params: ['hidden-1', 'hidden-2'] /* additional input as parameters to ajax */
    });
</script>

<!-- PHP example: /server/getSubCat -->
<?php
public function getSubcat() {
    $out = [];
    if (isset($_POST['depdrop_parents'])) {
        $parents = $_POST['depdrop_parents'];
        if ($parents != null) {
            $cat_id = $parents[0];
            $param1 = null;
            $param2 = null;
            if (!empty($_POST['depdrop_params'])) {
                $params = $_POST['depdrop_params'];
                $param1 = $params[0]; // get the value of hidden-1
                $param2 = $params[1]; // get the value of hidden-2
            }
            $out = self::getSubCatList1($cat_id, $param1, $param2); 
            // the getSubCatList1 function will query the database based on the
            // cat_id, param1, and param2 and return an array like below:
            // [
            //    'group1'=>[
            //        ['id'=>'<sub-cat-id-1>', 'name'=>'<sub-cat-name1>'],
            //        ['id'=>'<sub-cat-id-2>', 'name'=>'<sub-cat-name2>']
            //    ],
            //    'group2'=>[
            //        ['id'=>'<sub-cat-id-3>', 'name'=>'<sub-cat-name3>'], 
            //        ['id'=>'<sub-cat-id-4>', 'name'=>'<sub-cat-name4>']
            //    ]            
            // ]
            
            
            $selected = self::getDefaultSubCat($cat_id);
            // the getDefaultSubCat function will query the database
            // and return the default sub cat for the cat_id
            
            echo json_encode(['output'=>$out, 'selected'=>$selected]);
            return;
        }
    }
    echo json_encode(['output'=>'', 'selected'=>'']);
}
?>

Advanced four level dependency. Check how the initDepends and initialize properties are used for the last child to trigger the ajax requests correctly on initialization. Click here to view the same demo modified for usage with Select2 plugin and preselected values populated from your server (using Yii 2 PHP framework).

<!-- HTML Markup (Parent) -->
<select id="account-lev-0">
    <option id="">Select ...</option>
    <!-- other options -->
</select>

<!-- HTML Markup (Child # 1) -->
<select id="account-lev-1">
    <option id="6">Bank</option>
    <!-- other options -->
</select>

<!-- HTML Markup (Child # 2) -->
<select id="account-lev-2">
    <option id="9">Savings</option>
    <!-- other options -->
</select>

<!-- HTML Markup (Child # 3 - LAST CHILD) -->
<select id="account-lev-3">
    <option id="12">Savings A/C 2</option>
    <!-- other options -->
</select>

<!-- Javascript call on document ready -->
<script>
// Child # 1
$('#account-lev1').depdrop({
    depends: ['account-lev0'],
    url: 'http:///localhost/account/child-account',
    loadingText: 'Loading child level 1 ...'
});

// Child # 2 
$('#account-lev2').depdrop({
    depends: ['account-lev1'],
    url: 'http:///localhost/account/child-account',
    loadingText: 'Loading child level 2 ...'
});

// Child # 3 - LAST CHILD
$('#account-lev3').depdrop({
    depends: ['account-lev2'],
    initialize: true,
    initDepends: ['account-lev0'],
    url: 'http:///localhost/account/child-account',
    loadingText: 'Loading child level 3 ...'
});
</script>
?>

Ability to selectively format each dropdown option HTML attributes via the AJAX response sent. This is done by sending an additional data options as an object (associative array) of HTML attribute keys and values that will be applied to each dropdown option. For example, on selecting 'Electronics' as category the following data will be returned via ajax. Note how you can selectively disable 'Cameras' and 'Televisions' and how you can style each option.

{id: 1, name: 'Mobile Phones', options: {style: 'color:green'}}, 
{id: 2, name: 'Tablets', options: {style: 'color:blue'}}, 
{id: 3, name: 'Computers & Accessories', options: {style: 'color:red'}}, 
{id: 4, name: 'Cameras', options: {disabled: true, style: 'color:silver'}},
{id: 5, name: 'Televisons', options: {disabled: true, style: 'color:silver'}}
<!-- HTML Markup (Parent) -->
<select id="cat2-id">
    <option id="">Select ...</option>
    <!-- other options -->
</select>

<!-- HTML Markup (Child # 1) -->
<select id="subcat2-id">
    <option id="">Select ...</option>
    <!-- other options -->
</select>

<!-- Javascript call on document ready -->
<script>
    // Child # 1
    $("#subcat2-id").depdrop({
        url: '/server/getSubcat',
        depends: ['cat2-id'], /* dependent parent */
    });
</script>

<!-- PHP example: /server/getSubCat -->
<?php
public function getSubcat() {
    $out = [];
    if (isset($_POST['depdrop_parents'])) {
        $parents = $_POST['depdrop_parents'];
        if ($parents != null) {
            $cat_id = $parents[0];
            $param1 = null;
            $param2 = null;
            if (!empty($_POST['depdrop_params'])) {
                $params = $_POST['depdrop_params'];
                $param1 = $params[0]; // get the value of hidden-1
                $param2 = $params[1]; // get the value of hidden-2
            }
            $out = self::getSubCatList2($cat_id, $param1, $param2); 
            // the getSubCatList2 function will query the database based on the
            // cat_id, param1, and param2 and return an array like below:
            /**
             [
                ['id'=>1, 'name'=>'Mobile Phones', 'options'=>['style'=>'color:green']], 
                ['id'=>2, 'name'=>'Tablets', 'options'=>['style'=>'color:blue']], 
                ['id'=>3, 'name'=>'Computers & Accessories', 'options'=>['style'=>'color:red']], 
                ['id'=>4, 'name'=>'Cameras', 'options'=>['disabled'=>true, 'style'=>'color:silver']],
                ['id'=>5, 'name'=>'Televisons', 'options'=>['disabled'=>true, 'style'=>'color:silver']]
             ]
            **/
            
            $selected = self::getDefaultSubCat($cat_id);
            // the getDefaultSubCat function will query the database
            // and return the default sub cat for the cat_id
            echo json_encode(['output'=>$out, 'selected'=>$selected]);
            return;
        }
    }
    echo json_encode(['output'=>'', 'selected'=>'']);
}
?>