Tedd's State/City/Zip AJAX Demo

State City Zip Code

Description and Example of the AJAX Operation

When a user visits this site, the index.php script loads the main page with header and footer scripts and includes the assistant.php script (i.e. <?php include(assistant.php); ?> ). The main pages does nothing more than start the process and show the code.

The assistant.php script sets the default location State and City to AL, ABBEVILLE -- the top of the db.

When the user selects a State, the assistant.php script triggers an AJAX action that sends a request with data (i.e., the State) to the server. After the server approves the request, the AJAX script returns the data (i.e., the State) back to the assistant.php script via the GET method.

The assistant.php script then uses the GET statement to retrieve the data (i.e., the State) and searches the database for a list of Cities that match the State. After retrieving the data the assistant.php script populates the City Selection Control. The assistant.php script also populates the Zip Code Selection Control with a list of the Zip Code(s) found for the City shown.

When the user selects a City, then again the assistant.php script triggers an AJAX action that sends a request to the server. After the server approves the request, the AJAX script returns the data (i.e., the City) back to the assistant.php script via the GET method.

The assistant.php script then uses the GET statement to retrieve the data (i.e., the City) and searches the database for a list of Zip Codes that match that City and populates the Zip Code Selection Control.

What is neat about this DEMO is that the Selection Controls are brought forward via DOM scripting by the AJXA script. The assistant.php script does all the work with database calls and populating of the Selection Control and the AJAX script places those updated Selection Controls within the assistant.php page between the:

<div id="myspan">

Selection Control CODE GOES HERE

</div>

This is a neat DEMO to show how the client and server scripts can communicate without requiring a full Browser refresh and thus making the process behave more like a desktop application than a typical webpage.


1) CODE for index.php

<?php

    
if (!session_id())
        {
        
session_start();
        }

    
// init sessions setting default to LANSING, MI
    
$_SESSION['state'] = 'MI'// use state_prefix for state
    
$_SESSION['city'] = 'LANSING';

    include(
"includes/header.php");
?>

<h1> Tedd's State/City/Zip AJAX Demo </h1>

<?php include("assistant.php"); ?>

<br>
<h2>Description and Example of the AJAX Operation</h2>

<p>
    When a user visits this site, the index.php script loads the main page with header and footer scripts and
    includes the assistant.php script (i.e. &lt;?php include(assistant.php); ?&gt; ). The main pages does
    nothing more than start the process and show the code.
</p>

<p>
    The assistant.php script sets the default location State and City to AL, ABBEVILLE -- the top of the db.
</p>

<p>
    When the user selects a State, the assistant.php script triggers an AJAX action that sends a request with
    data (i.e., the State) to the server. After the server approves the request, the AJAX script returns the data
    (i.e., the State) back to the assistant.php script via the GET method.
</p>

<p>
    The assistant.php script then uses the GET statement to retrieve the data (i.e., the State) and searches the
    database
    for a list of Cities that match the State. After retrieving the data the assistant.php script populates the City
    Selection
    Control. The assistant.php script also populates the Zip Code Selection Control with a list of the Zip Code(s) found
    for
    the City shown.
</p>

<p>
    When the user selects a City, then again the assistant.php script triggers an AJAX action that sends a request to
    the
    server. After the server approves the request, the AJAX script returns the data (i.e., the City) back to the
    assistant.php script via the GET method.
</p>

<p>
    The assistant.php script then uses the GET statement to retrieve the data (i.e., the City) and searches the database
    for a list of Zip Codes that match that City and populates the Zip Code Selection Control.
</p>

<p>
    What is neat about this DEMO is that the Selection Controls are brought forward via DOM
    scripting by the AJXA script. The assistant.php script does all the work with database calls and populating of the
    Selection Control and the AJAX script places those updated Selection Controls within the assistant.php page between
    the:
    <br><br>
    &lt;div id="myspan"&gt; <br><br>
    Selection Control CODE GOES HERE
    <br><br>
    &lt;/div&gt;
    <br><br>
</p>

<p>
    This is a neat DEMO to show how the client and server scripts can communicate without requiring a full
    Browser refresh and thus making the process behave more like a desktop application than a typical webpage.
</p>

<?php

    
// =============== show all code ======================

    
echo('<hr>');
    
$self "index.php";
    echo(
'1) CODE for index.php<br><br>');
    
highlight_file($self);
    echo(
'<hr>');

    
$self "assistant.php";
    echo(
'2) CODE for assistant.php<br><br>');
    
highlight_file($self);
    echo(
'<hr>');

    
$self "js/ajax.js";
    echo(
'3) CODE for ajax.js<br><br>');
    
highlight_file($self);
    echo(
'<hr>');

    include(
'includes/footer.php');
?>

2) CODE for assistant.php

<?php

    
if (!session_id())
        {
        
session_start();
        }

    
// get current data from AJAX (if sent) or use the default SESSION
    
$state = isset($_GET['state']) ? $_GET['state'] : $_SESSION['state'];
    
$city = isset($_GET['city']) ? $_GET['city'] : $_SESSION['city'];
    
$zip = isset($_GET['zip']) ? $_GET['zip'] : $_SESSION['zip'];

    
$city str_replace('-'' '$city);   // remove the - from cities like AGOURA-HILLS, CA

    // update sessions if things have changed -- city first and then state

    
if ($_SESSION['state'] != $state)
        {
        
$city '';
        
$zip '';
        }

    if (
$_SESSION['city'] != $city)
        {
        
$zip '';
        }

    
$_SESSION['state'] = $state;
    
$_SESSION['city'] = $city;
    
$_SESSION['zip'] = $zip;

    
$state_name = array();
    
$state_prefix = array();
    
$city_name = array();
    
$state_prefix = array();
    
$zip_code = array();
    
$con '';

    include(
'includes/open-db.php');    // open dB

    // get States
    
$query "SELECT state_name, state_prefix  FROM state ORDER BY state_name ";
    
$result mysqli_query($con$query) or die(report($query__LINE____FILE__));
    while (
$row mysqli_fetch_array($result))
        {
        
$state_name[] = $row['state_name'];
        
$state_prefix[] = $row['state_prefix'];
        }

    
// get Cities
    
$query "SELECT city FROM zip_code WHERE state_prefix = '$state' ORDER BY city ";
    
$result mysqli_query($con$query) or die(report($query__LINE____FILE__));
    while (
$row mysqli_fetch_array($result))
        {
        
$city_name[] = $row['city'];
        }

    
$city_name array_unique($city_name); // city is not unique in the db
    
sort($city_name);

    if (
$city == '')
        {
        
$city $city_name[0];
        
$_SESSION['city'] = $city;
        }

    
// get zips
    
$query "SELECT zip_code FROM zip_code WHERE city = '$city' AND state_prefix = '$state' ORDER BY zip_code ";
    
$result mysqli_query($con$query) or die(report($query__LINE____FILE__));
    while (
$row mysqli_fetch_array($result))
        {
        
$zip_code[] = $row['zip_code'];
        }

    include(
'includes/close-db.php');            // close dB

    
sort($zip_code);

    
$url 'assistant.php';   // this is important for AJAX operation

    //====================  show dB errors  ======================

    
function report($query$line$file)
        {
        echo(
$query '<br>' $line '<br>' $file '<br>' mysqli_error());
        }

?>

<div id="myspan">     <!-- start of myspan -->

    <table class="full">
        <tr>
            <th>
                State
            </th>
            <th>
                City
            </th>
            <th>
                Zip Code
            </th>
        </tr>
        <tr>
            <td class="center">

                <select name="state" onchange="get(this.parentNode, '<?php echo($url); ?>');">

                    <?php

                        
foreach ($state_prefix as $key => $value)
                            {
                            
$selected '';
                            if (
$value == $state)
                                {
                                
$selected 'selected';
                                }
                            echo(
"<option value=$value $selected >$value : $state_name[$key]");
                            }
                    
?>
                </select>
            </td>
            <td class="center">
                <select name="city" onchange="get(this.parentNode, '<?php echo($url); ?>');">

                    <?php

                        
foreach ($city_name as $value)
                            {
                            
$selected '';
                            if (
$value == $city)
                                {
                                
$selected 'selected';
                                }
                            
$v str_replace(' ''-'$value);
                            echo(
"<option value=$v $selected >$value");
                            }
                    
?>

                </select>
            </td>
            <td class="center">
                <select name="zip">

                    <?php

                        
foreach ($zip_code as $value)
                            {
                            echo(
"<option value=$value>$value");
                            }
                    
?>

                </select>
            </td>
        </tr>
    </table>

</div>

3) CODE for ajax.js

// AJAX GET

var http_request = false;

function makeRequest(url, parameters)
    {
        http_request = false;
        if (window.XMLHttpRequest)  // Mozilla, Safari,...
            {
            http_request = new XMLHttpRequest();
            if (http_request.overrideMimeType)
                {
                http_request.overrideMimeType('text/html');
                }
            }
        else
            {
            if (window.ActiveXObject)  // IE
                {
                try
                    {
                    http_request = new ActiveXObject("Msxml2.XMLHTTP");
                    }
                catch (e)
                    {
                    try
                        {
                        http_request = new ActiveXObject("Microsoft.XMLHTTP");
                        }
                    catch (e)
                        {
                        // do nothing
                        }
                    }
                }
            }
        
        if (!http_request)
            {
            alert('Cannot create XMLHTTP instance');
            return false;
            }
        
        http_request.onreadystatechange = alertContents;
        http_request.open('GET', url + parameters, true);
        http_request.send(null);
    }

function alertContents()
    {
        if (http_request.readyState === 4)
            {
            if (http_request.status === 200)
                {
                result = http_request.responseText;
                document.getElementById('myspan').innerHTML = result;
                }
            else
                {
                alert('There was a problem with the request.');
                }
            }
    }

function get(obj, url)
    {
        var getstr = "?";
        var i;
        
        for (i = 0; i < obj.childNodes.length; i++)
            {
            if (obj.childNodes[i].tagName === "INPUT")
                {
                if (obj.childNodes[i].type === "text")
                    {
                    getstr += obj.childNodes[i].name + "=" + obj.childNodes[i].value + "&";
                    }
                
                if (obj.childNodes[i].type === "checkbox")
                    {
                    if (obj.childNodes[i].checked)
                        {
                        getstr += obj.childNodes[i].name + "=" + obj.childNodes[i].value + "&";
                        }
                    else
                        {
                        getstr += obj.childNodes[i].name + "=&";
                        }
                    }
                
                if (obj.childNodes[i].type === "radio")
                    {
                    if (obj.childNodes[i].checked)
                        {
                        getstr += obj.childNodes[i].name + "=" + obj.childNodes[i].value + "&";
                        }
                    }
                }
            
            if (obj.childNodes[i].tagName === "SELECT")
                {
                var sel = obj.childNodes[i];
                getstr += sel.name + "=" + sel.options[sel.selectedIndex].value + "&";
                }
            
            if (obj.childNodes[i].type === "textarea")
                {
                getstr += obj.childNodes[i].name + "=" + obj.childNodes[i].value + "&";
                }
            }
        //alert(getstr);
        makeRequest(url, getstr);
    }