In giro si trovano una marea di ottimi fremework AJAX che permettono di fare cose strabilianti nelle nostre pagine web. Io personalmente, ho usato ed uso in qualche applicazione la libreria prototype.lite associata alle moo.fx. Veramente ottima se quello che si cerca è la facilità d’uso e la leggerezza di codice.
Per chi volesse una soluzione completa, oltre la mega libreria di Yahoo, tempo fa Massimiliano Cuccia mi segnala Dojo Toolkit.
Ma a me piacciono le cose fatte in casa. Non perchè pretendi di essere migliore dei testoni che sviluppano ottimo codice, semplicemente perchè mi piace sentire le cose mie, ed anche perchè per piccoli progetti forse è meglio scriversi tutto da se per evitare il più possibile di perdere il controllo.
Per questo oggi vi propongo una sorta di driver AJAX. Una funzione costruita i modo tale da rappresentare una valida chiamata asincronica in ogni parte dell’applicazione web.
Basta includere il codice in un file .js e richiamarlo nei tag del head nelle pagine in cui risulterà utile (o più facilmente in tutta l’applicazione).
Cominciamo con il vedere come avviare l’handler in base al browser del client.
var myReq = null;
function AJAXReq(methodtype,url,asynch,resp){
if(window.XMLHttpRequest){
myReq = new XMLHttpRequest();
}else if(window.ActiveXObject){
myReq = new ActiveXObject("Msxml2.XMLHTTP");
if(!myReq){
myReq = new ActiveXObject("Microsoft.XMLHTTP");
}
}
if(myReq){
if(methodtype.toLowerCase() != "post"){
execfunc(methodtype,url,asynch,resp);
}else{
var args = arguments[4];
execfunc(methodtype,url,asynch,resp,args);
}
}else{
alert("Your browser doesn’t support AJAX utilities");
}
}
Abbiamo già visto un codice simile. E sappiamo già che se il browser supporta AJAX (via XMLHttpRequest o Activex che sia) andremo ad eseguire execfunc.
Ma già qui introduciamo una novità. Inseriamo un ciclo IF che controlla se la richiesta è in GET o POST. Se la richiesta è GET i parametri sono passati via URL e non abbiamo bisogno di inviare niente se non la richiesta vera e propria. In caso contrario, il POST dovrà portare con se le variabili relative. Per questo nel caso di una chiamata in POST la funzione execfunc avrà un argomento in più.
Ed andiamola a vedere.
function execfunc(methodtype,url,asynch,resp){
try{
myReq.onreadystatechange = resp;
myReq.open(methodtype,url,asynch);
if(methodtype.toLowerCase() == "post"){
myReq.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");
myReq.send(arguments[4]);
}else{
myReq.send(null);
}
}catch(errv){
alert("Enable to contact the server\nError: "+errv.message);
}
}
[MORE]
Anche qui introduciamo un ciclo di controllo per la tipologia di richiesta. Nel caso di una richiesta in POST andremo a settare un giusto header ed inviare con un send() i dati dell’argomento della richiesta. In caso contrario possiamo lasciare in default l’header e l’invio dei dati non avverrà con la funziona send() (come detto verranno passati tramite URL).
Praticamente è tutto qui. Basterà poi scrivere la funzione di risposta, che se vogliamo agisca a richiesta terminata ed andata a buon fine, sarà simile alla seguente:
function handleResponse(){
if(myReq.readyState == 4 && myReq.status == 200){
/*DO SOMETHING*/
}
}
Come usarla?
Abbastanza semplice. Scriveremo una stringa del genere.
AJAXReq(‘GET’,’inner.php’,true,handleResponse);
Ma possiamo anche scrivere la funzione di risposta direttamente nel richiamo
AJAXReq(‘GET’,’inner.php’,true,function (){/*do something*/});
Non è stilisticamente il massimo, ma per piccole cose potrebbe anche andar bene.
Altro metodo d’uso è quello di scrivere una funzione che all’interno includa le direttive AJAX. Metodo da utilizzare quando l’evento (onclick, onmouseup o quello che è) prevede movimentazioni complesse.
function funzioneComplessa(){
//CodiceTeorico
//CodiceTeorico
AJAXReq(‘GET’,’inner.php’,true,function (){handleResponse(‘parametri’)});
//AltroCodice
}
Non dimentichiamo di preparare i dati in post!
Per le richieste in post, dobbiamo inviare dei dati precisi! Possiamo scriversi ad uno ad uno dentro la funzione, in questo modo.
AJAXReq(‘POST’,’inner.php’,true,function (){handleResponse(‘target’)},dato=dato&dato1=dato1);
Oppure più semplicemente utilizzare la funzione vista in questo articolo che si occuperà di preparare una stringa adeguata all’invio dei dati.
function PreparaDati(){
stringa = "";
var form = document.forms[0];
var numeroElementi = form.elements.length;
for(var i = 0; i < numeroElementi; i++){
if(i < numeroElementi-1){
stringa += form.elements[i].name+"="+encodeURIComponent(form.elements[i].value)+"&";
}else{
stringa += form.elements[i].name+"="+encodeURIComponent(form.elements[i].value);
}
}
}
Ed allora potremmo scrivere una funzione del genere.
function Funz(){
PreparaDati();
AJAXReq(‘POST’,’inner.php’,true,function (){handleResponse(‘target’)},stringa);
}
Ovviamente non dobbiamo perdere di vista determinati nomi di variabili, come in questo caso "stringa" o in generale per l’handler considerato "myReq" (o quello che sceglierete voi). Di fatto diventano nomi di variabili non riutilizzabili.
E come sempre, un piccolo esempio, da cui poter prelevare il js 😉
Correggi il titolo 🙂
ooooopz, fatto, grazie! 🙂
come si aggiunge un loader?
Lo spiego qui: http://www.davidonzo.com/post/649/ajax-creare-un-loader-grafico/
Utilizzando lo script su due form va tutto bene, ma su un terzo la funzione execfunc mi riporta la popup con l'errore su ogni browser, e di conseguenza lo script non lavora come dovrebbe. A cosa può essere dovuto? Grazie.