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. <?php include(assistant.php); ?> ). 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>
<div id="myspan"> <br><br>
Selection Control CODE GOES HERE
<br><br>
</div>
<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);
}