skip to Main Content

Im trying to use PHP+MySQL+Ajax to dynamically load options in a select but I don’t know how to do it

Currently I have 2 select inside 2 forms and i need to send form 2 times, so the page will load 2 times.
I want to improve my code using ajax, so my page will load faster and will be easier to use.

  • Select 1 have a list of countries
  • Select 2 have a list of cities from the country selected in select 1

After you select the city, specific info from that city will be displayed in screen.

Form 1

<?php include_once "conn.php"; ?>
<!-- Form 1 -->
<form action="" method="post">
    <select required id="Countries" name="Countries">
        <?php
        $sql = "SELECT distinct Country FROM cities order by 1 asc";
        $result = $conn->query($sql);
        if ($result->num_rows > 0) {
            while ($row = $result->fetch_assoc()) {
                echo '<option value="' . $row["Country"] . '">' . $row["Country"] . '</option>';
            }
        } else {
            echo "0 results";
        }
        ?>
    </select>
    <input type="submit" id="LoadCities" name="LoadCities" value="Load Cities" />
</form>

Form 2

<!-- Store select 1 value in variable -->
<?php
if (isset($_POST['Countries'])) {
    $Countries = $_POST['Countries'];
}
?>

<!-- Form 1 -->
<form action="" method="post">
    <select required id="Cities" name="Cities">
        <?php
        $sql = 'SELECT  * FROM cities  where country="' . $Countries . '"';
        $result = $conn->query($sql);
        if ($result->num_rows > 0) {
            while ($row = $result->fetch_assoc()) {
                echo '<option value="' . $row["City"] . '">' . $row["City"] . '</option>';
            }
        } else {
            echo "0 results";
        }
        ?>
    </select>
    <input type="submit" id="ShowInfo" name="ShowInfo" value="ShowInfo" />
</form>

Display City info on screen:

<!-- Store select 2 value in variable and print selected options in screen-->
<?php
if (isset($_POST['Cities'])) {
    $City = $_POST['Cities'];
    $sql = 'SELECT * FROM cities where City="' . $City . '"';
    $result = $conn->query($sql);
    if ($result->num_rows > 0) {
        while ($row = $result->fetch_assoc()) {
            echo '<p>Country: ' . $row["Country"] . '</p>';
            echo '<p>City: ' . $row["City"] . '</p>';
        }
    } else {
        echo "0 results";
    }
}
?>

2

Answers


  1. For Ajax to work without you refreshing or submitting the forms. You need to create separate endpoints for your ajax calls. You should have 3 files:

    • index.php – Display the country form, city form and city info altogether here. The country data will load by default and other data will be linked to their respective Ajax calls.
    • fetchCities.php – Use this endpoint to fetch the dropdown values of cities based on the selected country value.
    • cityInfo.php – Use this endpoint to fetch the city information based on the selected city value.

    Note: You can combine fetchCities.php and cityInfo.php into a single file if you include a second parameter in your Ajax call, for eg: action: "fetchCity"

    Here’s what you can do:

    index.php

    <?php include_once "conn.php"; ?>
    <form action="" method="post">
        <select required id="Countries" name="Countries">
            <?php
            $sql = "SELECT distinct Country FROM cities order by 1 asc";
            $result = $conn->query($sql);
            if ($result->num_rows > 0) {
                while ($row = $result->fetch_assoc()) {
                    echo '<option value="' . $row["Country"] . '">' . $row["Country"] . '</option>';
                }
            } else {
                echo "0 results";
            }
            ?>
        </select>
        <input type="submit" id="LoadCities" name="LoadCities" value="Load Cities" />
    </form>
    
    //empty city dropdown. You may remove the form element from it if not required.
    <form action="" method="post">
        <select required id="Cities" name="Cities">
            <option disabled selected>Select a country first</option>
        </select>
    </form>
    
    //empty city info
    <div id="cityInfo"></div>
    
    <script>
        //whenever someone selects a country, hit the Ajax to fetch cities.
        $(document).on('change', '#Countries', function() {
            const selectedCountry = $(this).val();
            //run your cities Ajax here and pass selectedCountry value
            $.ajax({
                    method: "POST",
                    url: "fetchCities.php",
                    data: {
                        Countries: selectedCountry
                    }
                })
                .done(function(response) {
                    //replace City dropdown with values returned from fetchCities.php file.
                    $('#Cities').html(response);
                });
        });
    
        //whenever someone selects a city, hit the Ajax to fetch city information.
        $(document).on('change', '#Cities', function() {
            const selectedCity = $(this).val();
            //run your cities Ajax here and pass selectedCity value
            $.ajax({
                    method: "POST",
                    url: "cityInfo.php",
                    data: {
                        Cities: selectedCity
                    }
                })
                .done(function(response) {
                    $('#cityInfo').html(response);
                });
        });
    </script>
    

    fetchCities.php

    <?php include_once "conn.php";
    
    if (isset($_POST['Countries'])) {
        $Countries = $_POST['Countries'];
        $sql = 'SELECT  * FROM cities  where country="' . $Countries . '"';
        $result = $conn->query($sql);
        
        $returnHtml = '';
        if ($result->num_rows > 0) {
            while ($row = $result->fetch_assoc()) {
                $returnHtml .= '<option value="' . $row["City"] . '">' . $row["City"] . '</option>';
            }
        } else {
            $returnHtml = '<option disabled selected>0 results</option>';
        }
        echo $returnHtml;
    }else{
        echo '<option disabled selected>0 results</option>';
    }
    ?>
    

    cityInfo.php

    <?php
    include_once "conn.php";
    
    if (isset($_POST['Cities'])) {
        $City = $_POST['Cities'];
        $sql = 'SELECT * FROM cities where City="' . $City . '"';
        $result = $conn->query($sql);
    
        $returnHtml = '';
        if ($result->num_rows > 0) {
            while ($row = $result->fetch_assoc()) {
                $returnHtml .= '<p>Country: ' . $row["Country"] . '</p>';
                $returnHtml .= '<p>City: ' . $row["City"] . '</p>';
            }
            echo $returnHtml;
        } else {
            echo "0 results";
        }
    }else{
        echo "0 results";
    }
    ?>
    

    Also, as Dharman mentioned, you should really use parameterized queries. I know that seems like some extra work but trust me, it will be worth your time.

    Login or Signup to reply.
  2. (Too long for a Comment.)

    Let me get this straight. On a single page:

    1. The page is initialized with a list of all countries. (Either when building the page, or via AJAX.)
    2. The user selects one country from a list of all the countries.
    3. A second database lookup finds the cities in that country.
    4. Then something is done with those cities.

    That must be two lookups.

    Since you mentioned AJAX, you want to do all this without reloading the page? Be aware that <form> wants to reload the page. Yes you can pervert to do AJAX, but why have <form> if you won’t be submitting and reloading the page?

    The complete list of cities in the world is over 3 million. Are you working with that sized table? Or some subset, such as "cities that have a Burger King in it"?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search