Е, това, от което наистина се нуждаете, е AJAX повикване, което ви позволява да комуникирате със сървъра, без да презареждате страница. Всичко, което трябва да направите, е основно да изпратите нова HTTP заявка с параметър за държава, за да получите списъка с градове в нея. Правилният начин би бил да изпратите (HTTP отговор) само данните (градовете) в JSON или подобен формат, а не и тяхното представяне (html), но за простота можете да продължите да работите, както сте започнали (връщане на данни с html) .
Започнете, като разделите кода, който генерира HTML selectBoxOptions на градове в друг скрипт. Ще използвате този скрипт, за да получите списъка с градове в определена държава, като използвате AJAX (XMLHttpRequest библиотека).
Погледнете това, това е работещо решение на вашия проблем. HTTP заявката се изпраща всеки път, когато потребителят промени опцията countrySelectBox, по този начин вашето поле за избор на градове се актуализира всеки път, когато има нужда. Всичко, което трябва да направите, е да промените URL адреса в атрибута onchange, който сочи към вашия скрипт (преди казах, че трябва да преместите 2-ри блок от код в отделен скрипт).
<!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>");
}
?>
РЕДАКТИРАНЕ:
httpGetAsync е естествена (използва се само чист/ванилен javascript. Не се използват други библиотеки) javascript функция, която ви позволява да изпращате HTTP заявка без презареждане на страница. Виждам, че използвате jQuery, което скрива сложността на тази функция, същото като form->submit, но ви препоръчвам да научите как работи httpGetAsync, защото използването на jQuery за такава проста задача е излишно.
Нямате нужда от тази javascript функция
function getCity(countryId)
Вместо това трябва да поставите кода си, който комуникира с базата данни, в .php файл, а не в javascript (не забравяйте, че javascript е клиентска страна, той се изпълнява на клиентска машина, например браузър, докато php се изпълнява на сървър). Вашият SQL никога не трябва да бъде написан на javascript. Кодът от страна на клиента не може да комуникира директно с база данни, а само чрез кодиране от страна на сървъра. За да постигнете това, трябва да върнете стойност на PHP скрипта getCities.php обратно на клиента (javascript) като HTTP отговор.
Когато изпратите HTTP заявка към някакъв .php файл, този скрипт се изпълнява на сървър и всичко, което сте казали "echo" или "print", в края на скрипта, автоматично се изпраща като HTTP отговор. Всъщност не е нужно да пишете никакъв код, за да изпратите HTTP отговор. Извършва се автоматично. Просто трябва да повторите/отпечатате каквото ви трябва от страна на клиента. Във вашия случай трябва да отпечатате опции за конкретна държава.
Как скриптът знае за коя държава трябва да избере градове от базата данни? Е, изпращате HTTP заявка с параметър "страна". Това е, което вашият формуляр прави автоматично, когато го изпратите. Всички HTML тагове, които са във формуляра и имат зададен атрибут на име, ще бъдат изпратени в HTTP заявка като параметри. Но тъй като не можете да използвате submit, трябва да направите това ръчно.
Изпращането на параметър в HTTP GET заявка е много лесно. Разгледайте следния url:
localhost/getCities?country=countryX&someOtherParam=something&myThirdParam=something3
От страната на сървъра ще бъдат попълнени следните променливи:
$_GET["country"] // value is 'countryX'
$_GET["someOtherParam"] // value is 'something'
$_GET["myThirdParam"] // value is 'something3'
За да научите повече за това как работят GET и POST и каква е разликата, проверете това
Започнете, като създадете файл getCities.php и копирате и поставите кода, който комуникира с базата данни и генерира опции за град. Това е основно това, което вече сте направили, просто трябва да поставите този код в отделен .php файл. Така че, когато клиент (браузър) поиска списък с градове в определена държава, вие ще изпратите HTTP заявка (използвайки функцията httpGetAsync(), за да получите този списък от сървъра.
Във вашия index.php копирайте и поставете този скрипт
<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>
След това поставете атрибут onchange в полето за избор, не забравяйте, че всичко е с малки букви, а не onChange.
<select name="country" id="country" onchange="httpGetAsync('localhost/getCities?country=' + this.value, populateCities)">
За всякакви въпроси просто попитайте... :)