Da quando è venuto alla luce, Ajax ha dimostrato subito il suo potenziale. Il suo stesso nome – acronimo di “Asynchronous Javascript and Xml” – lascia un indizio su cosa è capace di fare: chiamate “asincrone”.
Cosa significa? Ajax è stato progettato per creare applicazioni web interattive, cioè per aggiornare in modo dinamico una pagina web senza che l’utente debba ricaricarla. Una volta chiamata la richiesta, non dobbiamo aspettare che finisca per eseguire altre operazioni. In parole povere, può chiamare pagine php, eseguirle e stampare a video il risultato senza dover ricaricare la pagina.
Il potenziale è enorme. Come sappiamo, il javascript è eseguito lato client (cioè direttamente dal browser dell’utente, tant’è che è possibile far funzionare in locale una pagina html contenente script in javascript, senza bisogno di una connessione internet e di un server apposito), mentre il php è lato server (l’uso corretto in locale è possibile solo attraverso un programma che simuli un server adatto). Per eseguire un codice javascript non serve il caricamento della pagina, mentre il php ha bisogno di inviare i dati al server, elaborarli e rimandarli indietro, mostrandoli solo se la pagina viene ricaricata.
Ajax, quindi, è una vera rivoluzione.
L’unica pecca di questa meraviglia – come sempre – è che il browser deve essere aggiornato per supportarlo, anche se ai nostri giorni qualsiasi browser si prodiga per restare al passo con i tempi e raramente ne incontreremo uno “inabile”.
In questo articolo mostrerò un esempio completo su come far interagire Ajax con il php.
Prenderemo una select contenente le regioni italiane e faremo in modo che, in base al valore scelto, appaia in tempo reale una seconda select prima nascosta, contenente le province della regione. Le province saranno prese da un database, che sarà interrogato tramite php.
Nell’articolo dò per scontato che si abbia una conoscenza delle basi di PHP e di come interagisce con un database di tipo MySQL. Utile sarà anche avere una base di Javascript e di Ajax (anche minima), ma non è indispensabile: ogni parte, infatti, sarà dovutamente commentata in modo che possiate eventualmente approfondire con delle ricerche personali.
Download script
Il database
Nel database ci basteranno solo due tabelle: l’elenco delle regioni italiane e l’elenco delle province, che avranno un campo di join con la tabella delle regioni. Qui sotto i dump delle due tabelle, con alcuni valori inseriti (si tratta di un esempio minimale, lo stretto necessario per capire l’esempio).
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 |
CREATE TABLE IF NOT EXISTS `regioni` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nome` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; INSERT INTO `regioni` (`id`, `nome`) VALUES (1, 'Lazio'), (2, 'Sardegna'), (3, 'Veneto'); CREATE TABLE IF NOT EXISTS `province` ( `id` int(11) NOT NULL AUTO_INCREMENT, `id_regione` tinyint(4) NOT NULL DEFAULT '0', `nome` varchar(50) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=111; INSERT INTO `province` (`id`, `id_regione`, `nome`) VALUES (1, 3, 'Verona'), (2, 3, 'Vicenza'), (3, 3, 'Belluno'), (4, 3, 'Treviso'), (5, 3, 'Venezia'), (6, 3, 'Padova'), (7, 3, 'Rovigo'); |
Il codice html per la select
Fingiamo per un momento che lo script in Ajax sia già stato predisposto e creiamo le componenti della pagina come se fosse fatta semplicemente in php.
Creiamo una pagina index.php
. Lascio a voi il compito di costruire il layout, l’header e il footer. Quello che importa è che, con il php, apriate una connessione con il database in cui avete appena creato le tabelle.
Il corpo della nostra pagina conterrà una select
come questa (ho preparato le classi css, che dovrete occuparvi di formattare a seconda del bisogno):
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<form id="form" class="formquery" action="" method="post" name="form"> <div class="titolo">Scegli la regione</div> <div class="riga"><?php $select = "SELECT * FROM regioni"; $query = mysql_query($select); ?><select id="regione" class="select1" name="regione" onchange="caricaProvince(this.value)"> <?php while($regioni = mysql_fetch_array($query)){ ?><option value="<?=$regioni['id']?>"><?=$regioni['nome']?></option> <?php } ?> </select></div> <div class="titolo">Scegli la provincia</div> <div class="riga" id="provincia"> <?php //nota: qui verrà stampato il contenuto elaborato dal file "carica_province.php" ?> </div> </form> |
In pratica avremo “in chiaro” la select contenente le nostre regioni, prese dalla tabella del database.
La parte contenuta nel div che ha id=”provincia” sarà invece caricata dinamicamente: in base al valore scelto nella prima select, cercheremo le province legate alla regione e le stamperemo qui come una nuova select.
Il file “carica_province.php”
Lo script incaricato di prelevare le province in base alla regione scelta sarà in file php a parte, che chiameremo carica_province.php
.
Il suo contenuto sarà questo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php //qua va il codice per aprire una connessione al db if(isset($_POST['regione'])){ $select = "SELECT * FROM province WHERE id_regione=".$_POST['regione']." order by nome"; $query = mysql_query($select); ?><select id="select_province" class="select1" name="province"> <?php while($province=mysql_fetch_array($query)){ ?><option value="<?=$province['id']?>"><?=$province['nome'] ?></option> <?php } ?> </select> <?php } ?> |
Niente di complicato, è una comunissima pagina php. In base al valore della regione passata, eseguo una query ed estraggo le sue province.
Da notare che, essendo un file esterno al precedente, dobbiamo ripetere lo script in php che apre la connessione con il database.
Poniamo che la regione scelta sia il Veneto. Se stampassimo a video questa pagina come siamo abituati a fare di solito, vedremmo semplicemente una select contenente l’elenco delle province del Veneto; ma avremmo dovuto ricaricare la pagina.
Con Ajax, invece, la select sarà stampata senza ricaricare la pagina, nel div con id=”provincia” che abbiamo visto sopra.
La parte in html è pronta, non c’è altro da aggiungere.
A questo punto occupiamoci del vero “core” dello script: Ajax.
La chiamata ad Ajax
Il mio primo utilizzo di Ajax è stato traumatico, a causa del solito Internet Explorer, che sembrava voler ostacolarmi a tutti i costi. Dopo diversi esperimenti, sono riuscito a trovare uno script ottimale, che uso ormai da diverso tempo senza problemi.
Perché Ajax funzioni anche su Explorer, è necessario includere a inizio pagina questo codice:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<script type="text/javascript" language="javascript">// <![CDATA[ var myRequest = null; function CreateXmlHttpReq(handler) { var xmlhttp = null; try { xmlhttp = new XMLHttpRequest(); } catch(e) { try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } } xmlhttp.onreadystatechange = handler; return xmlhttp; } // ]]></script> |
La funzione CreateXmlHttpReq()
sarà da richiamare ogni volta che dovremo fare uso di Ajax.
Sotto a questa funzione, inserite queste altre due funzioni (al momento ignorate i commenti, li vedremo subito sotto):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<script type="text/javascript">// <![CDATA[ function caricaProvince(valore){ myRequest = CreateXmlHttpReq(appendi_province); //apre la funzione appendi_province myRequest.open("POST","carica_province.php"); //apre carica_province.php e gli indica che i valori passati devono essere considerati POST myRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); //indica che il contenuto di risposta sarà di tipo html-utf8 myRequest.send("regione="+valore); //fa passare $_POST['regione']=valore al file carica_regione.php myRequest.setRequestHeader("connection", "close"); //chiude la connessione ajax } function appendi_province(){ if(myRequest.readyState==4 && myRequest.status==200){ var a=document.getElementById("provincia"); a.innerHTML=""; a.innerHTML=myRequest.responseText; //stampa il contenuto html passato all'interno dell'elemento con id="provincia" $(".select1").selectbox(); //è una funzione fittizia in js che formatta l'aspetto della select (usata solo ai fini dell'esempio) } } // ]]></script> |
Cosa abbiamo fatto?
Ho commentato ogni riga, ma vanno fatte delle precisazioni. Chi è abituato a pensare in modo sincrono (come nel php), dovrà fare uno sforzo.
Una volta aperta la richiesta, Ajax passa attraverso quattro stadi:
1) richiesta aperta, ma i dati non sono ancora stati inviati
2) richiesta (dati) inviata
3) i dati sono ricevuti e comincia la loro lettura
4) operazione completata
Usando l’esempio qui sopra, in sequenza:
* apre la funzione appendi_province()
;
* apre il file carica_province.php
;
* fa passare a carica_province.php
la variabile “regione”: il valore di questa variabile viene fatto passare come parametro della funzione caricaProvince()
. La variabile “regione” è stata fatta passare come post, ma nulla vieta di farla passare come get, apportando le dovute modifiche al file php.
* esegue il cotenuto di carica_province.php, che stamperà l’elenco delle province in una select.
* appendi_province()
viene eseguita quattro volta: una per ogni stato in cui passa l’Ajax (1, 2, 3, 4); poiché ho messo la condizione if(myRequest.readyState==4)
nella funzione, il contenuto html di carica_province.php
verrà mostrato solo al raggiungimento del quarto stadio. Questa funzione immetterà il contenuto html (elenco delle option) nella select con id=”provincia”
* quando appendi_province()
ha finito, chiude la connessione ajax
Notate che, poiché la pagina non viene caricata una volta eseguito lo script, sarà necessario richiamare esplicitamente le eventuali funzioni javascript che vengono applicate sulla select appena fatta comparire. Nell’esempio qui sopra, ho aggiunto la riga:
1 |
$(".select1").selectbox(); |
che formatta con una funzione javascript (più precisamente jquery) tutte le select aventi classe con valore “select1” (cioè entrambe le select che abbiamo creato). Se non l’avessi richiamata, sarebbe stata formatta la select delle regioni, ma non quella delle province. Nel vostro caso questa funzione è utile solo ai fini dell’esempio (a meno che non creiate una funzione js chiamata selectbox()
), per cui potete eliminare la riga.
Ringrazio Michele Mirandola per l’aiuto nella realizzazione dell’articolo
ciao,
ringrazio veramente molto per la soluzione sopra indicata. Mi congratulo per la semplicità delle spiegazioni in un sistema abbastanza complicato. Unica cosa mancante per completare, è il default delle province al primo caricamento della pagina.
Grazie ancora
continuate così.
Ciao Enrico,
fa piacere sapere che hai trovato l’esempio comprensibile, era l’obiettivo che ci eravamo prefissati (visto che, in effetti, l’ajax non è così semplice da seguire, soprattutto per i neofiti).
Tra l’altro hai ragione, non ho messo il default per le province, ma l’html in automatico prenderà la prima della lista.
Ciao mi potresti autare?avrei una pagina dove vorrei visualizzare tutti i valori del database, usando ajax.
Con php è molto semplice,ma vorrei non usare il refresh per visualizzare i nuovi valori che vengono inseriti da altri pc..come potrei fare?grazie!
Ciao Davide,
il procedimento è simile a quello che vedi sopra, però non mi hai detto come vengono mostrati questi valori nel database (ovvero, ci deve essere un “evento” che richiami la funzione ajax, per esempio il click su un pulsante).
Nell’esempio di questo articolo l’evento è dato dal cambio di select: ogni volta che si sceglie una voce diversa della select, viene richiamata la funzione “caricaProvince” (e i suoi risultati sono visualizzati senza ricaricare la pagina, grazie ad Ajax).
Ciao grazie per la risposta!no semplicemente ho una pagina dove vengono visualizzate delle camere che ogni persona dal proprio pc può inserire,nella pagina dove vengono visualizzate, c’e anche la possibilità di modificarle, però proprio quando uno va a modificare e scrivere i dati avviene il refresh che cancella tutto..anche se lo ho impostato per 1 minuto..questo è il problema..vorrei solamente che avvenga un aggiornamento delle camere senza refresh della pagina..tipo le nuove notizie di facebook..grazie!
Invece di usare un pulsante per salvare i dati che immettono (in pratica il pulsante submit del form), potresti usare l’evento “onmouseout”: quando l’utente scrive nel campo di input e poi esce, i dati si salvano in automatico senza bisogno di cliccare su pulsanti o di ricaricare la pagina.
In pratica funziona esattamente come l’onchange che vedi nell’esempio di questo articolo, solo che l’evento da usare è l’onmouseout
Grazie!questo mi sarà utile, però non risolve il mio problema..adesso mi spiego meglio.. ho una pagina dove visualizzo tutte le camere nel database, queste vengono inserite da altri pc..se io sto davanti al pc e un altra persona inserisce una camera nuova, io non la vedrei..per questo ho messo un refresh di un minuto,in modo che tutti i pc siano aggiornati, però il problema del refresh automatico è che se uno scrive nella pagina, viene cancellato tutto..per questo vorrei che le nuove camere si aggiornino senza un refresh di tutta la pagina..vorrei vedere i valori in modo dinamico con ajax..senza nessun pulsante o altro..magari imposto che ajax faccia la richiesta ogni 50 secondi..però non so come fare..grazie ancora
Allora la questione è un po’ più complicata, è come creare una sorta di chat: qualcuno inserisce un testo (aggiunge dati nel database) e gli altri possono vederlo in tempo reale.
Di getto farei così (ma magari esiste un sistema più efficiente): con ajax aggiorno i dati ogni tot secondi, ma devi evitare questo tipo di controllo se l’utente ha il mouse interno al campo di input
Ciao grazie per la risposta!ho risolto così :
setInterval(function() {
$(“#Dati”).load(“Dati.php”);
}, 45000);
Dove Dati.php contiene la query che estrae i dati dal database, così facendo ho eliminato il refresh, e i dati si aggiornano da soli ogni 45 secondi! Ho postato nel caso servisse a qualcuno..ho visto parecchie domande come la mia..grazie a tutti ugualmente
Mancava questo :
<div id="Dati
Ottimo, non si sa mai che sia utile a qualcuno in futuro 🙂
Ciao Manual ti espongo questo dilemma sto usando una chiamata asincrona tra Ajax e Php vedo che hai creato un tutoria di base, il mio scopo e di utilizzare Ajax per far si che l’utente inserisca in un determinato form di continuo i dati e quando l’utente clicca su salva la form non si chiude ma si ripropone vuota per poi poter inserire nuovamente i dati.
Premetto funziona tutto tranne una piccola cosa i campi come radio e checkbox ajax non riesce a inviarli al file .php dove quest’ultimo li andrà a salvare nel database.
Ti allego lo script:
$(document).ready(function() {
//al click sul bottone del form
$(“#bottone”).click(function(){
//associo variabili
var attivo = $(“#attivo”).val();
var ragionesociale = $(“#ragionesociale”).val();
var partita_iva = $(“#partita_iva”).val();
var codice_fiscale = $(“#codice_fiscale”).val();
var privato = $(“#privato”).val();
var id_vettore = $(“#id_vettore”).val();
var id_tipo_pagamenti = $(“#id_tipo_pagamenti”).val();
var data = $(“#data”).val();
var indirizzo = $(“#indirizzo”).val();
var comune = $(“#comune”).val();
var provincia = $(“#provincia”).val();
var cap = $(“#cap”).val();
var nazione = $(“#nazione”).val();
var findirizzo = $(“#findirizzo”).val();
var fcomune = $(“#fcomune”).val();
var fprovincia = $(“#fprovincia”).val();
var fcap = $(“#fcap”).val();
var fnazione = $(“#fnazione”).val();
var telefono = $(“#telefono”).val();
var fax = $(“#fax”).val();
var celprivato = $(“#celprivato”).val();
var email = $(“#email”).val();
var pec = $(“#pec”).val();
var web = $(“#web”).val();
//chiamata ajax
$.ajax({
//imposto il tipo di invio dati (GET O POST)
type: “POST”,
//Dove devo inviare i dati recuperati dal form?
url: “insert_conf.php”,
//Quali dati devo inviare?
data: “ragionesociale=” + ragionesociale + “&partita_iva=” + partita_iva + “&attivo=” + attivo + “&privato=” + privato + “&privato=” + privato + “&codice_fiscale=” + codice_fiscale
+ “&codice_fiscale=” + codice_fiscale + “&id_vettore=” + id_vettore + “&id_tipo_pagamenti=” + id_tipo_pagamenti + “&data=” + data + “&indirizzo=” + indirizzo + “&comune=” + comune + “&provincia=” + provincia
+ “&cap=” + cap + “&nazione=” + nazione + “&findirizzo=” + findirizzo + “&fcomune=” + fcomune + “&fprovincia=” + fprovincia + “&fcap=” + fcap + “&fnazione=” + fnazione + “&telefono=” + telefono + “&fax=” + fax
+ “&celprivato=” + celprivato + “&email=” + email + “&pec=” + pec + “&web=” + web,
dataType: “html”,
//Inizio visualizzazione errori
success: function(msg)
{
$(“#risultato”).html(msg); // messaggio di avvenuta aggiunta valori al db (preso dal file risultato_aggiunta.php) potete impostare anche un alert(“Aggiunto, grazie!”);
},
error: function()
{
alert(“Chiamata fallita, si prega di riprovare…”); //sempre meglio impostare una callback in caso di fallimento
}
});
});
});
il problema è nel campo attivo che usa il checkbox e privato che usa il radio.
Grazie per l’attenzione
Ciao Giuseppe,
le checkbox e le radio passano il valore soltanto quando sono selezionate; quando non sono selezionate il form non ti invia il loro valore (proprio non le vede, per cui recuperare il loro valore è impossibile).
La cosa migliore da fare è controllare con JQuery se la checkbox (o la radio) è selezionata, in questo modo:
if ($(‘#privato’).prop(“checked”)) { … }
Vedi: http://api.jquery.com/prop/
Buona sera, chiedo scusa, immagino che il blog sia ancora attivo, ho un problema di interazione tra ajax e php in un semplicissimo sito e prima di inondarvi di codici, chiedo se posso chiedere una mano.
Grazie per eventuali risposte.
Ciao Domenico,
se è un dubbio di procedimento, riporta pure la riga che non ti è chiara. Tempo permettendo io o qualcuno che legge il commento vedremo di darti una mano.
Buona sera grazie, innanzitutto grazie per avermi risposto.
Vado subito al dunque, ho creato varie pagine che poi mi richiamo con ajax e php e funziona tutto bene, però guardando il suo esempio, ho pensato se c’è un modo per riunire tutte insieme le pagine, ho letto del jonin ma non ci ho capito molto.
Cioè caricare un solo file php che contiene tutti contenuti delle singole pagine e con il link a richiamare solo quella associata appunto al link. Grazie ancora e saluti. Domenico
Dipende molto da come vuoi struttura il codice, non esiste un metodo unico e “giusto” per farlo. Diciamo che in linea generale possono bastare due file php:
– pagina1: contiene il codice di partenza, per intenderci quello che l’utente vede aprendo la pagina (form, pulsanti, ecc.). Questo file ha anche il codice per la chiamata ajax.
– pagina2: contiene il codice che modifica l’aspetto della pagina dopo la chiamata ajax.
Questi sono i due file essenziali, per il resto puoi strutturarli come più preferisci.