Laborator 10. AJAX

Responsabil: Popovici Matei <pdmatei@gmail.com>
Data publicarii: xx-04-2009
Data ultimei modificari: 29-04-2009

Introducere

In general, pentru obtinerea de informatii din baza de date, sau pentru a comunica cu serverul, folosim un formular. Trimitem informatiile cu una din metodele GET sau POST si apoi asteptam raspunsul serverului, in final primim noua pagina cu rezultate, care este incarcata de browser.

Serverul intoarce o noua pagina, de fiecare data cand utilizatorul realizeaza un input, ceea ce face ca aplicatiile web sa fie mai putin user-friendly, si sa ruleze mai greu.

Folosind AJAX (Asynchronous JavaScript And XML), putem comunica direct cu serverul, prin intermediul unui obiect (JavaScript) XMLHttpRequest. Acest obiect esentialmente realizeaza o cerere HTTP catre o pagina, si primeste un raspuns, FARA a reincarca pagina. Utilizatorul ramane pe aceeasi pagina, iar mecanismul de transmitere/primire informatii este transparent pentru el.

Modalitatea de implementare


Pasul 1: Crearea obiectului-cerere HTTP


Componenta de baza asociata cu AJAX este obiectul XMLHttpRequest. Acest obiect este creat in moduri diferite de browsere. Spre exemplu, Internet Explorer foloseste un obiect ActiveXObject, in vreme ce restul browserelor (FireFox, Opera, Safari) folosesc XMLHttpRequest.

Ca o precizare, ActiveXObject, primeste parametrii diferiti, in functie de versiunea de Internet Explorer folosita. Pentru browsere IE5.5 (si versiuni mai noi), creem obiectul astfel:

xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");

iar pentru browsere IE6.0 (si versiuni mai noi) folosim:

xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");


Pasul 2: Stabilirea proprietatilor (parametrilor) obiectului

Obiectul XMLHttpRequest are cateva proprietati importante. Una dintre ele este onreadystatechange. Aceasta proprietate stocheaza functia apelata la primirea unui raspuns de la server. Exemplu:

xmlHttp.onreadystatechange=function()

{
//TODO: cod specific la schimbarea starii obiectului

}

Proprietatea readyState retine starea in care se afla obiectul cerere. De fiecare data cand aceasta stare se modifica, functia din onreadystatechange se (re)apeleaza. Valorile pentru starile posibile sunt:


- 0 : cererea nu a fost initializata (obiectul request a fost creat, insa metoda open (prezentata mai jos) nu a fost apelata)

- 1 : cererea a fost initializata (obiectul request a fost creat, insa metoda send (prezentata mai jos) nu a fost apelata)

- 2 : cererea a fost trimisa (a fost apelat send, insa statusul cererii nu este inca disponibil)

- 3 : cererea este in curs de procesare (o parte a raspunsului a fost primita, insa nu integral; apelul proprietatii responseText (prezentata mai jos) va produce o eroare)

- 4 : cererea este completa (si s-a primit un raspuns integral).


Daca dorim sa executam cod la momentul efectiv al primirii raspunsului (pentru cererea noastra HTTP), vom scrie:

xmlHttp.onreadystatechange=function()

{

if(xmlHttp.readyState==4)

{

// TODO: cod tratare raspuns la cerere HTTP

}

}

Proprietatea responseText contine raspunsul primit de la server. (In cazul nostru, responseText este efectiv output-ul scriptului catre care trimitem cererea HTTP)


Putem accesa aceasta proprietate astfel:


xmlHttp.responseText


Pas 3: Trimiterea efectiva a cererii


Pentru trimiterea unei cereri catre server, folosim functiile open si send.

Functia open deschide o conexiune HTTP. Ea primeste trei parametrii. Primul este metoda prin care dorim sa trimitem cererea (GET sau POST). Al doilea parametru este URL-ul (script-ul) catre care trimitem cererea. Al treilea argument specifica faptul ca cererea trebuie tratata asincron.

Functia send realizeaza trimiterea efectiva.

Exemplu:


xmlHttp.open("GET","time.php",true);

xmlHttp.send(null);


Observatii


AJAX nu este altceva decat un mecanism de comunicare cu serverul, fara necesitatea de a reincarca pagina curenta.

Asadar, datele "de intrare" (cele care trebuie trimise serverului), trebuie obtinute folosind JavaScript (recuperand continutul unui INPUT dintr-un formular, de exemplu).

Folosind metoda get, putem realiza o trimitere astfel:


var params = "id=5&user=mike";

var url = "time.php?"+params;


xmlHttp.open("GET",url,true);

xmlHttp.send(null);


Daca dorim sa folosim metoda POST, trebuie sa adaugam informatii in header-ul cererii:


var params = "id=5&user=mike";

var url = "time.php";


xmlHttp.open("GET",url,true);


xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

xmlHttp.setRequestHeader("Content-length", params.length);

xmlHttp.setRequestHeader("Connection", "close");


xmlHttp.send(params);


Formatarea parametriilor este aceeasi, insa acestia fac parte din corpul mesajului HTTP de trimis.


Datele primite de la server (script), trebuie de asemenea tratate folosind JavaScript (asa cum am aratat anterior).


Task-uri:

Task 1: scrieti un script care populeaza un combo-box cu categorii. Aceste categorii le extrageti din tabelul Categories. Combo-box-ul trebuie sa contina TOATE categoriile.

2p


Task 2: In momentul selectarii unei categorii, populati un camp Input, cu numele copiilor categoriei selectate. Folositi Ajax.

8p


Task 3: In momentul selectarii unei categorii, creati dinamic (folosind JavaScript) un nou combo-box, care sa contina copii categoriei. (Textul afisat este numele categoriei, iar valorile sunt id-urile acestora).

Atentie la gestionarea combo-ului dinamic (daca el exista deja, trebuie re-creat, sau modificat)

4p


Hint-uri:

- pentru a accesa componenta (input-ul) cu atributul name="myName" dintr-un formular (de asemenea cu numele name="myForm"), puteti folosi:

document.myForm.myName


- pentru a accesa vectorul de optiuni al unui select (cu name="mySelect"), puteti folosi:

document.myForm.mySelect.options


- puteti parcurge acest vector astfel:

for (i=0; i<document.myForm.mySelect.options.length; i++)

{

//pentru stergere

document.myForm.mySelect.options.remove(i);

//pentru acces (afisare)

var opt = document.myForm.mySelect.options[i];

alert(opt.text+" "opt.value);

}


- pentru a crea o optiune noua:

//creeaza efectiv un element

var option = document.createElement("OPTION");

option.text = ...;

option.value = ...;

//leaga elementul creat de structura HTML existenta (copil al elementului SELECT)

document.myForm.mySelect.add(option);


- pentru a crea un tag nou (oarecare) folositi:

var tag = document.createElement("<nume tag>"); // poate fi div, span,f ont, etc

document.myForm.appendChild(tag); //tagul nou creat devine copil al tagului cu numele myForm (si este continut de acesta)


- pentru a parsa continutul responseText, folositi functia split, functioneaza asemanator cu explode: plecand de la un string, creeaza

un vector, separand string-ul dupa un caracter separator;

exemplu:

var myArray = xmlHttp.responseText.split(":");