Dynamic Dependent Select Box using CodeIgniter, AJAX & jQuery

Hi! In this tutorial let's see how to create dynamic dependent select box using codeigniter, ajax and jquery. If you wonder what dynamic dependent select box is, then they are the parent-child dropdowns in which the contents of the second dropdown solely depends on the option selected on the first dropdown. And the best example for such dynamic dependent select box is the country state city drop down list and here I'm going to show you how to create them in codeigniter and jquery ajax.

And creating dynamic dependent select box in php is straight-forward but implementing them in a MVC Framework like CodeIgniter gets little tricky. But don't worry; I'll walk you through the process step-by-step so that you can understand it easily.

Create Dynamic Dependent Select Box in Codeigniter and ajax:

Here the idea is to create three drop downs in an html form for country, state and city resp. and populate country names in the country dropdown from database on load. After that selecting a specific country should load all the state names related to the country and choosing a particular state should load the city names available under the state.

Since refreshing the form every time the user picks a country or state would be awkward. So we are going to use jQuery AJAX for updating the select box options as many times as required in a discreet way.

Step 1) Create Database

First create the database required for this example. I'm using MySQL DB here and you'll need three tables 'country', 'state' and 'city' which are related to each other like below.

codeigniter-country-state-city-dropdown-list-db-structure

Here's the sql command to create the above tables. And I have also included some sample records to run the demo.

CREATE TABLE IF NOT EXISTS `country` (
  `country_id` int(9) NOT NULL AUTO_INCREMENT,
  `country_name` varchar(30) NOT NULL,
  PRIMARY KEY (`country_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6;

INSERT INTO `country` (`country_id`, `country_name`) VALUES
(1, 'Canada'), (2, 'China'), (3, 'India'), (4, 'United Kingdom'), (5, 'United States');

CREATE TABLE IF NOT EXISTS `state` (
  `state_id` int(9) NOT NULL AUTO_INCREMENT,
  `country_id` int(9) NOT NULL,
  `state_name` varchar(30) NOT NULL,
  PRIMARY KEY (`state_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10;

INSERT INTO `state` (`state_id`, `country_id`, `state_name`) VALUES
(1, 3, 'Bihar'), (2, 3, 'Delhi'), (3, 3, 'Maharashtra'), (4, 3, 'Tamil Nadu'), (5, 3, 'West Bengal'), (6, 1, 'Newfoundland'), (7, 2, 'Shanghai'), (8, 4, 'England'), (9, 5, 'Florida');

CREATE TABLE IF NOT EXISTS `city` (
  `city_id` int(9) NOT NULL AUTO_INCREMENT,
  `state_id` int(9) NOT NULL,
  `city_name` varchar(30) NOT NULL,
  PRIMARY KEY (`city_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10;

INSERT INTO `city` (`city_id`, `state_id`, `city_name`) VALUES
(1, 3, 'Kalyan'), (2, 3, 'Mumbai'), (3, 3, 'Nagpur'), (4, 3, 'Pune'), (5, 3, 'Thane'), (6, 6, 'St Johns'), (7, 7, 'Shanghai'), (8, 8, 'London'), (9, 9, 'Miami');

Step 2) Create Model ('dropdown_demo_model.php')

Then create a model file with functions to fetch country, state and city names from mysql database. You have to place this file inside 'application/models' folder in CI.

<?php
class dropdown_demo_model extends CI_Model
{
    function __construct()
    {
        parent::__construct();
    }
    
    function get_country()
    {
        $result = $this->db->get('country')->result();;
        $id = array('0');
        $name = array('Select Country');
        for ($i = 0; $i < count($result); $i++)
        {
            array_push($id, $result[$i]->country_id);
            array_push($name, $result[$i]->country_name);
        }
        return array_combine($id, $name);
    }
    
    function get_state($cid=NULL)
    {
        $result = $this->db->where('country_id', $cid)->get('state')->result();
        $id = array('0');
        $name = array('Select State');
        for ($i=0; $i<count($result); $i++)
        {
            array_push($id, $result[$i]->state_id);
            array_push($name, $result[$i]->state_name);
        }
        return array_combine($id, $name);
    }

    function get_city($sid=NULL)
    {
        $result = $this->db->where('state_id', $sid)->get('city')->result();
        $id = array('0');
        $name = array('Select City');
        for ($i=0; $i<count($result); $i++)
        {
            array_push($id, $result[$i]->city_id);
            array_push($name, $result[$i]->city_name);
        }
        return array_combine($id, $name);
    }
}
?>

Step 3) Create Controller ('dropdown_demo.php')

Next create the main controller for this demo inside 'application/controllers' folder. Here's the code for the controller file.

<?php
class dropdown_demo extends CI_Controller
{
    function __construct()
    {
        parent::__construct();
        $this->load->helper(array('form', 'url'));
        $this->load->database();
        $this->load->model('dropdown_demo_model');
    }
    
    function index()
    {
        $data['country'] = $this->dropdown_demo_model->get_country();
        $data['state'] = $this->dropdown_demo_model->get_state();
        $data['city'] = $this->dropdown_demo_model->get_city();
        $this->load->view('dropdown_demo_view', $data);
    }
    
    function populate_state()
    {
        $id = $this->input->post('id');
        echo(json_encode($this->dropdown_demo_model->get_state($id)));
    }

    function populate_city()
    {
        $id = $this->input->post('id');
        echo(json_encode($this->dropdown_demo_model->get_city($id)));
    }
}
?>

Along with the index() function we have two more functions in the controller namely, populate_state() and populate_city() to which we'll send the ajax request. These methods in turn communicate with the model functions we have created in the previous step and return the state and city details as JSON to the ajax call.

Step 4) Create View ('dropdown_demo_view.php')

This is the user interface for our example. The file creates a form with three select boxes. Place this file inside 'application/views' folder.

<!DOCTYPE html>
<html>
<head>
    <title>CodeIgniter AJAX Dynamic Dependent Dropdowns Example</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="<?php echo base_url("assets/bootstrap/css/bootstrap.css"); ?>" rel="stylesheet" type="text/css" />
    </style>
</head>
<body>

<div class="container" style="margin-top: 30px;">
<div class="col-sm-6 col-sm-offset-3">
    <div class="panel panel-info">
        <div class="panel-heading"><h3 class="panel-title">Dynamic Country, State & City Dropdown List Demo</h3></div>
        <div class="panel-body">
            <?php $attributes = array("name" => "form1");
            echo form_open("dropdown_demo/index", $attributes);?>
            <div class="form-group">
                <?php $attributes = 'id="country" class="form-control"';
                echo form_dropdown('country', $country, set_value('country'), $attributes); ?>
            </div>
            <div class="form-group">
                <?php $attributes = 'id="state" class="form-control"';
                echo form_dropdown('state', $state, set_value('state'), $attributes); ?>
            </div>
            <div class="form-group">
                <?php $attributes = 'id="city" class="form-control"';
                echo form_dropdown('city', $city, set_value('city'), $attributes); ?>
            </div>
            <div class="form-group">
                <button name="submit" type="submit" class="btn btn-info btn-block">Submit</button>
            </div>
            <?php echo form_close(); ?>
        </div>
    </div>
</div>
</div>
<script src="<?php echo base_url("assets/js/jquery-1.10.2.js"); ?>" type="text/javascript"></script>
<script type="text/javascript">
$('#country').change(function(){
    var country_id = $(this).val();
    $("#state > option").remove();
    $.ajax({
        type: "POST",
        url: "<?php echo site_url('dropdown_demo/populate_state'); ?>",
        data: {id: country_id},
        dataType: 'json',
        success:function(data){
            $.each(data,function(k, v){
                var opt = $('<option />');
                opt.val(k);
                opt.text(v);
                $('#state').append(opt);
            });
            $('#city').html('<option value="0">Select City</option>');
            //$('#state').append('<option value="' + id + '">' + name + '</option>');
        }
    });
});

$('#state').change(function(){
    var state_id = $(this).val();
    $("#city > option").remove();
    $.ajax({
        type: "POST",
        url: "<?php echo site_url('dropdown_demo/populate_city'); ?>",
        data: {id: state_id},
        dataType: 'json',
        success:function(data){
            $.each(data,function(k, v){
                var opt = $('<option />');
                opt.val(k);
                opt.text(v);
                $('#city').append(opt);
            });
        }
    });
});
</script>
</body>
</html>

In the view we have two jquery functions, one to load state details and another for city in the respective select boxes via ajax call. And jquery's ajax() function has been used for this and will be triggered when user choose country or state from the drop downs. Also the function sends and receives data in json format and including the option dataType: 'json' ensures it interprets the data properly.

That's it! We have everything in place. Just run the controller and a form will be shown with three dropdowns with country names alone loaded from the database.

dynamic-dependent-select-box-codeigniter-ajax-jquery

Selecting a country name will load 'State' combo with options and selecting a state name will load 'City' combo with available city names.

Read Also: CodeIgniter Login and Registration System with Source Code

Don't Miss: Code Igniter Pagination with Search Filter using Bootstrap

That explains about creating dynamic dependent select box using codeigniter and ajax. Did you find this post useful? Please let us know through comments. And your queries too :)

1 comment: