Cóż, to czego naprawdę potrzebujesz to wywołanie AJAX, które pozwala komunikować się z serwerem bez przeładowywania strony. Wszystko, co musisz zrobić, to w zasadzie wysłać nowe żądanie HTTP z parametrem kraju, aby uzyskać w nim listę miast. Prawidłowym sposobem byłoby przesłanie (odpowiedź HTTP) tylko danych (miasta) w formacie JSON lub podobnym, a nie ich prezentacji również (html), ale dla uproszczenia można kontynuować pracę tak, jak na początku (zwróć dane za pomocą html) .
Zacznij od oddzielenia kodu, który generuje HTML selectBoxOptions miast w innym skrypcie. Użyjesz tego skryptu, aby uzyskać listę miast w danym kraju za pomocą AJAX (biblioteka XMLHttpRequest).
Spójrz na to, to działające rozwiązanie Twojego problemu. Żądanie HTTP jest wysyłane za każdym razem, gdy użytkownik zmienia opcję countrySelectBox, dzięki czemu pole wyboru miast jest aktualizowane za każdym razem, gdy jest to potrzebne. Wystarczy zmienić adres URL w atrybucie onchange, który wskazuje na twój skrypt (wcześniej powiedziałem, że powinieneś przenieść Drugi blok kodu do osobnego skryptu).
<!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>");
}
?>
EDYCJA:
httpGetAsync jest natywny (używany jest tylko czysty/vanilla javascript. Żadne inne biblioteki nie są używane) funkcja javascript, która umożliwia wysyłanie żądań HTTP bez przeładowywania strony. Widzę, że używasz jQuery, które ukrywa złożoność tej funkcji, podobnie jak form->submit, ale radzę dowiedzieć się, jak działa httpGetAsync, ponieważ używanie jQuery do tak prostego zadania jest przesadą.
Nie potrzebujesz tej funkcji javascript
function getCity(countryId)
Zamiast tego należy umieścić kod komunikujący się z bazą danych w pliku .php, a nie w javascript (pamiętaj, że javascript to strona kliencka, wykonuje się na maszynie klienta, np. przeglądarce, a php na serwerze). Twój SQL nigdy nie powinien być napisany w javascript. Kod po stronie klienta nie może komunikować się bezpośrednio z bazą danych, tylko poprzez kodowanie po stronie serwera. Aby to osiągnąć, musisz zwrócić wartość skryptu PHP getCities.php z powrotem do klienta (javascript) jako odpowiedź HTTP.
Kiedy wysyłasz żądanie HTTP do jakiegoś pliku .php, skrypty są wykonywane na serwerze, a wszystko, co powiedziałeś „echo” lub „drukuj” na końcu skryptu, jest automatycznie wysyłane jako odpowiedź HTTP. W rzeczywistości nie musisz pisać żadnego kodu, aby wysłać odpowiedź HTTP. Zrobione automatycznie. Musisz tylko powtórzyć/wydrukować wszystko, czego potrzebujesz po stronie klienta. W Twoim przypadku musisz wydrukować opcje dla konkretnego kraju.
Skąd skrypt wie, dla jakiego kraju musi wybrać miasta z bazy danych? Cóż, wysyłasz żądanie HTTP z parametrem "kraj". To właśnie robi Twój formularz automatycznie po przesłaniu go. Wszystkie znaczniki HTML, które znajdują się w formularzu i mają ustawiony atrybut nazwy, zostaną wysłane w żądaniu HTTP jako parametry. Ale ponieważ nie możesz użyć przesyłania, musisz to zrobić ręcznie.
Wysłanie parametru w żądaniu HTTP GET jest bardzo proste. Spójrz na następujący adres URL:
localhost/getCities?country=countryX&someOtherParam=something&myThirdParam=something3
Po stronie serwera zostaną wypełnione następujące zmienne:
$_GET["country"] // value is 'countryX'
$_GET["someOtherParam"] // value is 'something'
$_GET["myThirdParam"] // value is 'something3'
Aby dowiedzieć się więcej o tym, jak działają GET i POST i jaka jest różnica, przeczytaj to
Zacznij od utworzenia pliku getCities.php i skopiuj i wklej kod, który komunikuje się z bazą danych i generuje opcje miasta. To w zasadzie to, co już zrobiłeś, wystarczy umieścić ten kod w osobnym pliku .php. Tak więc, gdy klient (przeglądarka) poprosi o listę miast w danym kraju, wyślesz żądanie HTTP (za pomocą funkcji httpGetAsync()), aby pobrać tę listę z serwera.
W swoim index.php skopiuj wklej ten skrypt
<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>
Następnie umieść atrybut onchange w polu wyboru, pamiętaj, że wszystkie małe litery, a nie onChange.
<select name="country" id="country" onchange="httpGetAsync('localhost/getCities?country=' + this.value, populateCities)">
W przypadku jakichkolwiek pytań po prostu zadaj... :)