Chà, những gì bạn thực sự cần là lệnh gọi AJAX cho phép bạn giao tiếp với máy chủ mà không cần tải lại trang. Tất cả những gì bạn phải làm về cơ bản là gửi một yêu cầu HTTP mới với tham số quốc gia để lấy danh sách các thành phố trong đó. Cách chính xác sẽ là chỉ gửi (phản hồi HTTP) dữ liệu (thành phố) ở định dạng JSON hoặc tương tự và không gửi bản trình bày của nó (html), nhưng để đơn giản hơn, bạn có thể tiếp tục làm việc như bạn đã bắt đầu (trả lại dữ liệu bằng html) .
Bắt đầu bằng cách tách mã tạo HTML selectBoxOptions của các thành phố trong một tập lệnh khác. Bạn sẽ sử dụng tập lệnh đó để lấy danh sách các thành phố ở quốc gia cụ thể bằng cách sử dụng AJAX (thư viện XMLHttpRequest).
Hãy xem đây, nó là một giải pháp hiệu quả cho vấn đề của bạn. Yêu cầu HTTP được gửi bất cứ khi nào người dùng thay đổi tùy chọn countrySelectBox, theo cách đó hộp chọn thành phố của bạn được cập nhật bất cứ khi nào nó cần. Tất cả những gì bạn phải làm là thay đổi url trong thuộc tính onchange trỏ đến tập lệnh của bạn (trước đây tôi đã nói rằng bạn nên di chuyển Khối mã thứ 2 thành tập lệnh riêng biệt).
<!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>");
}
?>
CHỈNH SỬA:
httpGetAsync là bản địa (chỉ sử dụng javascript thuần túy / vani. Không sử dụng thư viện khác) hàm javascript cho phép bạn gửi yêu cầu HTTP mà không cần tải lại trang. Tôi thấy bạn đang sử dụng jQuery, tính năng này ẩn độ phức tạp của hàm này, giống như form-> submit, nhưng tôi khuyên bạn nên tìm hiểu cách hoạt động của httpGetAsync, vì sử dụng jQuery cho một tác vụ đơn giản như vậy là quá mức cần thiết.
Bạn không cần hàm javascript này
function getCity(countryId)
Thay vào đó, bạn nên đặt mã giao tiếp với cơ sở dữ liệu trong tệp .php, không phải trong javascript (hãy nhớ rằng, javascript là một phía máy khách, nó thực thi trên máy khách, ví dụ:trình duyệt, trong khi php thực thi trên máy chủ). SQL của bạn không bao giờ được viết bằng javascript. Mã phía máy khách không thể giao tiếp trực tiếp với cơ sở dữ liệu, chỉ thông qua mã phía máy chủ. Để thực hiện điều đó, bạn phải trả lại một giá trị của tập lệnh PHP getCities.php trở lại máy khách (javascript) dưới dạng phản hồi HTTP.
Khi bạn gửi một yêu cầu HTTP đến một số tệp .php, tập lệnh đó thực thi trên máy chủ và mọi thứ mà bạn đã nói "echo" hoặc "print", ở cuối tập lệnh, sẽ được tự động gửi dưới dạng phản hồi HTTP. Bạn không thực sự phải viết bất kỳ mã nào để gửi phản hồi HTTP. Đã hoàn thành tự động của nó. Bạn chỉ cần lặp lại / in bất cứ thứ gì bạn cần ở phía máy khách. Trong trường hợp của bạn, bạn cần phải in các tùy chọn cho quốc gia cụ thể.
Làm thế nào script biết được quốc gia nào nó cần chọn các thành phố từ cơ sở dữ liệu? Chà, bạn gửi yêu cầu HTTP với tham số "country". Đó là những gì bạn Biểu mẫu đang thực hiện tự động khi bạn gửi nó. Tất cả các thẻ HTML bên trong Biểu mẫu và có bộ thuộc tính tên, sẽ được gửi trong yêu cầu HTTP dưới dạng tham số. Tuy nhiên, vì bạn không thể sử dụng submit, bạn phải thực hiện thao tác này một cách thủ công.
Để gửi một tham số bên trong yêu cầu HTTP GET rất đơn giản. Hãy xem url sau:
localhost/getCities?country=countryX&someOtherParam=something&myThirdParam=something3
Ở phía máy chủ, các biến sau sẽ được điền:
$_GET["country"] // value is 'countryX'
$_GET["someOtherParam"] // value is 'something'
$_GET["myThirdParam"] // value is 'something3'
Để tìm hiểu thêm về cách GET và POST hoạt động và sự khác biệt là gì, hãy kiểm tra this
Bắt đầu bằng cách tạo tệp getCities.php và sao chép, dán mã giao tiếp với cơ sở dữ liệu và tạo các tùy chọn thành phố. Về cơ bản, đó là những gì bạn đã làm, bạn chỉ cần đặt mã đó trong tệp .php riêng biệt. Vì vậy, khi một ứng dụng khách (trình duyệt) yêu cầu danh sách các thành phố ở quốc gia cụ thể, bạn sẽ gửi một yêu cầu HTTP (sử dụng hàm httpGetAsync ()) để lấy danh sách đó từ máy chủ.
Trong bản sao index.php của bạn, hãy dán tập lệnh này vào
<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>
Tiếp theo, đặt thuộc tính onchange trên hộp chọn, hãy nhớ rằng, tất cả đều là chữ thường của nó, không phải onChange.
<select name="country" id="country" onchange="httpGetAsync('localhost/getCities?country=' + this.value, populateCities)">
Đối với bất kỳ câu hỏi chỉ cần hỏi ... :)