Multiple Dropdown Lists Using jQuery Ajax and PHP

In this tutorial we will populate a dropdown list based on the value of another dropdown list. This is commonly used for countries and states.

For example:

Dropdown Example Using jQuery

We will be creating 4 files:

  • dbConfig.php
  • index.php
  • style.css
  • getStates.php

STEP 1

We will start by considering the relationships required for our database.

We will need a table for the countries and a table for the states.

The two tables will have a one-to-many relationship i.e. one country will have many states.

Database Entity Relationship Diagram

Note how the two tables are linked. We have the countryId as a foreign key in the states table.

We can now create the tables. You can download the SQL dump here or create your own tables based on the above relationship diagram.

STEP 2

We can now create a connection script to connect to the database. Your connection details will differ depending on your platform and login credentials. I will be using a MySQL database and PDO connection.

<?php

$db_host = 'localhost';
$db_name = 'yourDatabaseNameHere';
$db_username = 'yourUsernameHere';
$db_password = 'yourPasswordHere'; 

try{
$db = new PDO("mysql:host=$db_host;dbname=$db_name", $db_username, $db_password);
} catch (PDOException $e){
	echo 'Error: Oh dear, we experienced some technical issues!';
}

Save this file as required. I'll name mine dbConfig.php.

STEP 3

Create a file called index.php.

Now we will create the HTML for the dropdowns.  We will start with a basic HTML5 template and connections to Bootstrap css, our own css styles and jQuery:

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>Dropdown list example</title>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <link rel="stylesheet" href="style.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
   </head>
   <body>

   </body>
</html>

STEP 4

Now the structure for the dropdowns. Since we are using Bootstrap I have added some form classes to make things easier to style.

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>Dropdown list example</title>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <link rel="stylesheet" href="style.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
   </head>
   <body>
      <div class="container">
         <form class="form-horizontal">
            <div class="form-group">
               <label for="country" class="col-sm-2 control-label">Country:</label>
               <div class="col-sm-4">
                  <select class="form-control" id="country">
                     <option value="">Select Country</option>
                  </select>
               </div>
            </div>
            <div class="form-group" id="state">
               <label for="state" class="col-sm-2 control-label">State:</label>
               <div class="col-sm-4">               
                  <select class="form-control" id="stateDropdown">
                  </select>
               </div>
            </div>
         </form>
      </div>
   </body>
</html>

STEP 5

We want the states dropdown to be hidden by default and only show when the country has been selected.

We therefore create our style.css page and add the following code:

#state {
   display: none;
}

STEP 6

The country dropdown will need to be populated with the list of countries when the page loads. We can add the required php code and database call at the top of the page:

<?php
   include("dbConfig.php");
   $sql = "SELECT * FROM countries ORDER BY countryName ASC";
   $results = $db->query($sql);
?>

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>Dropdown list example</title>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <link rel="stylesheet" href="style.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
   </head>
   <body>
      <div class="container">
         <form class="form-horizontal">
            <div class="form-group">
               <label for="country" class="col-sm-2 control-label">Country:</label>
               <div class="col-sm-4">
                  <select class="form-control" id="country">
                     <option value="">Select Country</option>
                  </select>
               </div>
            </div>
            <div class="form-group" id="state">
               <label for="state" class="col-sm-2 control-label">State:</label>
               <div class="col-sm-4">               
                  <select class="form-control" id="stateDropdown">
                  </select>
               </div>
            </div>
         </form>
      </div>
   </body>
</html>

STEP 7

We will now loop through the results and create a separate option list element for each country (lines 24 to 28):

<?php
   include("dbConfig.php");
   $sql = "SELECT * FROM countries ORDER BY countryName ASC";
   $countries = $db->query($sql);
?>

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>Dropdown list example</title>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <link rel="stylesheet" href="style.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
   </head>
   <body>
      <div class="container">
         <form class="form-horizontal">
            <div class="form-group">
               <label for="country" class="col-sm-2 control-label">Country:</label>
               <div class="col-sm-4">
                  <select class="form-control" id="country">
                     <option value="">Select Country</option>
                     <?php
                        foreach($countries as $country){
                           echo "<option value='" . $country['id'] . "'>" . $country['countryName'] . "</option>";
                        }
                     ?>
                  </select>
               </div>
            </div>
            <div class="form-group" id="state">
               <label for="state" class="col-sm-2 control-label">State:</label>
               <div class="col-sm-4">               
                  <select class="form-control" id="stateDropdown">
                  </select>
               </div>
            </div>
         </form>
      </div>
   </body>
</html>

STEP 8

When we select a country from the dropdown country list we want the state dropdown list to be updated. Therefore we need to perform an action when the country list has been changed.

We add an onChange attribute which is calling a function called getStates() on line 22.

We pass in this.value which is the id of the selected country.

<?php
   include("dbConfig.php");
   $sql = "SELECT * FROM countries ORDER BY countryName ASC";
   $countries = $db->query($sql);
?>

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>Dropdown list example</title>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <link rel="stylesheet" href="style.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
   </head>
   <body>
      <div class="container">
         <form class="form-horizontal">
            <div class="form-group">
               <label for="country" class="col-sm-2 control-label">Country:</label>
               <div class="col-sm-4">
                  <select class="form-control" id="country" onChange="getStates(this.value)">
                     <option value="">Select Country</option>
                     <?php
                        foreach($countries as $country){
                           echo "<option value='" . $country['id'] . "'>" . $country['countryName'] . "</option>";
                        }
                     ?>
                  </select>
               </div>
            </div>
            <div class="form-group" id="state">
               <label for="state" class="col-sm-2 control-label">State:</label>
               <div class="col-sm-4">               
                  <select class="form-control" id="stateDropdown">
                  </select>
               </div>
            </div>
         </form>
      </div>
   </body>
</html>

STEP 9

We can now write the jQuery function called getStates.

To check that the country dropdown is passing the value of the selected country to the function we can just use a simple alert command. Lines 15 to 19.

<?php
include("dbConfig.php");
$sql = "SELECT * FROM countries ORDER BY countryName ASC";
$countries = $db->query($sql);
?>

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>Dropdown list example</title>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <link rel="stylesheet" href="style.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
      <script>
         function getStates(countryId){
            alert(countryId);
         }  
      </script>
   </head>
   <body>
      <div class="container">
         <form class="form-horizontal">
            <div class="form-group">
               <label for="country" class="col-sm-2 control-label">Country:</label>
               <div class="col-sm-4">
                  <select class="form-control" id="country" onChange="getStates(this.value)">
                     <option value="">Select Country</option>
                     <?php
                     foreach($countries as $country){
                        echo "<option value='" . $country['id'] . "'>" . $country['countryName'] . "</option>";
                     }
                     ?>
                  </select>
               </div>
            </div>
            <div class="form-group" id="state">
               <label for="state" class="col-sm-2 control-label">State:</label>
               <div class="col-sm-4">               
                  <select class="form-control" id="stateDropdown">
                  </select>
               </div>
            </div>
         </form>
      </div>
   </body>
</html>

If everything is working you should have an alert appear when you change the country. The id of the country should appear in the popup.

You should see something like this:

Country Dropdown Popup

STEP 10

We can now start the rest of the jQuery coding.

<?php
include("dbConfig.php");
$sql = "SELECT * FROM countries ORDER BY countryName ASC";
$countries = $db->query($sql);
?>

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8">
      <title>Dropdown list example</title>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <link rel="stylesheet" href="style.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
      <script>
         function getStates(countryId){
            $("#state").show();
            $("#stateDropdown").html('<option>Loading...</option>');
            $.ajax({
               method: "POST",
               url: "getStates.php",
               dataType: "html",
               data: {country: countryId}
            })
               .done(function(data){
               $("#stateDropdown").html(data);
            });
         }  
      </script>
   </head>
   <body>
      <div class="container">
         <form class="form-horizontal">
            <div class="form-group">
               <label for="country" class="col-sm-2 control-label">Country:</label>
               <div class="col-sm-4">
                  <select class="form-control" id="country" onChange="getStates(this.value)">
                     <option value="">Select Country</option>
                     <?php
                     foreach($countries as $country){
                        echo "<option value='" . $country['id'] . "'>" . $country['countryName'] . "</option>";
                     }
                     ?>
                  </select>
               </div>
            </div>
            <div class="form-group" id="state">
               <label for="state" class="col-sm-2 control-label">State:</label>
               <div class="col-sm-4">               
                  <select class="form-control" id="stateDropdown">
                  </select>
               </div>
            </div>
         </form>
      </div>
   </body>
</html>

Line 16: we create a function and accept the argument countryId. This is the this.value we passed into the function on line 37.

Line 17: by default the states select list is hidden so we now show it

Line 18: we present a 'Loading...' message while the ajax call is being processed below

Line 19: this is an ajax request

Line 20: we are using a POST method

Line 21: the URL of the page we are sending the data to (we have yet to create this page)

Line 22: the dataType that we are expecting back from our request

Line 23: the data that we are posting to the page on line 19. We are sending the country id.

Line 25: upon completion of the processing we should receive some data back. 

Line 26: we update the state dropdown

STEP 11

All we need to do now is create the getStates.php page:

<?php
if(!empty($_POST['country'])){
   require("dbConfig.php");
   $countryId = $_POST['country'];
   $sql = "SELECT * FROM states WHERE countryId = :countryId ORDER BY stateName";
   $states = $db->prepare($sql);
   $states->execute(array(
      ':countryId'   => $countryId
   ));
   echo "<option>Select State...</option>";
   foreach($states as $state){
      echo "<option value='" . $state['id'] . "'>" . $state['stateName'] . "</option>";
   }
}

Line 2: we check if we actually received a value for the country

Line 3: we require our database connection

Line 4: we assign the posted country id value to the variable $countryId. Note that we have NOT considered any sanitization of values which you MUST do on a live server!

Lines 5 to 8: We search for all states belonging to the country. I am using prepared statements here.

Line 10: echo out a default ' Select State...' message. This will be the first option in the new select list

Lines 11 to 13: we loop through the results and build up a list for the state dropdown.

Want to Learn More?

Become a member and get access to the member only area of this site here.

Comments

Your email address will not be published.

User Avatar

A comprehensive tutorial. Thanks very much!

by JD, 06-Jan-2016

User Avatar

is it possible when you click 'state' a company details is displayed from "company" table

by Gautam Bose, 20-Jul-2016

User Avatar

@Gautam Yes, it is possible to do this. You would just need to add another level to the drop downs. The code would be similar to getStates.php

by Patrick Morrow, 22-Jul-2016

User Avatar

can you please show me your tables

by Mangen, 08-Apr-2017

User Avatar

@Mangen - if you look at STEP 1 you will see the table structure. They are very basic tables. If you look at the end of the step you will also see a link to a SQL dump of the tables which you could then upload to your own server.

by Patrick Morrow, 10-Apr-2017

User Avatar

sir can you share the connection part using object oriented or procedural instead of pdo

by mangen, 10-Apr-2017

User Avatar

@mangen - I highly recommend that you use a PDO connection. However, the MySQLi connection would look something like this:

$db_host = "localhost";
$db_username = "username";
$db_password = "password";
$db = mysqli_connect($db_host, $db_username, $db_password);

You can obviously then test for a successful connection etc.

by Patrick Morrow, 13-Apr-2017

User Avatar

thank you sir, your code is very helpful

by Mangen, 13-Apr-2017

User Avatar

sir i'm new to php would you show me how proper validation is done both from the front and back end

by mangen, 15-Apr-2017

User Avatar

@Mangen what do you mean by proper validation? Do you mean how to validate an input e.g. to check if an email address is actually an email address OR do you mean to validate for security?

by Patrick Morrow, 16-Apr-2017

PHP for Beginners

Enrol in the full course here

PHP, MySQL and PDO

Coming soon, a full course on using PHP, MySQL and PDO. Be notified as soon as the course goes live.