I have a list of cities, and a set of "travel time" between any given two cities. The "travel time" is fixed and not necessarily dependent on absolute distance between the two cities, and it currently exists in an Excel doc that's manually maintained.
I wanted users to be able to specify two cities from two dropdown menus and see how long it takes to travel between those cities without submitting anything to the page.
Challenges I ran into:
- How to minimize redundant data in the database
- How to delay running the AJAX request until both variables have been specified (this is my first time using AJAX for...anything.)
Here is the completed code - it works, but it seems a little clumsy. I'd really appreciate any feedback. (The database entries are fake and only for testing purposes.)
AJAX:
// Create empty variables in preparation for the two values from the two dropdown menus
var first;
var second;
function firstly(x) {
// Grab the value from the first dropdown and set it to 'first'
first = x.value;
if (typeof second != 'undefined') { // If 'second' isn't undefined, run the 'route' function with the two variables
route(first, second);
} // Otherwise do nothing
}
// This is the same function but for the second variable
function secondly(x) {
second = x.value;
if (typeof first != 'undefined') {
route(first, second);
}
}
// This is the AJAX function that takes two parameters
function route(first, second) {
var xmlhttp;
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
// if the XMLHttpRequest is successful
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
// Then populate div id="distance" with the responseText
document.getElementById("distance").innerHTML=xmlhttp.responseText;
}
}
// Actually send the data using the variables assigned with firstly() and secondly()
xmlhttp.open("GET","route.php?first="+first+"&second="+second,true);
xmlhttp.send();
}
PHP:
<?php
require_once('config.php');
$first = $_GET['first'];
$second = $_GET['second'];
if ($first === $second) {
echo "These two cities are the same: '" . $first . "' and '" . $second . "'.";
} else {
$select = "SELECT * FROM distances WHERE (first='$first' OR second='$first') AND (first='$second' OR second='$second');";
$result = mysql_query($select);
if (!$result) { die ('Error: ' . mysql_error()); };
while($row = mysql_fetch_array($result)) { echo $first . " to " . $second . " will take " . $row['distance'] . " hours.<br />"; }
}
?>
DROPDOWNS:
<?php
// This creates the two dropdown menus based on what's available in the database
$select = "SELECT DISTINCT(first) AS first FROM distances";
$result = mysql_query($select);
if (!$result) { die ('Error: ' . mysql_error()); };
// Store a distinct list of all cities in the table in an array
$cities = array();
$count = 0;
while ($row = mysql_fetch_array($result)) {
$count++;
$cities[$count] = $row['first'];
}
?>
<form>
<!-- When an option is selected, it runs firstly() -->
<select name="first" onchange="firstly(this)">
<option selected value=""></option>
<?php
// Loop through all the entries in $cities and create an option for each one
for ($i = 1; $i <= count($cities); ++$i) {
echo "<option value='" . $cities[$i] . "'>" . $cities[$i] . "</option>";
}
?>
</select>
<br />
<!-- Repeat the process for the destination city -->
<select name="second" onchange="secondly(this)">
<option selected value=""></option>
<?php
for ($i = 1; $i <= count($cities); ++$i) {
echo "<option value='" . $cities[$i] . "'>" . $cities[$i] . "</option>";
}
?>
</select>
<br />
</form>
<div id="distance"></div>
Gist link: https://gist.github.com/phirephoenix/5523188