Bene, ciò di cui hai veramente bisogno è una chiamata AJAX che ti consente di comunicare con il server senza ricaricare una pagina. Tutto quello che devi fare è fondamentalmente inviare una nuova richiesta HTTP con un parametro paese per ottenere l'elenco delle città al suo interno. Il modo corretto sarebbe inviare (risposta HTTP) solo i dati (città) in formato JSON o simile e non anche la sua presentazione (html), ma per semplicità puoi continuare a lavorare come hai iniziato (restituire i dati con html) .
Inizia separando il codice che genera selectBoxOptions HTML delle città in un altro script. Utilizzerai quello script per ottenere l'elenco delle città in un determinato paese utilizzando AJAX (libreria XMLHttpRequest).
Dai un'occhiata a questo, è una soluzione funzionante del tuo problema. La richiesta HTTP viene inviata ogni volta che l'utente modifica l'opzione countrySelectBox, in questo modo la casella di selezione delle città viene aggiornata ogni volta che è necessario. Tutto quello che devi fare è modificare l'URL nell'attributo onchange che punta al tuo script (in precedenza ho detto che dovresti spostarti 2° blocco di codice in uno script separato).
<!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>");
}
?>
MODIFICA:
httpGetAsync è una funzione javascript nativa (viene utilizzato solo javascript puro/vanilla. Non vengono utilizzate altre librerie) che consente di inviare richieste HTTP senza ricaricare una pagina. Vedo che stai usando jQuery, che nasconde la complessità di questa funzione, come form->submit, ma ti consiglio di imparare come funziona httpGetAsync, perché usare un jQuery per un compito così semplice è eccessivo.
Non hai bisogno di questa funzione javascript
function getCity(countryId)
Invece, dovresti mettere il tuo codice che comunica con il database in un file .php, non in javascript (ricorda, javascript è un lato client, viene eseguito sulla macchina client, ad esempio un browser, mentre php viene eseguito sul server). Il tuo SQL non dovrebbe mai essere scritto in javascript. Il codice lato client non può comunicare direttamente con un database, solo tramite la codifica lato server. Per fare ciò, devi restituire un valore dello script PHP getCities.php al client (javascript) come risposta HTTP.
Quando invii una richiesta HTTP a un file .php, lo script viene eseguito su un server e tutto ciò che hai detto "eco" o "stampa", alla fine dello script, viene automaticamente inviato come risposta HTTP. In realtà non è necessario scrivere alcun codice per inviare una risposta HTTP. È fatto automaticamente. Devi solo fare eco/stampare tutto ciò di cui hai bisogno sul lato client. Nel tuo caso, devi stampare le opzioni per un determinato paese.
In che modo lo script sa per quale paese deve selezionare le città dal database? Bene, invii una richiesta HTTP con un parametro "paese". Questo è ciò che il modulo sta facendo automaticamente quando lo invii. Tutti i tag HTML che si trovano all'interno del modulo e hanno un attributo name impostato verranno inviati nella richiesta HTTP come parametri. Ma, poiché non puoi usare invia, devi farlo manualmente.
Inviare un parametro all'interno della richiesta HTTP GET è molto semplice. Dai un'occhiata al seguente URL:
localhost/getCities?country=countryX&someOtherParam=something&myThirdParam=something3
Sul lato server, verranno popolate le seguenti variabili:
$_GET["country"] // value is 'countryX'
$_GET["someOtherParam"] // value is 'something'
$_GET["myThirdParam"] // value is 'something3'
Per saperne di più su come funzionano GET e POST e qual è la differenza, controlla questo
Inizia creando un file getCities.php e copia incolla il codice che comunica con il database e genera le opzioni della città. Fondamentalmente è quello che hai già fatto, devi solo inserire quel codice in un file .php separato. Quindi, quando un client (browser) richiede un elenco di città in un determinato paese, invierai una richiesta HTTP (usando la funzione httpGetAsync()) per ottenere quell'elenco dal server.
Nel tuo index.php copia e incolla questo 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>
Quindi, inserisci l'attributo onchange nella casella di selezione, ricorda, è tutto minuscolo, non onChange.
<select name="country" id="country" onchange="httpGetAsync('localhost/getCities?country=' + this.value, populateCities)">
Per qualsiasi domanda chiedi pure... :)