Eh bien, ce dont vous avez vraiment besoin, c'est d'un appel AJAX qui vous permet de communiquer avec le serveur sans recharger une page. Tout ce que vous avez à faire est d'envoyer une nouvelle requête HTTP avec un paramètre de pays pour obtenir la liste des villes qu'elle contient. La bonne façon serait d'envoyer (réponse HTTP) uniquement les données (villes) au format JSON ou similaire, et non sa présentation également (html), mais pour plus de simplicité, vous pouvez continuer à travailler comme vous avez commencé (renvoyer les données avec html) .
Commencez par séparer le code qui génère HTML selectBoxOptions des villes dans un autre script. Vous utiliserez ce script pour obtenir la liste des villes d'un pays particulier en utilisant AJAX (bibliothèque XMLHttpRequest).
Jetez un oeil à ceci, c'est une solution de travail de votre problème. La requête HTTP est envoyée chaque fois que l'utilisateur modifie l'option countrySelectBox, de cette façon votre boîte de sélection de villes est mise à jour chaque fois qu'elle en a besoin. Tout ce que vous avez à faire est de changer l'url dans l'attribut onchange qui pointe vers votre script (j'ai déjà dit que vous devriez déplacer 2ème bloc de code dans un script séparé).
<!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>");
}
?>
MODIFIER :
httpGetAsync est une fonction javascript native (seul le javascript pur/vanilla est utilisé. Aucune autre bibliothèque n'est utilisée) qui vous permet d'envoyer une requête HTTP sans recharger une page. Je vois que vous utilisez jQuery, qui masque la complexité de cette fonction, comme form->submit, mais je vous recommande d'apprendre comment fonctionne httpGetAsync, car utiliser un jQuery pour une tâche aussi simple est exagéré.
Vous n'avez pas besoin de cette fonction javascript
function getCity(countryId)
Au lieu de cela, vous devez mettre votre code qui communique avec la base de données dans un fichier .php, pas en javascript (rappelez-vous que javascript est un côté client, il s'exécute sur la machine cliente, par exemple le navigateur, tandis que php s'exécute sur le serveur). Votre SQL ne doit jamais être écrit en javascript. Le code côté client ne peut pas communiquer directement avec une base de données, uniquement via le codage côté serveur. Pour ce faire, vous devez renvoyer une valeur du script PHP getCities.php au client (javascript) en tant que réponse HTTP.
Lorsque vous envoyez une requête HTTP à un fichier .php, ce script s'exécute sur un serveur, et tout ce que vous avez dit "echo" ou "print", à la fin du script, est automatiquement envoyé en tant que réponse HTTP. Vous n'avez pas besoin d'écrire de code pour envoyer une réponse HTTP. C'est fait automatiquement. Il vous suffit de faire écho/imprimer tout ce dont vous avez besoin côté client. Dans votre cas, vous devez imprimer des options pour un pays particulier.
Comment le script sait-il pour quel pays il doit sélectionner les villes de la base de données ? Eh bien, vous envoyez une requête HTTP avec un paramètre "pays". C'est ce que votre formulaire fait automatiquement lorsque vous le soumettez. Toutes les balises HTML qui se trouvent à l'intérieur du formulaire et dont l'attribut name est défini seront envoyées dans une requête HTTP en tant que paramètres. Mais, puisque vous ne pouvez pas utiliser submit, vous devez le faire manuellement.
Envoyer un paramètre dans la requête HTTP GET est très simple. Jetez un œil à l'url suivante :
localhost/getCities?country=countryX&someOtherParam=something&myThirdParam=something3
Côté serveur, les variables suivantes seront renseignées :
$_GET["country"] // value is 'countryX'
$_GET["someOtherParam"] // value is 'something'
$_GET["myThirdParam"] // value is 'something3'
Pour en savoir plus sur le fonctionnement de GET et POST, et quelle est la différence, consultez ceci
Commencez par créer un fichier getCities.php et copiez-collez le code qui communique avec la base de données et génère des options de ville. C'est essentiellement ce que vous avez déjà fait, il vous suffit de mettre ce code dans un fichier .php séparé. Ainsi, lorsqu'un client (navigateur) demande une liste de villes dans un pays particulier, vous allez envoyer une requête HTTP (en utilisant la fonction httpGetAsync()) pour obtenir cette liste du serveur.
Dans votre index.php copiez collez ce 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>
Ensuite, mettez l'attribut onchange sur la case de sélection, rappelez-vous, c'est tout en minuscules, pas onChange.
<select name="country" id="country" onchange="httpGetAsync('localhost/getCities?country=' + this.value, populateCities)">
Pour toute question, il suffit de demander... :)