Or for AJAX use something like this one we did which does it for countries, states, towns, schools. You obviously need the GEO data for each country. I am sure you can buy this online or maybe get it free from somewhere. We can't release ours as it is licenced.
function StatesPopulate(FormHandler,AllowEmpty){
for(var k = FormHandler.state.options.length-1; k>=0; k--){
FormHandler.state.options[k] = null;
}//for
for(var k = FormHandler.city.options.length-1; k>=0; k--){
FormHandler.city.options[k] = null;
}//for
FormHandler.state.options[0] = new Option("...loading...");
FormHandler.city.options[0] = new Option("...loading...");
var Country = FormHandler.country.options[FormHandler.country.selectedIndex].value;
var xmlHttpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}//if
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}//else if
self.xmlHttpReq.open('POST', "http://www.neredesindostum.com/geo.php", true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4 && self.xmlHttpReq.status == 200) {
//alert(self.xmlHttpReq.responseText);
PullData(self.xmlHttpReq.responseXML,FormHandler.state,'state');
PullData(self.xmlHttpReq.responseXML,FormHandler.city,'city');
}//if
if (xmlHttpReq.readyState == 4) {
strResponse = xmlHttpReq.responseText;
switch (xmlHttpReq.status) {
// Page-not-found error
case 404:
alert('Error: Not Found. The requested URL ' +
strURL + ' could not be found.');
break;
// Display results in a full window for server-side errors
case 500:
handleErrFullPage(strResponse);
break;
default:
// Call JS alert for custom error or debug messages
if (strResponse.indexOf('Error:') > -1 ||
strResponse.indexOf('Debug:') > -1) {
alert(strResponse);
}
// Call the desired result function
else {
eval(strResultFunc + '(strResponse);');
}
break;
}
}
}//function
self.xmlHttpReq.send("action=states&country="+Country);
}//StatesPopulate
function CitiesPopulate(FormHandler,AllowEmpty){
for(var k = FormHandler.city.options.length-1; k>=0; k--){
FormHandler.city.options[k] = null;
}//for
FormHandler.city.options[0] = new Option("...loading...");
var Country = FormHandler.country.options[FormHandler.country.selectedIndex].value;
var State = FormHandler.state.options[FormHandler.state.selectedIndex].value;
var xmlHttpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}//if
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}//else if
self.xmlHttpReq.open('POST', "http://www.neredesindostum.com/geo.php", true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4 && self.xmlHttpReq.status == 200) {
alert(self.xmlHttpReq.responseText);
PullData(self.xmlHttpReq.responseXML,FormHandler.city,'city');
}//if
}//function
self.xmlHttpReq.send("action=cities&country="+Country+"&state="+State+"&allow_empty="+AllowEmpty);
}//CitiesPopulate
function PullData(XMLData,FieldHandler,ItemName){
//alert(XMLData[1]);
for(var k = FieldHandler.options.length-1; k>=0; k--){
FieldHandler.options[k] = null;
}//for
var Items = XMLData.getElementsByTagName(ItemName);
// alert(Items[0,0]);
for(var i=0;i<Items.length;i++){
var ItemID = Items[i].firstChild.firstChild.nodeValue;
var ItemName = Items[i].firstChild.nextSibling.firstChild.nodeValue;
FieldHandler.options[i] = new Option(ItemName,ItemID);
}//for
}//PullData
And then the geo.php
<?php
if ( !defined( 'SMARTY_DIR' ) ) {
include_once( 'init.php' );
}
$action = $_POST["action"];
$fill = $_POST["fill"];
switch($action)
{
case 'states':
states($fill);
break;
case 'cities':
cities($fill);
break;
case 'streets':
streets($fill,'');
break;
case 'organisations':
organisations($fill,'');
break;
case 'schools':
schools($fill,'');
break;
}//switch
function states($fill=0){
$countryID = $_POST["country"];
$allow_empty = $_POST["allow_empty"];
$sql = "SELECT state_id,state_name FROM tbl_states WHERE country_id=$countryID ORDER BY state_name";
$res1 = mysql_query ($sql);
$rows=array();
while ($row = mysql_fetch_array ($res1)) {
$rows[]=$row;
}
$first = 1;
$reply = "<geo>\n";
$reply.= "<states>\n";
foreach($rows as $row){
if($first){
$stateID = $row["state_id"];
$first = 0;
}//if
$reply.= "<state><id>".$row[0]."</id><name>".htmlspecialchars(trim($row[1]))."</name></state>\n";
}//foreach
$reply.= "</states>\n";
if(empty($state) || $allow_empty)
$state = 0;
$sql = "SELECT * FROM tbl_towns
WHERE country_id=".$countryID."
AND state_id=".$stateID."
ORDER BY town_name";
$res = mysql_query ($sql);
if (mysql_num_rows ($res) >= 1)
{
$result2=array();
while ($rows = mysql_fetch_array ($res)) $result2[]=$rows;
$reply.= "<cities>\n";
$first=1;
foreach($result2 as $res3){
if ($first) {
$townID = $res3["town_id"];
$first=0;
}
$reply.= "<city><id>".$res3["town_id"]."</id><name>".htmlspecialchars(trim($res3["town_name"]))."</name></city>\n";
}//foreach
$reply.= "</cities>\n";
}
switch($fill)
{
case 'streets':
streets($fill,$reply,$townID,$stateID);
break;
case 'organisations':
organisations($fill,$reply,$townID,$stateID);
break;
case 'schools':
schools($fill,$reply,$townID,$stateID);
break;
}//switch
$reply.= "</geo>";
Header("Content-Type: text/xml; charset:utf-8");
print $reply;
exit;
}//states
function cities($fill=0){
$countryID = $_POST["country"];
$stateID = $_POST["state"];
$reply = "<geo>\n";
$sql_query = "SELECT * FROM tbl_towns
WHERE country_id=".$countryID."
AND state_id=".$stateID."
ORDER BY town_name";
$res = mysql_query ($sql_query);
$result3=array();
while ($rows = mysql_fetch_array ($res)) $result3[]=$rows;
$reply.= "<cities>\n";
//if($allow_empty){
// $reply.= "<city><id>0</id><name>Please select</name></city>";
//}//if
$first=1;
foreach($result3 as $res){
if($first){
$townID = $res["town_id"];
$first = 0;
}
$reply.= "<city><id>".$res["town_id"]."</id><name>".htmlspecialchars(trim($res["town_name"]))."</name></city>\n";
}//foreach
$reply.= "</cities>\n";
switch($fill)
{
case 'streets':
streets($fill,$reply,$townID,$stateID);
break;
case 'organisations':
organisations($fill,$reply,$townID,$stateID);
break;
case 'schools':
schools($fill,$reply,$townID,$stateID);
break;
default:
$reply.="</geo>";
}//switch
Header("Content-Type: text/xml; charset:utf-8");
print $reply;
exit;
}//cities
function schools($fill=0,$reply='',$townID='',$stateID=''){
$countryID = $_POST["country"];
if ($stateID=='') $stateID = $_POST["state"];
if ($townID=='') $townID = $_POST["city"];
if (!($fill=="schools")) $reply = "<geo>\n";
$sql_query = "SELECT * FROM tbl_schools
WHERE country_id=".$countryID."
AND state_id=".$stateID."
AND town_id=".$townID."
ORDER BY school_name";
$res = mysql_query ($sql_query);
$result4=array();
while ($rows = mysql_fetch_array ($res)) $result4[]=$rows;
$reply.= "<schools>\n";
foreach($result4 as $res){
$reply.= "<school><id>".$res["school_id"]."</id><name>".htmlspecialchars(trim($res["school_name"]))."</name></school>\n";
}//foreach
$reply.= "</schools>\n";
$reply.= "</geo>";
Header("Content-Type: text/xml; charset:utf-8");
print $reply;
exit;
}
function streets($fill=0,$reply='',$townID='',$stateID=''){
$countryID = $_POST["country"];
if ($stateID=='') $stateID = $_POST["state"];
if ($townID=='') $townID = $_POST["city"];
if (!($fill=="streets")) $reply = "<geo>\n";
//$reply="<geo>\n";
$sql_query = "SELECT * FROM tbl_streets
WHERE country_id=".$countryID."
AND state_id=".$stateID."
AND town_id=".$townID."
ORDER BY street_name";
$res = mysql_query ($sql_query);
$result4=array();
while ($rows = mysql_fetch_array ($res)) $result4[]=$rows;
$reply.= "<streets>\n";
foreach($result4 as $res){
$reply.= "<street><id>".$res["street_id"]."</id><name>".htmlspecialchars(trim($res["street_name"]))."</name></street>\n";
}//foreach
$reply.= "</streets>\n";
$reply.= "</geo>";
Header("Content-Type: text/xml; charset:utf-8");
print $reply;
exit;
}//streets
function organisations($fill=0,$reply='',$townID='',$stateID=''){
$countryID = $_POST["country"];
if ($stateID=='') $stateID = $_POST["state"];
if ($townID=='') $townID = $_POST["city"];
if (!($fill=="organisations")) $reply = "<geo>\n";
$sql_query = "SELECT * FROM tbl_organisations
WHERE country_id=".$countryID."
AND state_id=".$stateID."
AND town_id=".$townID."
ORDER BY organisation_name";
$res = mysql_query ($sql_query);
$result4=array();
while ($rows = mysql_fetch_array ($res)) $result4[]=$rows;
$reply.= "<organisations>\n";
foreach($result4 as $res){
$reply.= "<organisation><id>".$res["organisation_id"]."</id><name>".htmlspecialchars(trim($res["organisation_name"]))."</name></organisation>\n";
}//foreach
$reply.= "</organisations>\n";
$reply.= "</geo>";
Header("Content-Type: text/xml; charset:utf-8");
print $reply;
exit;
}
?>