How to create Dynamic Dependent Dropdown in CodeIgniter using jQuery and Ajax
The dynamic dependent select box auto-populates dependent data in the dropdown based on the selection. Dynamic dependent dropdown commonly used in country-state-city and category-subcategory selection. Load dynamic data in select boxes without page refresh makes the web application user-friendly. Using jQuery and Ajax, you can easily implement dynamic dependent dropdown functionality without page refresh.
In this tutorial, we will show you how to create the dynamic dependent dropdown in CodeIgniter using jQuery and Ajax. To demonstrate the dependent dropdown functionality, we will implement relational dropdown of country state city in CodeIgniter. The state will be related to country and city will be related to the state. Based on the selection of country & state, dependent state & city will be fetched from the database without reloading the page using jQuery and Ajax in CodeIgniter.
The example code initially displays all countries in the country dropdown. When a country is selected, the respective states will be fetched from the MySQL database and appear in the state dropdown. Alike, when a state is selected, the respective cities will be fetched from the MySQL database and appear in the city dropdown.
Create Database Tables
To store the data of country, state, and city, three tables need to be created in the database. Also, there would be a relationship between countries, states, and cities table. The states table has a relation with countries table and cities table has a relation with states table.
Countries Table:
The following SQL creates a countries
table in the MySQL database.
CREATE TABLE `countries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 NOT NULL,
`status` enum('1','0') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1' COMMENT '0:Blocked, 1:Active',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
States Table:
The following SQL creates a states
table in the MySQL database.
CREATE TABLE `states` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`country_id` int(11) NOT NULL,
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`status` enum('1','0') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1' COMMENT '0:Blocked, 1:Active',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Cities Table:
The following SQL creates a cities
table in the MySQL database.
CREATE TABLE `cities` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`state_id` int(11) NOT NULL,
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`status` enum('1','0') COLLATE utf8_unicode_ci NOT NULL DEFAULT '1' COMMENT '0:Blocked, 1:Active',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Controller (Dropdowns.php)
The Dropdowns controller contains 4 functions, __construct(), index(), getStates(), and getCities().
__construct()
– Loads the Dropdown model.index()
– All the country data is retrieved from the database using Dropdown model and pass data to the view.getStates()
– Bases on the country ID the state data is retrieved from the database using Dropdown model and render data in JSON format.getCities()
– Bases on the state ID the city data is retrieved from the database using Dropdown model and render data in JSON format.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Dropdowns extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->model('dropdown');
}
public function index(){
$data['countries'] = $this->dropdown->getCountryRows();
$this->load->view('dropdowns/index', $data);
}
public function getStates(){
$states = array();
$country_id = $this->input->post('country_id');
if($country_id){
$con['conditions'] = array('country_id'=>$country_id);
$states = $this->dropdown->getStateRows($con);
}
echo json_encode($states);
}
public function getCities(){
$cities = array();
$state_id = $this->input->post('state_id');
if($state_id){
$con['conditions'] = array('state_id'=>$state_id);
$cities = $this->dropdown->getCityRows($con);
}
echo json_encode($cities);
}
}
Model (Dropdown.php)
The Dropdown model contains 4 functions, __construct(), getCountryRows(), getStateRows(), and getCityRows().
__construct()
– Defines database tables for country, state, and city.getCountryRows()
– Fetch country data from the database and return the rows based on the conditions provided by the $params array.getStateRows()
– Fetch state data from the database and return the rows based on the conditions provided by the $params array.getCityRows()
– Fetch city data from the database and return the rows based on the conditions provided by the $params array.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Dropdown extends CI_Model{
function __construct() {
$this->countryTbl = 'countries';
$this->stateTbl = 'states';
$this->cityTbl = ' cities';
}
/*
* Get country rows from the countries table
*/
function getCountryRows($params = array()){
$this->db->select('c.id, c.name');
$this->db->from($this->countryTbl.' as c');
//fetch data by conditions
if(array_key_exists("conditions",$params)){
foreach ($params['conditions'] as $key => $value) {
if(strpos($key,'.') !== false){
$this->db->where($key,$value);
}else{
$this->db->where('c.'.$key,$value);
}
}
}
$this->db->where('c.status','1');
$query = $this->db->get();
$result = ($query->num_rows() > 0)?$query->result_array():FALSE;
//return fetched data
return $result;
}
/*
* Get state rows from the countries table
*/
function getStateRows($params = array()){
$this->db->select('s.id, s.name');
$this->db->from($this->stateTbl.' as s');
//fetch data by conditions
if(array_key_exists("conditions",$params)){
foreach ($params['conditions'] as $key => $value) {
if(strpos($key,'.') !== false){
$this->db->where($key,$value);
}else{
$this->db->where('s.'.$key,$value);
}
}
}
$query = $this->db->get();
$result = ($query->num_rows() > 0)?$query->result_array():FALSE;
//return fetched data
return $result;
}
/*
* Get city rows from the countries table
*/
function getCityRows($params = array()){
$this->db->select('c.id, c.name');
$this->db->from($this->cityTbl.' as c');
//fetch data by conditions
if(array_key_exists("conditions",$params)){
foreach ($params['conditions'] as $key => $value) {
if(strpos($key,'.') !== false){
$this->db->where($key,$value);
}else{
$this->db->where('c.'.$key,$value);
}
}
}
$query = $this->db->get();
$result = ($query->num_rows() > 0)?$query->result_array():FALSE;
//return fetched data
return $result;
}
}
View (dropdowns/)
The view folder (dropdowns/) contains the index.php
file.
index.php
In index.php
file, the country, state, and city dropdown are displayed.
jQuery & Ajax
The dynamic dependent select boxes functionality uses jquery, include the jQuery library.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
The following jQuery is used to initialize Ajax request and get dynamic data from Dropdowns controller.
- On changing the country dropdown, selected country ID is taken and post this ID to
getStates()
method of Dropdowns controller. On success, the returned JSON data is parsed and options are appended to the state dropdown. - On changing the state dropdown, selected state ID is taken and post this ID to
getCities()
method of Dropdowns controller. On success, the returned JSON data is parsed and options are appended to the city dropdown.
<script type="text/javascript">
$(document).ready(function(){
/* Populate data to state dropdown */
$('#country').on('change',function(){
var countryID = $(this).val();
if(countryID){
$.ajax({
type:'POST',
url:'<?php echo base_url('dropdowns/getStates'); ?>',
data:'country_id='+countryID,
success:function(data){
$('#state').html('<option value="">Select State</option>');
var dataObj = jQuery.parseJSON(data);
if(dataObj){
$(dataObj).each(function(){
var option = $('<option />');
option.attr('value', this.id).text(this.name);
$('#state').append(option);
});
}else{
$('#state').html('<option value="">State not available</option>');
}
}
});
}else{
$('#state').html('<option value="">Select country first</option>');
$('#city').html('<option value="">Select state first</option>');
}
});
/* Populate data to city dropdown */
$('#state').on('change',function(){
var stateID = $(this).val();
if(stateID){
$.ajax({
type:'POST',
url:'<?php echo base_url('dropdowns/getCities'); ?>',
data:'state_id='+stateID,
success:function(data){
$('#city').html('<option value="">Select City</option>');
var dataObj = jQuery.parseJSON(data);
if(dataObj){
$(dataObj).each(function(){
var option = $('<option />');
option.attr('value', this.id).text(this.name);
$('#city').append(option);
});
}else{
$('#city').html('<option value="">City not available</option>');
}
}
});
}else{
$('#city').html('<option value="">Select state first</option>');
}
});
});
</script>
Dynamic Dependent Dropdown
Initially, all the countries are listed in the country dropdown. Once a country is chosen, the states which belong to the selected country will be populated in the state dropdown. Alike, once a state is chosen, the cities which belong to the selected state will be populated in the city dropdown.
<!-- Country dropdown -->
<select id="country">
<option value="">Select Country</option>
<?php
if(!empty($countries)){
foreach($countries as $row){
echo '<option value="'.$row['id'].'">'.$row['name'].'</option>';
}
}else{
echo '<option value="">Country not available</option>';
}
?>
</select>
<!-- State dropdown -->
<select id="state">
<option value="">Select country first</option>
</select>
<!-- City dropdown -->
<select id="city">
<option value="">Select state first</option>
</select>
Conclusion
Here we have shown how to implement dynamic dependent dropdown in CodeIgniter for the country, state, and city. Using this example, you can easily build relational dropdown for any types of dynamic data. Also, you can extend the dynamic dependent select boxes functionality as per the requirement in CodeIgniter application.