Si vuole realizzare un form con due caselle di scelta collegate, la prima per scegliere la provincia, la seconda la città. Le due caselle devono essere collegate nel senso che: prima si potrà scegliere la provincia e poi la città, in modo che nella casella a discesa della città la scelta possa avvenire solo fra le città appartenenti alla provincia scelta. A tal scopo il form interagisce con le tabelle “province” e “città” di un database relazionale di nome “anagrafica”, legate dall’associazione 1 a N descritta dal seguente schema E/R:
La pagina web dovrà funzionare così:
- Quando la pagina viene caricata nel browser, nel form dovrà essere visibile solo la casella a discesa della provincia, che dovrà contenere tutte le province presenti nella tabella “province” del database.
- Quando l’utente sceglierà la provincia, nella pagina dovrà comparire anche la casella a discesa della città, che dovrà contenere le sole città presenti nel database appartenenti alla provincia scelta.
(Soluzione proposta – Punto 1)
Il seguente codice risolve il problema del punto 1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<!DOCTYPE html> <html> <body> <?php //si connette al server @ $conn = new mysqli('localhost', 'root', ''); if($conn->connect_errno) die("Connessione al server non riuscita!<br/>"); //seleziona il database anagrafica if(@ !$conn->select_db('anagrafica')) die("Connessione al database 'anagrafica' non riuscita!<br/>"); //1) si procura le province $cmd = "SELECT * FROM province ORDER BY sigla"; $ris = $conn->query($cmd); ?> <form> <b><label>Provincia</label></b><br/> <select name='prov'required> <option value=''>Scegli provincia...</option> <?php //2) carica le province nella casella a discesa della provincia while ($riga = $ris->fetch_assoc()) { echo "<option value='$riga[idProvincia]'>$riga[sigla]</option>"; } ?> </select> </form> <?php $conn->close(); ?> </body> </html> |
La pagina web dopo essersi connessa al database, recupera i record di tutte le province da visualizzare e le carica all’interno della casella di scelta (righe di codice evidenziate in giallo). Per il resto il codice precedente è tutto commentato ed è autoesplicativo.
(Soluzione proposta – Punto 2)
Per la soluzione del punto 2 vale la pena fare alcune osservazioni. Prima che la casella di scelta della città possa essere visualizzata, è necessario interrogare il database per estrarre le città appartenenti alla provincia selezionata dall’utente. Dunque, prima sarà necessario inviare il form per comandare l’esecuzione di questa interrogazione. Ovviamente la pagina PHP verso la quale inviare la richiesta, dev’essere la stessa pagina d’invio (ciò viene ottenuto con: action=”<?php $_SERVER[‘PHP_SELF’] ?>), visto che la casella di scelta delle città dovrà essere visualizzata nella stessa pagina dalla quale parte la richiesta. Infine, per eseguire l’invio del form dopo la scelta della provincia, può essere conveniente utilizzare l’evento onchange sulla casella di scelta della provincia, con il codice Javascript per l’invio del form. Il risultato che si ottiene è il seguente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<!DOCTYPE html> <html> <body> <?php //si connette al server @ $conn = new mysqli('localhost', 'root', ''); if($conn->connect_errno) die("Connessione al server non riuscita!<br/>"); //seleziona il database anagrafica if(@ !$conn->select_db('anagrafica')) die("Connessione al database 'anagrafica' non riuscita!<br/>"); //1a) si procura le province $cmd = "SELECT * FROM province ORDER BY sigla"; $ris = $conn->query($cmd); ?> <form id='modulo' method="POST" action="<?php $_SERVER['PHP_SELF'] ?>"> <b><label>Provincia</label></b><br/> <select name='prov'required onchange="document.getElementById('modulo').submit()"> <option value=''>Scegli provincia...</option> <?php //2a) carica le province nella casella a discesa della provincia while ($riga = $ris->fetch_assoc()) { echo "<option value='$riga[idProvincia]'>$riga[sigla]</option>"; } ?> </select><br/> <?php if(isset($_POST['prov'])) //SE LA PROVINCIA E' STATA GIA' SCELTA { //1b) recupera idProvincia della provincia scelta $idProvincia = $_POST['prov']; //2b) si procura le città appartenenti alla provincia scelta $cmd = "SELECT * FROM citta WHERE idProvincia = '$idProvincia' ORDER BY nome;"; $ris = $conn->query($cmd); ?> <b><label>Città</label></b><br/> <select> <option value=''>Scegli la città...</option> <?php //3b) carica le città nella casella a discesa della città while ($riga = $ris->fetch_assoc()) { echo "<option value='$riga[idCitta]'>$riga[nome]</option>"; } } ?> </select> </form> <?php $conn->close(); ?> </body> </html> |
Miglioriamo la soluzione precedente
La soluzione precedente presenta il difetto che quando la provincia viene scelta, la pagina viene ricaricata e la provincia scelta non viene più visualizzata, così come viene mostrato nella figura seguente:
Il codice precedente potrebbe essere migliorato in modo da continuare a visualizzare la provincia scelta anche quando si sceglie la città:
Per ottenere ciò basta sostituire le righe evidenziate in giallo del codice precedente con le seguenti:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
if(!isset($_POST['prov'])) //se la provincia non è stata ancora inviata, ossia non è stata ancora scelta while ($riga = $ris->fetch_assoc()) { echo "<option value='$riga[idProvincia]'>$riga[sigla]</option>"; } else { //altrimenti (la provincia è stata già scelta) while ($riga = $ris->fetch_assoc()) { //se idProvincia è quello della provincia che risultava selezionata if($riga[idProvincia] == $_POST['prov']) //imposta come selezionata la provincia inviata echo "<option selected value='$riga[idProvincia]'>$riga[sigla]</option>"; else echo "<option value='$riga[idProvincia]'>$riga[sigla]</option>"; } } |