Nå, hvad du virkelig har brug for er AJAX-opkald, som giver dig mulighed for at kommunikere med serveren uden at genindlæse en side. Alt du skal gøre er i bund og grund at sende en ny HTTP-anmodning med en landeparameter for at få listen over byer i den. Den korrekte måde ville være at sende (HTTP-svar) kun data(byer) i JSON eller lignende format, og ikke dets præsentation også (html), men for nemheds skyld kan du fortsætte med at arbejde som du startede (returner data med html) .
Start med at adskille koden, der genererer HTML selectBoxOptions af byer i et andet script. Du vil bruge dette script til at få listen over byer i et bestemt land ved at bruge AJAX (XMLHttpRequest library).
Tag et kig på dette, det er en fungerende løsning på dit problem. HTTP-anmodning sendes, hver gang brugeren ændrer countrySelectBox-indstillingen, på den måde bliver din byvalgsboks opdateret, hver gang den har brug for det. Alt du skal gøre er at ændre url'en i onchange-attributten, der peger på dit script (jeg sagde tidligere, at du skulle flytte 2. kodeblok i separat script).
<!DOCTYPE html>
<html>
<head>
<script>
function populateCities(citiesSelectBoxOptions){
document.getElementById("city").innerHTML = citiesSelectBoxOptions;
}
function httpGetAsync(theUrl, callback)
{
alert(theUrl);
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
xmlHttp.open("GET", theUrl, true); // true for asynchronous
xmlHttp.send(null);
}
</script>
</head>
<body>
<select name="country" id="country" onchange="httpGetAsync('www.yourdomain.com/getCities.php?country=' + this.options[this.selectedIndex].value, populateCities)">
<option value="Country1">Country 1</option>
<option value="Country2">Country 2</option>
</select>
<select name="city" id="city">
</select>
</body>
</html>
getCities.php
<?php
$db = pg_connect("$db_host $db_name $db_username $db_password");
$selectedCountry = $_GET['country'];
$query = "SELECT city FROM cities where country = ' $selectedCountry '";
$result = pg_query($query);
if (!$result) {
echo "Problem with query " . $query . "<br/>";
echo pg_last_error();
exit();
}
printf ("<option value='Select'>Select a City</option>");
while($myrow = pg_fetch_assoc($result)) {
printf ("<option value='$myrow[city]'>$myrow[city]</option>");
}
?>
EDIT:
httpGetAsync er native (kun ren/vanilla javascript bruges. Der bruges ingen andre biblioteker) javascript-funktion, der gør det muligt for dig at sende HTTP-anmodning uden at genindlæse en side. Jeg kan se, at du bruger jQuery, som skjuler denne funktions kompleksitet, det samme som form->submit, men jeg anbefaler dig at lære, hvordan httpGetAsync fungerer, fordi det er overdrevet at bruge en jQuery til sådan en simpel opgave.
Du behøver ikke denne javascript-funktion
function getCity(countryId)
I stedet skal du lægge din kode, der kommunikerer med databasen, i en .php-fil, ikke i javascript (husk, javascript er en klientside, det kører på klientmaskine, f.eks. browser, mens php kører på server). Din SQL bør aldrig skrives i javascript. Klientsidekode kan ikke kommunikere direkte med en database, kun gennem serversidekodning. For at opnå det skal du returnere en værdi af PHP-scriptet getCities.php tilbage til klienten (javascript) som et HTTP-svar.
Når du sender en HTTP-anmodning til en eller anden .php-fil, udføres det script på en server, og alt, hvad du sagde "ekko" eller "udskriv", i slutningen af scriptet, sendes automatisk som HTTP-svar. Du behøver faktisk ikke at skrive nogen kode for at sende et HTTP-svar. Det gøres automatisk. Du skal bare gentage/printe, hvad du har brug for på klientsiden. I dit tilfælde skal du udskrive muligheder for et bestemt land.
Hvordan ved scriptet for hvilket land det skal vælge byer fra databasen? Nå, du sender HTTP-anmodning med en parameter "land". Det er det, du formular gør automatisk, når du indsender det. Alle HTML-tags, der er inde i Form, og som har en navneattribut indstillet, vil blive sendt i HTTP-anmodning som parametre. Men da du ikke kan bruge submit, skal du gøre dette manuelt.
Det er meget enkelt at sende en parameter inde i HTTP GET-anmodningen. Tag et kig på følgende url:
localhost/getCities?country=countryX&someOtherParam=something&myThirdParam=something3
På serversiden vil følgende variabler blive udfyldt:
$_GET["country"] // value is 'countryX'
$_GET["someOtherParam"] // value is 'something'
$_GET["myThirdParam"] // value is 'something3'
For at lære mere om, hvordan GET og POST fungerer, og hvad der er forskellen, tjek dette
Kom i gang ved at oprette en getCities.php-fil, og copy-paste koden, der kommunikerer med databasen og genererer byindstillinger. Det er dybest set, hvad du allerede har gjort, du skal bare sætte den kode i en separat .php-fil. Så når en klient (browser) beder om en liste over byer i et bestemt land, vil du sende en HTTP-anmodning (ved at bruge httpGetAsync()-funktionen) for at hente listen fra serveren.
I din index.php kopi indsæt dette script
<script>
function populateCities(citiesSelectBoxOptions){
document.getElementById("city").innerHTML = citiesSelectBoxOptions;
}
function httpGetAsync(theUrl, callback)
{
alert(theUrl);
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
xmlHttp.open("GET", theUrl, true); // true for asynchronous
xmlHttp.send(null);
}
</script>
Dernæst skal du sætte onchange attribut på select box, husk, det er små bogstaver, ikke onChange.
<select name="country" id="country" onchange="httpGetAsync('localhost/getCities?country=' + this.value, populateCities)">
For ethvert spørgsmål bare spørg... :)