Tja, vad du verkligen behöver är AJAX-anrop som låter dig kommunicera med servern utan att ladda om en sida. Allt du behöver göra är att skicka en ny HTTP-förfrågan med en landsparameter för att få listan över städer i den. Det korrekta sättet skulle vara att bara skicka (HTTP-svar) data(städer) i JSON eller liknande format, och inte dess presentation också (html), men för enkelhetens skull kan du fortsätta att arbeta som du började (returnera data med html) .
Börja med att separera koden som genererar HTML selectBoxAlternativ för städer i ett annat skript. Du kommer att använda det skriptet för att få listan över städer i ett visst land genom att använda AJAX (XMLHttpRequest library).
Ta en titt på det här, det är en fungerande lösning på ditt problem. HTTP-begäran skickas när användaren ändrar alternativet countrySelectBox, på så sätt uppdateras dina städervalsruta varje gång den behöver. Allt du behöver göra är att ändra URL:en i onchange-attributet som pekar på ditt skript (jag sa tidigare att du ska flytta 2:a kodblocket i separat skript).
<!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 är inbyggd (endast rent/vanilla javascript används. Inga andra bibliotek används) javascript-funktion som gör att du kan skicka HTTP-förfrågan utan att ladda om en sida. Jag ser att du använder jQuery, vilket döljer den här funktionens komplexitet, samma som form->submit, men jag rekommenderar dig att lära dig hur httpGetAsync fungerar, eftersom det är överdrivet att använda en jQuery för en så enkel uppgift.
Du behöver inte denna javascript-funktion
function getCity(countryId)
Istället bör du lägga din kod som kommunicerar med databasen i en .php-fil, inte i javascript (kom ihåg att javascript är en klientsida, det körs på klientdatorn, t.ex. webbläsaren, medan php körs på servern). Din SQL ska aldrig skrivas i javascript. Kod på klientsidan kan inte kommunicera direkt med en databas, endast genom kodning på serversidan. För att åstadkomma det måste du returnera värdet på PHP-skriptet getCities.php till klienten (javascript) som ett HTTP-svar.
När du skickar en HTTP-förfrågan till någon .php-fil, körs det skriptet på en server, och allt som du sa "eko" eller "skriv ut", i slutet av skriptet, skickas automatiskt som HTTP-svar. Du behöver faktiskt inte skriva någon kod för att skicka ett HTTP-svar. Det görs automatiskt. Du behöver bara eka/skriva ut vad du behöver på klientsidan. I ditt fall måste du skriva ut alternativ för ett visst land.
Hur vet skriptet för vilket land det behöver välja städer från databasen? Tja, du skickar HTTP-förfrågan med parametern "land". Det är vad du formulär gör automatiskt när du skickar in det. Alla HTML-taggar som finns i Form och har ett namnattribut set, kommer att skickas i HTTP-förfrågan som parametrar. Men eftersom du inte kan använda submit måste du göra detta manuellt.
Att skicka en parameter inuti HTTP GET-begäran är väldigt enkelt. Ta en titt på följande url:
localhost/getCities?country=countryX&someOtherParam=something&myThirdParam=something3
På serversidan kommer följande variabler att fyllas i:
$_GET["country"] // value is 'countryX'
$_GET["someOtherParam"] // value is 'something'
$_GET["myThirdParam"] // value is 'something3'
För att lära dig mer om hur GET och POST fungerar, och vad som är skillnaden, kolla detta
Kom igång genom att skapa en getCities.php-fil och kopiera klistra in koden som kommunicerar med databasen och genererar stadsalternativ. Det är i princip vad du redan har gjort, du måste bara lägga den koden i en separat .php-fil. Så när en klient (webbläsare) frågar efter en lista över städer i ett visst land, kommer du att skicka en HTTP-förfrågan (med hjälp av funktionen httpGetAsync() för att hämta den listan från servern.
I din index.php kopiera klistra in detta skript
<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>
Lägg sedan onchange attribut på select box, kom ihåg att det bara är gemener, inte onChange.
<select name="country" id="country" onchange="httpGetAsync('localhost/getCities?country=' + this.value, populateCities)">
För alla frågor, fråga bara... :)