Sunteți pe pagina 1din 125

See discussions, stats, and author profiles for this publication at: https://www.researchgate.

net/publication/310846228

Bazele proiectarii si implementarii aplicatiilor WEB

Book · November 2016

CITATIONS READS

0 791

1 author:

Liviu Serbanescu
Hyperion University
31 PUBLICATIONS   33 CITATIONS   

SEE PROFILE

Some of the authors of this publication are also working on these related projects:

Development of software applications for business analysis View project

All content following this page was uploaded by Liviu Serbanescu on 27 November 2016.

The user has requested enhancement of the downloaded file.


BAZELE PROIECTĂRII ŞI IMPLEMENTĂRII APLICAŢIILOR WEB
Procesare computerizată a textului şi imaginii
Postprocesare şi editare grafică: LIVIU ŞERBĂNESCU
Tehnoredactare: LIVIU ŞERBĂNESCU
Redactor: Cerasela POSTOLACHE

Editura Fair Partners


tel./fax: 021.346.05.23
e-mail: editura@fairpartners.ro
http://www.fairpartners.ro

Fair Partners este editură acreditată de C.N.C.S.I.S.

Descrierea CIP a Bibliotecii Naţionale a României


ŞERBĂNESCU, LIVIU
Bazele proiectării şi implementării aplicaţiilor WEB / Liviu
Şerbănescu. - Bucureşti : Fair Partners, 2016
Conţine bibliografie
ISBN 978-606-718-013-8

004.738.5
Liviu ŞERBĂNESCU

BAZELE PROIECTĂRII ŞI IMPLEMENTĂRII


APLICAŢIILOR WEB

Editura Fair Partners


Bucureşti, 2016
MANUALE. TRATATE. MONOGRAFII (VOL. 147)

Editor-şef:
prof. univ. dr. Mihai POSTOLACHE
Universitatea ,,Politehnica” din Bucureşti

Referent:
prof. univ. dr. Albeanu GRIGORE
Universitatea Europei de Sud-Est Lumina

©2016 Editura FAIR PARTNERS


Toate drepturile asupra acestei ediţii sunt rezervate editurii FAIR PARTNERS. Nicio
parte din acest volum nu poate fi copiată, prin niciun mijloc, fără acordul scris al
editurii FAIR PARTNERS.
Această carte prezintă o scurtă introducere în dezvoltarea aplicațiilor
WEB, urmată de un studiu de caz pentru realizarea unei hărți de dispersie a
poluării, prin utilizarea programării în javascript, a funcțiilor grafce din HTML5
și a framework-ului qooxdoo.
Este prezentată conectarea la bazele de date prin utilizarea PHP și a
tehnicii Remote Procedure Call, iar apoi este prezentat un mic exemplu privind
conectarea unei interfețe WEB, ce utilizează framework-ul qooxdoo, la un server
de baze de date PostgreSQL. Este prezentat și un exemplu de dezvoltare a unei
aplicații WEB, exemplu ce cuprinde fazele de analiză, proiectare și implementare.
Aplicația prezentată este realizată prin utilizarea obiectelor JavaScript din cadrul
framework-ului qooxdoo .
 
CUPRINS

I.Introducere............................................................................................................... 4
1.Etape în dezvoltarea aplicațiilor software............................................................4
1.1.Analiza...............................................................................................................................5
1.2.Proiectarea.........................................................................................................................5
1.3.Implementarea (dezvoltarea codului sursă)................................................................5
1.4.Testarea..............................................................................................................................5
1.5.Mentenanța.......................................................................................................................5
2.Modele de dezvoltare a software-ului...................................................................5
2.1.Modelul în cascadă...........................................................................................................6
2.2.Modelul incremental........................................................................................................6
2.3.Modelul prototip...............................................................................................................7
2.4.Modelul în spirală............................................................................................................7
II.Implementarea aplicațiilor pe partea de client..................................................9
1.Noțiuni introductive HTML....................................................................................9
1.1.Structura HTML...............................................................................................................9
1.2.Legături între pagini........................................................................................................9
1.3.Liste în HTML................................................................................................................10
1.4.Tabele în HTML.............................................................................................................10
1.5.Formulare în HTML......................................................................................................12
2.Introducere în limbajul JavaScript.......................................................................16
2.1. Convenții de sintaxa....................................................................................................16
2.2.Adăugarea JavaScript într-o pagina HTML.............................................................17
2.3.Variabile...........................................................................................................................18
2.4. Operatori........................................................................................................................18
2.5.Operatorul typeof...........................................................................................................19
2.6.Instrucțiuni condiționale..............................................................................................20
2.7.Instrucțiuni ciclice.........................................................................................................22
2.8.Funcții JavaScript...........................................................................................................25
3. Despre obiectele JavaScript.................................................................................26
3.1.Obiecte JavaScript predefnite.....................................................................................27
3.2.Modelul Obiectului Document (DOM)......................................................................28
3.3.Obiecte de nivel 3 și 4...................................................................................................28
4.Evenimente JavaScript...........................................................................................33
5.Cookie-uri.................................................................................................................34
6.Obiecte defnite de utilizator în JavaScript........................................................35
6.1.Defnire obiecte prin utilizarea funcțiilor.................................................................35
6.2.Obiecte defnite literal...................................................................................................36
6.3.Obiecte ce utilizeză mecanismul singleton...............................................................37
6.4.Constructori în JavaScript............................................................................................37
6.5.Moștenirea în JavaScript..............................................................................................38
6.6.Specifcatori de acces....................................................................................................40
6.7.Date și funcții de tip static...........................................................................................41
III.Implemementarea aplicațiilor pe parte de server - Noțiuni introductive
PHP............................................................................................................................ 42
1.Variabile PHP...........................................................................................................43
1.1.Tipuri de variabile..........................................................................................................44
1.2.Variabile predefnite......................................................................................................46
1.3.Vizibilitatea variabilelor................................................................................................47
1.4.Variabile statice..............................................................................................................47
1.5.Variabile referință..........................................................................................................48
1.6.Funcții de tipul typeof...................................................................................................48
2.Funcții în php...........................................................................................................50
2.2.Valorile returnate de funcţii.........................................................................................51
2.3.Numere aleatoare...........................................................................................................52
2.4.Funcția de rotunjire.......................................................................................................52
3.Instrucţiuni de decizie............................................................................................53
3.1.Instrucţiunea if...............................................................................................................53
3.2.Instrucţiunea switch......................................................................................................54
4.Implementarea structurilor repetitive (ciclice)..................................................57
4.1. Implementarea structurilor ciclice cu test iniţial - Instrucţiunea for.................57
4.2.Implementarea structurilor ciclice cu test iniţial - Instrucţiunea while..............58
4.3.Implementarea structurilor ciclice cu test fnal - Instrucţiunea do while...........59
4.4.Instrucţiunile break și continue..................................................................................59
5.Lucrul cu șiruri........................................................................................................60
6.Sesiuni PHP..............................................................................................................61
IV.Introducere în transferul de date client-server...............................................63
1.Preluarea datelor din formularele HTML..........................................................63
1.1.Verifcarea datelor introduse în formular..................................................................63
2.Conexiunea cu bazele de date (conexiunea cu PostgreSQL)..........................64
3.Noțiuni introductive despre AJAX......................................................................67
3.1.Metode din cadrul obiectului XMLHtpRequest......................................................68
3.2.Exemplu...........................................................................................................................69
V.Exemplu privind accesarea bazelor de date PostgreSQL din cadrul
framework-ului qooxdoo......................................................................................... 72
1.Dezvoltarea pe partea de server - dezvoltarea claselor PHP în vederea

2
comunicației prin RPC...............................................................................................72
2.Dezvoltarea pe partea de client – dezvoltarea interfeței prin utilizarea
claselor qooxdoo..........................................................................................................76
2.1.Noțiuni introductive privind crearea scheletului unei aplicații qooxdoo...........77
2.2.Descrierea codului aplicației ”untabelpg”.................................................................77
VI.Aplicație – Construcția unei hărți pentru dispersie......................................85
1.Formulare cerințe....................................................................................................85
2.Analiza aplicației.....................................................................................................85
2.1.Preluarea și mixarea celor două imagini...................................................................85
2.2.Preluarea datelor din fșierul de tip log – aplicație de tip desktop.......................85
2.3.Preluarea datelor din fșierul de tip log – aplicație de tip WEB...........................86
3.Proiectarea aplicației..............................................................................................86
3.1.Diagrama de secvență...................................................................................................88
3.2.Diagrama de colaborare................................................................................................89
3.3. Diagrama activităților..................................................................................................89
3.4.Diagrama stărilor...........................................................................................................91
4.Implementarea aplicației.......................................................................................92
4.1.Clasa ”dsp.Application”................................................................................................92
4.2.Clasa ”dsp.wharta”.........................................................................................................92
4.3.Clasa ”dsp.wsharta”.....................................................................................................100
4.4.Clasa ”dsp.wdharta”....................................................................................................107
5.Testarea aplicației..................................................................................................111
Bibliografe.............................................................................................................. 112
ANEXE.................................................................................................................... 113
Operatori javascript/php..........................................................................................113
Harta obținută............................................................................................................115

3
I.Introducere

I. Introducere
Ingineria aplicațiilor aplică principiile și tehnicile din informatică,
inginerie, și analiză matematică în proiectarea, dezvoltarea, testarea și evaluarea
sofware-ului dezvoltat.
În ingineria dezvoltării aplicațiilor se utilizează unelte specializate în
analiza, proiectarea, dezvoltarea și testarea aplicațiilor, în scopul măririi
productivității. Acestea sunt cunoscute sub acronimul C.A.S.E. (Computer Aided
Sofware Engineering).
Printre obiectivele ingineriei dezvoltării aplicațiilor putem menționa:
➔ Mentenabilitatea - ușurința cu care pot fi realizate modifcări într-o unitate
funcțională, cu scopul de a fi îndeplinite anumite cerințe prescrise;
➔ Corectitudinea - măsura în care sofware-ul îndeplinește cerințele sale
specifce;
➔ Reutilizabilitatea - măsura în care un modul de cod poate fi utilizat în mai
multe aplicații;
➔ Testabilitatea - măsura în care sofware-ul poate fi testat și evaluat;
➔ cu privire la aceste criterii.
➔ Fiabilitatea - măsura în care un sofware își îndeplinește corect funcțiile
pentru care a fost proiectat;
➔ Portabilitatea - ușurința cu care sofware-ul poate fi portat pe un alt
echipament de calcul sau mediu de lucru;
➔ Adaptabilitatea - ușurința cu care sofware-ul permite noi modifcări
rezultate din noi cerințe ale clientului.

Etapele din cadrul ingineriei dezvoltării aplicațiilor WEB sunt


aproximativ aceleași cu cele pentru dezvoltarea aplicațiilor de tip DESKTOP. În
domeniul aplicațiilor WEB este necesară o atenție sporită pentru secțiunea de
securitate a aplicației. În plus, secțiumea de testare se realizează pe mai multe
browsere, în timp ce aplicațiile de tip desktop se testează pe un singur sistem de
operare. În cazul aplicațiilor de tip cross-platform, compilarea fnală se realizează
pe platforme diferite.

1. Etape în dezvoltarea aplicațiilor software


Aceste etape sunt date de ciclul de dezvoltare al produsului software
(SDLC - Sofware Development Life Cycle) .
Fiecare fază produce rezultatele preconizate, solicitate de următoarea fază
din ciclul de viață. Cerințele sunt traduse în proiectare. Codul este produs
conform proiectului care se numește faza de dezvoltare/implementare. După
codifcare urmează testarea în raport cu cerințele defnite în etapa de analiză.

4
1 . E t a p e î n d e z v o l t a r e a a p l i c a ț i i l o r s o f tw a r e

După ce aplicația începe a fi utilizată urmează faza de mentenanță.


1.1. Analiza
Această fază este realizată de managerii de proiect în colaborare cu
clienții. În această etapă se răspunde la întrebări precum: Este oportună
dezvoltarea aplicației? Cine va utiliza sistemul? Cum vor utiliza sistemul? Care
sunt datele de intrare în sistem? Care sunt datele de ieșire din sistem? Care sunt
restricțiile?
După colectarea datelor și găsirea răspunsurilor, acestea vor fi validate de
managerul de proiect și clienți și se va constitui CAIETUL DE SARCINI.
1.2. Proiectarea
Dacă faza de Analiză îşi propunea să determine ce trebuie făcut, faza de
Proiectare trebuie să arate cum trebuie făcut. În această fază sunt proiectate
funcţionalităţile pe care viitorul sistem va trebui să le aibă.
În această fază se stabilesc detaliile pe module, fuxul informațional.
1.3. Implementarea (dezvoltarea codului sursă)
Modulele proiectate și fuxul informațional se transpun în code. Aceasta
este cea mai lungă fază a ciclului de viață de dezvoltare de sofware.
1.4. Testarea
După ce codul este dezvoltat, acesta este testat în conformitate cu
cerințele impuse. În timpul acestei faze, se realizează teste la nivel de modul, teste
la nivel de aplicație. Testele se fac inițial la dezvoltator, urmând a fi efectuate și la
client.
1.5. Mentenanța
Odată ce clienții încep să utilizeze sistemul dezvoltat pot să apară situații
ce nu au fost luate în calcul în faza de analiză și să genereze probleme în
exploatarea aplicației. De asemenea activitatea clientului poate suferi schimbări
în timp ceea ce duce la necesitatea adaptării aplicației sofware.

2. Modele de dezvoltare a software-ului


În dezvoltarea de sofware există diferite abordări defnite și proiectate
care sunt utilizate în timpul procesului de dezvoltare a sofware-ului. Fiecare
model de proces urmează un anumit ciclu de viață, pentru a asigura
funcționalitatea sofware-ului pe o perioadă cât mai lungă.

5
2 . M o d e l e d e d e z v o l t a r e a s o f tw a r e - u l u i

Felul în care se grupează activităţile şi succesiunea fazelor duce la diferite


modele care implementează ciclul de viaţă. Un model al ciclului de viaţă descrie
activitatea de realizare a produsului sofware şi fuxul procesului de dezvoltare.
Dintre cele mai cunoscute modele, ţinând seama de evoluţia lor în timp, putem
enumera:
➔ Modelul în cascadă,
➔ Modelul incremental,
➔ Modelul prototip,
➔ Modelul în spirală,
➔ Inginerie sofware bazată pe model.

2.1. Modelul în cascadă


Este un model în care dezvoltarea începe cu defnirea cerinţelor şi a
specifcaţiilor, urmează proiectarea, după care se pot implementa module mici ce
se pot testa separat şi apoi împreună; după ce se termină testul de integrare,
produsul sofware este testat şi livrat la benefciar, urmând faza de mentenanţă.

Analiză

Proiectare

Implementare

Testare

Mentenanță
Fig. I.-1. Modelul în cascadă
În acest model intrările unei faze sunt ieşirile alteia. Feedback-ul este
generat de erorile ce apar în faza următoare.
Dacă se utilizează modelul în domenii mai puţin cunoscute, pot interveni
costuri mari, antrenate de înţelegerea eronată a cerinţelor, fapt ce apare într-o
etapă târzie, de aceea la nivel conceptual este necesară utilizarea unor prototipuri
în fazele iniţiale ale ciclului de viaţă.
2.2. Modelul incremental
Etapele fnale se realizează în mai mulţi paşi succesivi, fapt ce permite
obţinerea de mai multe versiuni ale produsului sofware

6
2.2.Modelul incremental

(A)
(P)

FUNCȚIONALITĂȚI
(I)
(T)
(M)
Increment #n
(A)
(P)
(I)
(T)
(A) (M) Increment #2
(P)
(I)
(T)
(M) Increment #1
timp

Fig. I.-2. Modelul incremental


Modelul incremental combină elemente ale modelului secvențial liniar
(aplicat în mod repetat) cu flosofa iterativ de prototipuri. Fiecare secvență liniară
produce o dezvoltare livrabilă a sofware-ului.
Obţinerea produsului sofware incremental permite verifcarea dacă
acesta va da rezultatele scontate. Riscul este divizat la câteva incremente mai mici
(la fecare increment) în loc să se concentreze pe o dezvoltare amplă, iar
înţelegerea cerinţelor pentru incrementele ulterioare este mai bună. Prin
obţinerea de mai multe versiuni, se oferă posibilitatea creşterii calităţii produsului
sofware, însă cresc considerabil și costurile de dezvoltare.
2.3. Modelul prototip
Acest model presupune realizarea unui prototip care este testat apoi
testat și evaluat. În funcție de aceste teste și evaluari, se ajustează cerințele din
etapa de Analiză.
(P) Proiectare (R) Prototip (M) Mentenanță

(I) Implementare (T) Testare + Evaluare


(A) Analiză

Fig. I.-3. Modelul prototip


Prezintă dezavantajul unui timp îndelungat pentru implementare și
testare.
2.4. Modelul în spirală
Acest model porneşte de la premisa că în faza de mentenanţă a
produselor sofware pot apărea probleme care necesită defnirea de noi cerinţe de
specifcare ceea ce duce la reluarea fazelor. Acesta apare în contextul activităților
cu dinamică continuă.

7
2 . M o d e l e d e d e z v o l t a r e a s o f tw a r e - u l u i

Proiectare Analiză

Implementare
Testare + Evaluare

Fig. I.-4. Modelul în spirală


Criteriul care stă la baza alegerii modelelor este dat și de costul implicat.

8
II.Implementarea aplicațiilor pe partea de client

II. Implementarea aplicațiilor pe partea de client


1. Noțiuni introductive HTML
Unul din primele elemente ale WWW (World Wide Web) este HTML
(HyperText Markup Language), standard ce descrie formatul primar în care
documentele sunt distribuite și văzute pe Web.
1.1. Structura HTML
Orice document HTML începe cu notația <html> și se termină cu notația
</html>. Astfel de perechi de marcaje sau etichete) se numesc TAG-uri. Prin
convenție, toate marcajele HTML încep cu o paranteză unghiulară deschisă "<" și
se termină cu o paranteză unghiulară închisă ">". Marcajele dintre aceste
paranteze transmit comenzi către browser pentru a afșa pagina într-un anumit
mod.
Între cele două marcaje <html> și </html> pot exista următoarele
secțiuni:
 secțiunea de antet, reprezentată prin tag-urile: <head>...</head>
 corpul documentului, reprezentat prin tag-urile: <body>...</body>
Blocul <body>...</body> cuprinde conținutul propriu-zis al paginii
HTML, adică ceea ce va fi afșat în fereastra browser-ului. Un marcaj poate fi scris
atât cu litere mici, cât și cu litere mari. De exemplu, <BODY> = <BOdy> =
<body>. Caracterele "spațiu" și "CR/LF" ce apar între taguri sunt ignorate de către
browser.
Structura unui document HTML poate avea forma:
<html>
<head>
<title> titlul paginii </title>
</head>
<body>
Prima pagina <br> O pagina Web!
</body>
</html>

1.2. Legături între pagini


O legătură de pe o pagină către o alta afată în același director se
formează cu ajutorul etichetei <a> (de la "anchor"= ancoră).
<html>
<head>

9
1.Noțiuni introductive HTML

<title> Comutarea intre doua pagini</title>


</head>
<body>
<h3>Pagina initiala </h3>
<!-- comentariu - - >
<a href="pagina_2.html"> <!-- Link(legatura) către pag. 2 - - >
</body>
</html>
Legătura poate fi și către un site, ex: href="htp://www.google.com">
Prin <!-- Comentariu - - > se specifică un comentariu.
1.3. Liste în HTML
Unul dintre elementele frecvent întâlnite în documentele HTML este dat
de setul de defniții, referințe sau indecși. O listă neordonată este un bloc text
delimitat de etichetele <ul>...</ul> ("ul" vine de la "unordered list"= lista
neordonată). Fiecare element al listei este inițiat de eticheta<li> (list item). Lista
va fi indentată față de restul paginii Web și fecare element al listei începe pe un
rând nou.
<html>
<head><title> lista nr 1 </title></head>
<body><H2 align=center>O lista neordonata</H2><hr>
<ul>Culori
<li>Negru <li>Alb <li>Galben <li>Albastru <li>Rosu <li>Verde
</ul>
</body>
</html>

1.4. Tabele în HTML


Tabelele ne permit să creăm o rețea dreptunghiulară de zone, fecare zonă
având propriile opțiuni în ceea ce privește culoarea fondului, culoarea textului,
alinierea textului etc.
Pentru a insera un tabel sunt ultilizate etichetele <table>...</table>. Un
tabel este format din rânduri. Pentru a insera un rând într-un tabel se folosesc
etichetele <tr>...</tr> (de la "table row" = rând de tabel ). Un rând este format din
mai multe celule ce conțin date. O celulă de date se introduce cu etichetele
<td>...</td>.
Ex1: tabel simplu 3x3
<html>
<head><title>Denumire tabel</title></head>

10
1.4.Tabele în H TML

<body>
<table border="1" cellpadding="10" cellspacing="15" width="100%">
<tr>
<td align="left">CELULA 1 1</td>
<td align="right">date in celula 2</td>
<td align="middle">date in celula 3</td>
</tr>
<tr>
<td align="middle">date in celula 4</td>
<td align="middle">date in celula 5</td>
<td align="middle">date in celula 6</td>
</tr>
<tr align="right">
<td>date in celula 7</td>
<td>date in celula 8</td>
<td>date in celula 9</td>
</tr>
</table>
</body>
</html>
Ex2:
<html>
TABELE
<table border="1" bgcolor="#0facf">
<tr>
<td bgcolor="#adcdf"> A1 </td>
<td> A2</td>
<td colspan="2"> A3</td>
</tr>
<tr>
<td>B1 </td>
<td> B2</td>
<td> B3</td>
</tr>
<tr bgcolor="#adadf">
<td> C1</td>
<td> C2</td>
<td> C3</td>
</tr>
<tr>
<td>D1 </td>
<td rowspan="2"> D2</td>

11
1.Noțiuni introductive HTML

<td> D3</td>
</table>
</html>
Ex3:
<HTML>
<HEAD>
</HEAD>
<BODY>
TEST <B> ABC </B> <BR/> 123
<BR/>
<!-- un comentariu -->
<TABLE BORDER="1" bgcolor="#3176694">
<TR> <TD>A11</TD> <TD>A12</TD> <TD>A13</TD> </TR>
<TR> <TD>A21</TD> <TD>A22</TD> <TD>A23</TD> </TR>
</TABLE>
<!--ancora -->
<a href="www.qooxdoo.org"> O indirectare (legatura -- link) </a>
</BODY>
</HTML>

1.5. Formulare în HTML


Un formular este un ansamblu de zone active, alcătuit din butoane, casete
de selecție, câmpuri de editare etc. Formularele asigură construirea unor pagini
Web care să permită utilizatorilor să introducă/editeze informații și să le
transmită serverului. Formularele pot varia de la o simplă casetă de text, pentru
introducerea unui șir de caractere pe post de cheie de căutare - element
caracteristic tuturor motoarelor de cautare din Web, până la o structură complexă,
cu multiple secțiuni, care oferă facilități de transmisie a datelor. O sesiune cu o
pagina web ce conține un formular cuprinde următoarele etape:
1. Utilizatorul completează formularul și îl expediează unui server.
2. O aplicație dedicată de pe server (ex: php) analizează formularul
completat și (dacă este necesar) stochează datele într-o bază de date.
3. Dacă este necesar, aplicația de pe server expediază un răspuns
utilizatorului.
Un formular este defnit într-un bloc delimitat de etichetele
corespondente <form> ……. </form>.
1.5.1. Atribute esențiale ale elementului <form>
Există două atribute esențiale ale elementului <form>:
1 Atributul "Action" precizează ce se va întâmpla cu datele formularului
odată ce acestea ajung la destinație. De regulă, valoarea atributului

12
1.5.Formulare în HTML

"Action" este adresa URL a unui script afat pe un server WWW, care
primește datele formularului, efectuează o prelucrare a lor și expediează
către utilizator un răspuns. Script-urile server side (aplicația de pe server)
pot fi scrise în limbaje precum: C, PHP, Unix shell, Java etc.
2 Atributul "Method" precizează metoda utilizată de browser pentru
expedierea datelor formularului. Sunt posibile următoarele valori:
2.1 "Get" (valoarea implicită). În acest caz, datele din formular sunt
adăugate la adresa URL precizată de atributul Action. Nu sunt permise
cantități mari de date (maxim 1 Kb), iar între adresa URL și date este
inserat simbolul "?"
2.2 "Post". În acest caz, datele sunt expediate separat. Sunt permise
cantități mari de date (de ordinul MB).
JavaScript a fost dezvoltat prima dată de către frma Netscape, cu numele
de Live Script, un limbaj de script care extindea capacitățile HTML. Acesta adaugă
dinamism în paginile web.
1.5.2. Formulare cu un câmp de editare și un buton de expediere
Majoritatea elementelor unui formular sunt defnite cu ajutorul etichetei
<input>. Pentru a preciza tipul elementului se foloseste atributul "type" al
etichetei <input>. Pentru un câmp de editare, acest atribut primește valoarea
"text". Alte atribute pentru un element <input> sunt:
 Atributul "name" permite atașarea unui nume fecarui element al
formularului;
 Atributul "value" permite atribuirea unei valori inițiale, unui element al
formularului.
Un buton de expediere al unui formular se introduce cu ajutorul etichetei
<input>, în care atributul "type" este confgurat la valoarea "submit". Acest
element poate primi un nume prin atributul "name".
Pentru elementul <input> de tipul câmp de editare (type= "text"), alte
două atribute pot fi utile:
 Atributul "size", ce specifcă lățimea câmpului de editare. Dacă textul
introdus în câmp de utilizator depășește această lățime, atunci se execută
automat o derulare a conținutului acestui câmp;
 Atributul "maxlength", ce specifcă numarul maxim de caractere pe care le
poate primi un câmp de editare; caracterele tastate peste numărul maxim
sunt ignorate.
Butoanele radio permit alegerea, la un moment dat, a unei singure
variante de răspuns din mai multe posibile. Butoanele radio se introduc prin
eticheta <input> cu atributul " type" având valoarea "radio".
Ex:
<html>

13
1.Noțiuni introductive HTML

<head><title>form exemplu</title></head>
<body><H2>Un formular cu butoane radio</H2>
<hr>
<form action="ex: apel functie JavaScript" method="post">
Selectie 1:<input type="radio" name="var1" value="x1"><br>
Selectie 2:<input type="radio" name="var1" value="x2"><br>
<input type="reset"> <input type="submit">
</form></body>
</html>
În momentul expedierii formularului se va transmite una dintre perechile
"var1=x1" sau "var1=x2", în funcție de alegerea realizată de utilizator.
1.5.3. Casete de validare
O casetă de validare (checkbox) permite selectarea sau deselectarea unei
opțiuni. Pentru inserarea unei casete de validare se utilizează eticheta <input> cu
atributul "type" confgurat la valoarea "checkbox".
Observații:
- fecare casetă poate avea un nume defnit prin atributul "name".
- fecare casetă poate avea valoarea prestabilită "selectat", defnită prin atributul
"checked".
Ex1:
<html><head></head>
<body>
<form>
<input type="text" name="E1" value="1234"></input>
</br>
<textarea>.........A.......</textarea>
</br>
<input type="checkbox" id="36"> selectie </input>
</br>
<input type="radio" id="41"> selectie </input>
<input type="radio"> alta selectie </input>
</br>
<input type="buton" value="Apasa"> </input>
</br>
<select name="select">
<option>Optiune 1</option>
<option>Optiune 2</option>
</select>
</form>
</body>
</html>

14
1.5.Formulare în HTML

Ex2:
<HTML><BODY>
<FORM>
<p> a= <input type="text" name="E1"/></p>
<p> b= <input type="text" name="E2"/> </p>
<p> verifcat: <input type="checkbox" name="CB"></input>
<p> O1: <input type="radio" name="RB" id="R1"></input>
<p> O2: <input type="radio" name="RB" id="R2"></input>
<p> <select name="select" size="3">
<option>Optiune 1</option> <option>Optiune 2</option>
<option>Optiune 3</option> <option>Optiune 4</option>
</select></p>
<p> <select name="select" >
<option>Optiune 1</option> <option>Optiune 2</option>
<option>Optiune 3</option> <option>Optiune 4</option>
</select></p>
<br/>
<input type="buton" value="APASA"></input>
<input type="reset" value="Renunta"></input> <input type="submit"
value="Trimite"></input>
</FORM>
</BODY></HTML>
Fiecare control din cadrul form-ului poate avea un identifcator (id)
și/sau nume(name). Numele controalelor se pot repeta (de exemplu, la butoanele
radio unde numele stabilește gruparea acestora, însă identifcatoarele controalelor
sunt unice.

15
2.Introducere în limbajul JavaScript

2. Introducere în limbajul JavaScript


JavaScript a fost dezvoltat prima dată de către frma Netscape, cu numele
de Live Script, un limbaj de script care extindea capacitățile HTML și care adăuga
dinamism în paginile web. După lansarea limbajului Java, Netscape a început să
lucreze cu frma Sun, cu scopul de a crea un limbaj de script cu o sintaxa și
semantică asemanatoare cu a limbajului Java, și din motive de marketing numele
noului limbaj de script a fost schimbat în "JavaScript". Unii autori consideră că
limbajul Javascript este un ”lisp în haine de C”.
2.1. Convenții de sintaxa
În orice limbaj, scrierea are convenții și reguli de sintaxa. Câteva din
regulile de sintaxă ale limbajului JavaScript:
1. Case-sensitive - se face diferența între literele mari și mici; astfel
cuvinte precum "exemple, Exemple" vor fi tratate diferit.
2. Punct și virgulă (;) - Toate declarațiile trebuie să se termine cu
caracterul "punct și virgula - semicolon" (;) (Exemplu" var1 = 3; var2 = 8;)
3. Spațiile libere - JavaScript ignoră spațiile libere, tab-urile și liniile
libere care apar în instrucțiuni, acestea find utile pentru a face codul mai
bine structurat și ușor de citit. Recunoaște doar spațiile care apar în
string-uri (șirurile de caractere). Exemplu: "var1 = 2;" este la fel cu
"var1=2;".
4. Ghilimelele - Ghilimelele simple / apostrof ('') și duble ("") sunt
folosite pentru a delimita șirurile de caractere (string). (Exemplu: "Acesta
este un test" sau 'Acesta este un test ').
5. Caractere speciale - când scriem scripturi apare necesitatea de a folosi
un caracter special sau o apăsare de tastă, cum ar fi tasta TAB sau o linie
nouă. Pentru aceasta folosim caracterul backslash "\" în fața unuia din
codurile Escape , astfel:
\b - backspace
\f - indică o pagină nouă
\n - indică o linie nouă
\r - indică un ”retur de car”
\t - indica o apăsare a tastei TAB
\\ - indică un caracter backslash
\' - indică un apostrof (ghilimele simple)
\" - indică ghilimele duble
6. Comentarii - comentariile în interiorul codului sunt necesare când
dorim să specifcăm rolul anumitor funcții și variabile, pentru o mai
ușoară înțelegere ulterioară a scriptului. Pentru a adăuga un comentariu,

16
2.1. Convenții de sintaxa

pe o singură linie, în interiorul codului, începem scrierea acestuia cu


succesiunea //(Exemplu: // Comentariu. Dacă dorim să scriem comentarii
pe mai multe rânduri, se folosește /* la începutul comentariului și */ la
sfârșitul acestuia (Exemplu: /* ... comentariu pe mai multe rânduri ... */)
7. Numele variabilelor și funcțiilor - numele dat variabilelor și
funcțiilor trebuie să respecte următoarele reguli:
- primul caracter trebuie să fe o literă, un caracter de subliniere (_) sau
semnul $,
- primul caracter nu poate fi un număr,
- numele nu trebuie să conțină spații libere,
- nu se folosesc cuvinte rezervate, care fac parte din limbajul JavaScript.
2.2. Adăugarea JavaScript într-o pagina HTML
Pentru a insera cod JavaScript într-un document HTML deja existent, este
necesară introducerea în fșier a tag-urilor <script> și </script>. Această etichetă
necesită aributul "type", sau atributul "language" (pentru versiunile vechi de
browsere), care va specifca browserului limbajul folosit pentru interpretarea
codului inclus.
Ex1:
<html><body>
<script type="text/javascript">
document.write("Textul care va f afsat pe ecran");
</script>
</body></html>
Ex2:
<html>
<script type="text/javascript">
//comentariu
//document.write("Textul care va f afsat pe ecran");
var a=5, b='5', s=5, c;
c=a+b;
//alert(c); ("abc");
document.write(c);
if(a==b) alert("a==b"); else alert ("a!=b");
if(a===b) alert ("a===b"); else alert ("a!==b");
if(a===s) alert ("a===s"); else alert ("a!==s");
</script>
</html>

Operatorii utilizați în exemplul de mai sus sunt asemănători cu cei din


PHP, descriși în Anexă.

17
2.Introducere în limbajul JavaScript

Ex:
<html>
<head>
<script type="text/javascript">
function f1(a1) { alert(a1); }
</script>
</head>
<body>
<form>
<input type="buton" onclick="f1('ABC!')" value="LITERE" />
<input type="buton" onclick="f1('123!')" value="CIFRE" />
</form>
</body>
</html>
De obicei funcțiile sunt defnite în secțiunea de header sau în fșiere
separate de tipul JS.
2.3. Variabile
2.3.1. Tipuri de variabile
Spre deosebire de alte limbaje (cum sunt Pascal, Java sau C), JavaScript nu
are tipuri de date predefnite, adică permite schimbarea tipului unei variabile în
cadrul scriptului.
De exemplu:
var x = "xyz"; x = 8;
2.3.2. Durata de viață a unei variabile
O variabilă scrisă sau declarată în cadrul unei funcții este o variabilă
locală; aceasta este vizibilă doar în cadrul acelei funcții, când se iese din funcție
variabila este distrusă. Astfel o altă funcție poate declara și folosi o variabilă cu
același nume. JS (JavaScript) tratează cele două variabile ca find diferite.
Se pot declara și variabile în afara oricarei funcții, care să fe folosite de
toate funcțiile. Acestea se numesc variabile globale și sunt vizibile de la
încărcarea paginii web până la închiderea acesteia, în orice script de tip JS.
2.4. Operatori
Pentru a lucra cu datele introduse într-un script și a manipula valorile
variabilelor se folosesc operatori.
Operatorii sunt simboluri și identifcatori care determina felul în care
sunt modifcate datele și modul în care este evaluată o combinație de expresii și
variabile.

18
2.4. Operatori

JavaScript recunoaște:
- operatori binari - care necesită existentă a doi operanzi în expresie,
- operatori unari - care au nevoie doar de un operand.
Operatorii sunt de mai multe tipuri:
- Operatori aritmetici,
- Operatori de atribuire,
- Operatori de comparare,
- Operatori logici (numiți și booleeni),
- Operatori string (sau șiruri),
- Operatori typeof,
- Operator condițional “?”,
- Operatori pentru funcții,
- Operatori pentru structuri de date.
Operatorii din JavaScript sunt asemănători cu cei din limbajul C și cei din
limbajul PHP explicați în Anexă.
Ex:
<html> <head>
<script type="text/javascript">
function f2(a,b) {
var a1,b1;
a1=parseFloat(a);
b1=parseFloat(b);
alert(a1+b1);
/*var x,y,z; x=E1.value; y=E2.value; */
E3.value=a1+b1;
}
</script>
</head>
<body>
<form>
<p> a= <input type="text" id="E1"/></p>
<p> b= <input type="text" id="E2"/> </p>
<input type="buton" onclick="f2(E1.value,E2.value)" value="adunare" />
<p> a+b= <input type="text" id="E3"/> </p>
</form>
</body> </html>

2.5. Operatorul typeof


Acest operator returnează tipul de date. Acesta este util în special pentru
a determina dacă o variabila a fost defnită sau nu. Spre deosebire de limbajul C,
există și operatorul === ceea ce înseamnă identic atât ca valoare cât și ca tip.

19
2.Introducere în limbajul JavaScript

Dacă a=5 iar b='5' operatorul == întoarce true, în timp ce operatorul ===
intoarce false.
2.6. Instrucțiuni condiționale
2.6.1. Instrucțiunea "if"
Forma generală a acestei instrucțiuni este următoarea:
if (condiție) {
// codul care va f executat dacă este adevărată condiția
},
unde 'condiție' poate fi orice expresie logică. Dacă rezultatul condiției este TRUE,
se execută codul dintre acolade; în caz contrar, când condiția returnează FALSE,
se trece peste acest cod.
Precum și în limbajul C, FALSE corespunde cu ZERO “curat”, iar tot ce
este diferit de zero reprezintă TRUE.
2.6.2. Instrucțiunea "if ... else"
Forma generală a instrucțiunii "if ... else" este următoarea:
if (condiție) {
//codul care va f executat dacă este adevărată conditia
} else { // codul care va f executat dacă conditia este falsa },
unde 'condiție' poate fi orice expresie logică. Dacă rezultatul condiției este
TRUE, se execută codul dintre primele acoladele, care aparțin de if; în caz contrar,
când condiția returnează FALSE, sunt executate comenzile din a doua grupă de
acolade (după else).

TRUE FALSE
if (<expresie>)

instr.1 instr.1

Fig. II.-1. Instrucțiunea if


2.6.3. Instrucțiunea switch
Această instrucțiune este folosită pentru a compara o valoare cu altele
dintr-o listă. Sintaxa generală a instrucțiunii "switch" este următoarea:

20
2.6.Instrucțiuni condiționale

switch (expresie) {
case valoare1:
// cod executat dacă expresie = valoare1
break
case valoare2:
// cod executat dacă expresie = valoare2
break
case valoare3:
// cod executat dacă expresie = valoare3
break
..........................................
default ://in caz contrar se execută default
// cod executat dacă expresie este diferit de valoare1, valoare2 sau valoare3
}
La început este evaluată expresia scrisă între parantezele rotunde, apoi
valoarea expresiei este comparată pe rând cu fecare valoare determinată de
"case". Dacă se găsește o identitate, se execută codul asociat acelui "case", iar în
fnal iese din instrucțiunea "stwitch".
default
case
test expresie

instrucţiune m

instrucţiune 1
break

instrucţiune 2
break

instrucţiune n

Fig. II.-2. Instrucțiunea switch


Dacă prin parcurgerea fecărui "case", nu se găsește o egalitate, se execută
codul ce urmează instrucțiunii "default".
Prin utilizarea instrucțiunii "break" se oprește parcurgerea corpului
instrucțiunii și execuția părăsește blocul "stwitch".

21
2.Introducere în limbajul JavaScript

2.7. Instrucțiuni ciclice


Instrucțiunile repetitive se folosesc atunci când se dorește efectuarea unei
comenzi de mai multe ori. În JavaScript putem utiliza următoarele instrucțiuni
ciclice:
 for - la fel ca și în C, execută codul de un număr specifcat de ori;
 for ... in - execută câte un set de instrucțiuni pentru fecare proprietate
dintr-un obiect;
 twhile - repetă codul atât timp cât o anumită condiție este adevărată;
 do ... twhile – mai întâi execută o dată codul apoi îl repetă atâta timp cât o
anumită condiție este adevărată.
2.7.1. Instrucțiunea for
Aceasta are următoarea formă generală:
for (expresie1; expresie2; expresie3)
bloc instructini
unde:
 "expresie1" este folosită la 'inițializare' pentru a da o valoarea inițială
numărului de repetări; de multe ori prin aceasta se declară o variabilă
care poate fi folosită ca un contoar al ciclului și care este vizibilă la
nivelul blocului dat de for;
 "expresie2" verifcă dacă numărul de cicluri se încadrează într-o anumită
valoare și dacă rezultatul este TRUE se execută încă o dată blocul de
instrucțini;
 "expresie3" de obicei, incrementează sau decrementează valoarea la care a
ajuns contoarul ciclului, apoi această valoare este verifcată din nou de
"conditie_nr" până când rezultatul este FALSE.
Aceste trei expresii dintre parantezele rotunde sunt opționale, dar dacă
este omisă una dintre ele, caracterul punct și virgula ";" trebuie să rămană pentru
ca forma expresiei să rămână neschimbată.
În interiorul instrucțiunii for (ca și la instrucțiunea if), între acolade, pot
fi introduse și alte instrucțiuni for sau alte instrucțiuni condiționale, acest lucru
purtând numele de imbricare a instrucțiunilor.

22
2.7.Instrucțiuni ciclice

evaluare <expresie1>
(de obicei iniţializare contori)

FALSE
evaluare <expresie2>

TRUE

Instrucţiune 1
(blocul instr. for)

evaluare <expresie3>
(de obicei incrementare contori)

Fig. II.-3. Instrucțiunea for

2.7.2. Instrucțiunea for ... in


Această instrucțiune se întâlnește la limbaje de tip ”scripting” și este
utilizată pentru parcurgerea elementelor unui obiect.
Cu instrucțiunea "for ... in" se execută câte un set de instrucțiuni pentru
fecare proprietate dintr-un obiect. Acest ciclul se poate executa cu orice obiect
JavaScript, indiferent dacă are sau nu proprietăți. Pentru fecare proprietate se
execută câte o iterație; dacă obiectul nu are nicio proprietate nu se desfășoară
niciun ciclu. Instrucțiunea "for ... in" are următoarea formă generală:
for (nume_proprietate in obiect) { instrucțiuni }
unde "nume_ proprietate" este un iterator de tip șir, generat de JavaScript. Pentru
fecare repetare a execuției instrucțiunii pentru "nume_proprietate", i se atribuie
următorul nume de proprietate conținut în "obiect", până când parcurgerea este
completă.
Ex:
<!DOCTYPE html>
<html><body>
<script>

23
2.Introducere în limbajul JavaScript

var txt = "";


var adresa = {tara:"Ro", oras:"Oras1", strada:"Str1",codPostal:0123};
for (var x in adresa)
{ txt += adresa[x]; txt += ' - '; }
alert(txt);
</script>
</body></html>

2.7.3. Instrucţiunea while


Sintaxa:
while( <expresie>) instr1;
La întâlnirea acestei instrucţiuni se evaluează <expresie>. Dacă aceasta
are valoarea TRUE (diferită de ZERO), se execută instrucţiunea instr1. Se
reevaluează din nou valoarea expresiei; dacă ea rămâne TRUE, se repetă
instrucţiunea etc. Astfel, instrucţiunea (corpul ciclului) se repetă atât timp cât
expresie are valoarea de adevăr TRUE. În momentul în care <expresie> are
valoarea de adevăr FALSE (sau egal cu ZERO), se iese din ciclu şi se trece la
următoarea instrucţiune din afară buclei twhile.
În cazul în care la prima evaluare a expresiei, aceasta are valoarea de
adevăr FALSE, corpul instrucţiunii twhile nu va fi executat niciodată. Instr1 din
corpul ciclului twhile poate fi compusă (un bloc).

WHILE
evaluare <expresie>
FALSE
TRUE

Instrucţiune 1
(blocul instr)

Fig. II.-4. Instrucțiunea while


2.7.4. Instrucțiunea ”do while”
Sintaxa:
do instr1;
while(<expresie>)
Se execută instrucţiunea instr1 sau blocul de instrucţiuni. Se evaluează
apoi <expresie>. Dacă aceasta are valoarea de adevăr TRUE, se execută din nou

24
2.7.Instrucțiuni ciclice

instr1 altfel se iese din buclă; se testează din nou valoarea expresiei. Se repetă
execuţia instrucţiunii instr1 atâta timp cât valoarea expresiei are valoarea de
adevăr TRUE. În cazul instrucţiunii do twhile, corpul ciclului se execută cel puţin
o dată.

Instrucţiune 1
(blocul instr.)

DO WHILE
evaluare <expresie> TRUE
FALSE

Fig. II.-5. Instrucțiunea do while


2.7.5. Alte instrucțiuni
 Instrucţiunea break - aceasta forţează ieşirea din interiorul unei bucle fără
a se mai ţine seama de condiţia de menţinere în buclă. Instrucţiunile
situate în corpul buclei după instrucţiunea break nu vor mai fi executate.
 Instrucţiunea continue - aceasta duce la ignorarea instrucţiunilor din
buclă, situate după aceasta, şi testarea din nou a expresiei de menţinere în
buclă. În cazul buclelor for se realizează și evaluarea celei de a treia
expresii responsabilă cu incrementarea contorilor.
 Instrucțiunea twith - această comandă este utilizată pentru a evita referirea
în mod repetat la un obiect, atunci când îi accesăm metodele sau
proprietățile de mai multe ori. Orice metodă sau proprietate dintr-un bloc
"with" pe care JavaScript nu o recunoaște va fi asociată cu obiectul
specifcat pentru acel bloc. Sintaxa acestei instrucțiuni este:
with (obiect) { instrucțiuni }

2.8. Funcții JavaScript


Funcțiile ajută la divizarea mai multor sarcini pe care trebuie să le
realizeze un program. O funcție poate conține una sau mai multe instrucțiuni și
comenzi, care ulterior pot fi utilizate de mai multe ori prin apelarea funcției care
le conține.
Asemănător cu limbajul C, pot fi doua feluri de funcții:
✔ Predefnite - cum sunt de exemplu: parseInt(string), parseFloat(string);
✔ Create de programator,

25
2.Introducere în limbajul JavaScript

De asemenea pot fi funcții:


• care returnează o valoare;
• care nu returnează o valoare.

2.8.1. Explicitarea/defnirea funcțiilor


O funcție se defneste la începutul fșierului, în secțiunea head și poate fi
utilizată în cadrul paginii prin apelarea ei. Scriptul care conține defnirea unei
funcții se adaugă în secțiunea "head" pentru a asigura încărcarea acesteia înainte
de a fi apelată.
Pentru crearea unei funcții se folosește cuvantul function urmat de
numele pe care vrem să-l atribuim funcției după care putem adauga între
paranteze rotunde argumentele (numite și atribute) funcției (separate prin virgula
dacă sunt mai multe) și între acolade corpul funcției care conține codul care
trebuie executat.
Forma generală a unei funcții este următoarea:
function nume_functie(argument1, argument, ...) {
codul care va f executat
}
Argumentele sunt variabile folosite de funcție și a căror valoare este
preluată la apelarea funcției. Acestea nu sunt obligatorii, o funcție poate fi
defnită și fără argumente, dar se păstrează parantezele rotunde. Astfel sintaxa
unei funcții fără argumente este următoarea:
function nume_functie() { codul care va f executat
}

2.8.2. Instrucțiunea return


O funcție care returnează un rezultat folosește pentru aceasta
instrucțiunea return. Aceasta specifcă valoarea pe care o returnează funcția
atunci când este apelată.
2.8.3. Apelarea funcțiilor
O funcție este utilizată în momentul în care este apelată. În cazul în care
conține argumente, se apelează în modul următor:
nume_functie(argument1, argument, ...)
O funcție fără argumente se apelează prin:
nume_functie();

3. Despre obiectele JavaScript

JavaScript cuprinde o serie de obiecte ce pot fi utilizate în dezvoltarea

26
3. Despre obiectele JavaScript

codului JavaScript. Aceste obiecte pot fi reprezentate de: un formular, o fereastră,


butoane, imagini etc. Toate elementele dintr-o pagină sunt văzute de JavaScript ca
find obiecte.
3.1. Obiecte JavaScript predefnite
JavaScript are următoarele obiecte predefnite:
1 – String,
2 – Math,
3 – Date,
4 – Array,
5 – Global.
3.1.1. Obiectul String
String (sau obiectul șir) se folosește pentru a manipula date de tip text.
3.1.2. Obiectul Date
Obiectul Date se utilizează pentru a lucra cu data zilei și timpul.
3.1.3. Obiectul Array
Obiectul Array (numit și tablou) se folosește pentru a stoca mai multe
valori într-un singur nume de variabilă. Fiecare valoare stocată devine un element
al tabloului, acesta are asociat un "număr index" (sau cheie). Cu ajutorul acestei
chei se poate face referire la oricare element specifcat din tablou. Cu operatorul
netw se poate crea o "instanță" a obiectului Array, ca în exemplul următor:
var a= new Array(5);
unde între parantezele rotunde este trecut numărul de elemente ale tabloului.
3.1.4. Obiectul Math
Acest obiect include constante matematice și funcții. Nu este nevoie să fe
creat (instanțiat) un obiect Math înainte de a fi folosit. Dacă, de exemplu, dorim
să obținem un număr aleator între 0 și 1, scriem comanda:
nr_aleator = Math.random

3.1.5. Obiectul Global


Acest obiect grupează proprietățile și metodele de nivel cel mai înalt, fără
un obiect părinte. JavaScript organizează toate elementele unei pagini web într-o
ierarhie. Toate elementele sunt văzute ca obiecte și fecare obiect are anumite
proprietăți și metode. Cu JavaScript putem manipula ușor obiectele. Pentru
aceasta este importantă înțelegerea ierarhiei obiectelor HTML.
JavaScript tratează fereastra browser-ului ca pe un obiect window. Acesta

27
3. Despre obiectele JavaScript

conține anumite elemente, cum ar fi de exemplu bara de stare, bara de titlu etc .
În fereastra browser-ului putem încărca /afșa un document HTML, iar
pagina din interiorul browser-ului este un obiect document.
3.2. Modelul Obiectului Document (DOM)
DOM defnește o structură standardizată a documentelor. Structura DOM
este reprezentată de o ierarhie de obiecte compatibilă cu limbajul JavaScript.
Ierarhia obiectelor este:
0. Fereastra curentă:
1. self, window, parent, top,
2. navigator,
3. frames,
4. location,
5. history,
6. document:
6.1. forms[] (butons, checkbox, hidden, radio, password,
reset, select, submit, text, textarea, fleupload),
6.2. anchors[],
6.3. links[],
6.4. images[],
6.5. embeds[],
6.6. layer[]
etc.
Elementele principale legate de lucrul pe partea de client din JavaScript se
axează pe ceea ce putem face cu paginile HTML, mai exact - ceea ce poate realiza
vizitatorul cu scriptul JavaScript încărcat în pagina HTML.
Primul set de obiecte are o legătură cu navigatorul și cu etichetele HTML
din acesta. Majoritatea obiectelor JavaScript din nivelul 2 sunt văzute ca obiecte
corespondente etichetelor HTML:
Buton - <input type="buton">; Checkbox - <input type="checkbox">;
Fileupload - <input type="fle">; Password - <input type="passtword">;
Radio - <input type="radio">; Reset - <input type="reset">; Select - <select>;
Frame - <frame>; Document - <body>; Layer - <layer> sau <ilayer>;
Link - <a href="">; Image - <img> Area - <map>; Anchor - <a name="">;
Plugin - <embed>; Form - <form>; Submit - <input type="submit">;
Text - <input type="text">; Textarea - <textarea>; Option - <option>
3.3. Obiecte de nivel 3 și 4
Obiectele de nivelul 3 sunt subobiecte ale obiectului "Form". La fel cum
sunt imbricate elementele HTML în interiorul etichetelor <form>, aceste obiecte

28
3.3.Obiecte de nivel 3 și 4

sunt imbricate în interiorul obiectului "Form".


3.3.1. Obiectul Buton
JavaScript are trei obiecte butons: Buton, Submit și Reset. Fiecare
dintre acestea are o reprezentare a unei etichetei HTML. Obiectul Buton este un
buton generic, la care, pentru a fi folosit pentru o anumită funcție, trebuie să îi
adăugăm linii de cod specifce, dar celelalte două: Submit (trimite datele la un
script) și Reset (șterge datele noi completate în formular); au scopuri specifce.
Totuși, se poate să folosim un obiect Buton pentru a avea același efect ca și
obiectul Submit (apelând Form.submit()), sau ca obiect Reset (apelând
Form.reset()). Proprietățile obiectului Buton:
form - returnează obiectul Form al carui membru este butonul name -
returnează șirul specifcat în atributul name al etichetei HTML <input>;
type - returnează șirul specifcat în atributul type al etichetei HTML
<input>;
value - returnează șirul care apare în reprezentarea grafca a unui buton,
afșată în browser.
Metodele obiectului Buton:
 blur() - dezactivează butonul;
 click() - apelează un eveniment click pentru butonul respectiv;
 focus() - eveniment de activare a butonului;
 handleEvent() - transferă un eveniment handlerului de evenimente
corespunzător.
3.3.2. Obiectul Checkbox
Acest obiect reprezintă caseta de validare HTML dintr-un "Form", care
permite vizitatorului să specifce o valoare "DA" sau "NU", ori "true" sau "false".
Proprietățile obiectului "Checkbox" sunt următoarele:
➔ checked - returnează o valoare booleană care determină dacă este bifată
caseta de validare;
➔ defaultChecked - returnează o valoare booleană care pastrează starea
inițială a casetei de validare. Este stabilită cu atributul "checked";
➔ form - returnează obiectul Form al casetei de validare;
➔ name - returnează șirul specifcat în atributul name al etichetei HTML
<input>;
➔ type - returnează șirul specifcat în atributul type al etichetei HTML
<input>;
➔ value - returnează o valoare returnată când formularul este înaintat.
Metodele obiectului "Checkbox" sunt următoarele:
 blur() - dezactivează caseta de validare;
 click() - apelează un eveniment click pentru caseta de validare respectivă

29
3. Despre obiectele JavaScript

 focus() - eveniment de activare a casetei de validare;


 handleEvent() - transferă un eveniment handlerului de eveniment
corespunzător.
3.3.3. Obiectul Password
Obiectul password este asemănător cu obiectul "text", diferența find că
toate caracterele introduse în cazeta "Password" sunt afșate cu "*" pentru a nu fi
vizibil textul introdus.
Proprietățile obiectului "Passtword" sunt următoarele:
➔ defaultValue - face referire la atributul "value" al casetei pentru parola din
formularul HTML;
➔ form - face referire la obiectul Form ce conține caseta pentru parolă;
➔ name - conține șirul specifcat în atributul name al pentru parolă;
➔ type - conține șirul specifcat în atributul type al casetei pentru parolă;
➔ value - face referire la conținutul curent din caseta pentru parolă.
Metode ale obiectului "Passtword" sunt următoarele:
 blur() - dezactivează caseta pentru parolă;
 focus() - activează caseta pentru parolă;
 handleEvent() - transferă un eveniment handlerului de eveniment
corespunzător;
 select() - selectează textul adăugat în caseta pentru parolă.

3.3.4. Obiectul Radio


Butoanele radio sunt controale dintr-un formular HTML care se exclud
unul pe altul. Astfel dacă este selectat un buton radio, toate celelalte butoane din
set sunt neselectate. Setul de butoane se defnește având aceeași proprietate
name pentru toate butoanele radio.
Proprietățile obiectului "Radio" sunt următoarele:
➔ checked - returnează o valoare care determină dacă este bifat obiectul
radio;
➔ defaultChecked - returnează o valoare care păstrează starea inițială a
obiectului Radio, care se stabilește cu atributul checked al etichetei
<input> respective;
➔ form - returnează obiectul Form ce conține obiectul Radio;
➔ name - conține șirul specifcat în atributul name al etichetei <input>;
➔ type - conține șirul specifcat în atributul type al etichetei <input>;
➔ value - face referire la atributul value al etichetei <input>.
Metodele obiectului Radio sunt următoarele:
 blur() - dezactivează obiectul Radio;
 click() - apelează un eveniment "click" pentru obiectul Radio;
 focus() - activează un buton radio;

30
3.3.Obiecte de nivel 3 și 4

 handleEvent() - transferă un eveniment handlerului de eveniment


corespunzător.
3.3.5. Obiectul Submit
Acest obiect este asociat butonului submit dintr-un formular HTML;
când butonul este acționat, trimite datele din formular, către server pe calea
specifcată în atributul action din eticheta <form> .
Proprietățile obiectului "Submit" sunt următoarele:
➔ form - returnează datele din întreg formularul ce conține butonul
submit;
➔ name - returnează șirul specifcat în atributul name al etichetei <input>
corespunzătoare butonului;
➔ type - returnează șirul specifcat în atributul type din eticheta <input> a
butonului submit;
➔ value - returnează șirul adaugat în atributul value din eticheta <input> a
butonului.
Metode ale obiectului Submit sunt următoarele:
 blur() - dezactivează butonul;
 click() - apelează un eveniment click pentru butonul respectiv;
 focus() - activează butonul;
 handleEvent() - apelează handlerul pentru evenimentul specifcat.

3.3.6. Obiectul Reset


Acest obiect este asociat butonului "reset" dintr-un formular HTML;
atunci când butonul este acționat, sterge toate datele introduse în formular,
stabilind câmpurile la valoarea lor inițială.
Proprietățile obiectului Reset sunt următoarele:
➔ form - returnează obiectul Form ce conține butonul;
➔ name - conține șirul specifcat în atributul name al etichetei <input>
corespunzătoare butonului;
➔ type - conține șirul specifcat în atributul type al etichetei <input>;
➔ value - returnează șirul adăugat în atributul value din eticheta <input>
corespunzătoare butonului.
Metode ale obiectului Reset sunt următoarele:
 blur() - dezactivează butonul;
 click() - apelează un eveniment click pentru butonul respectiv;
 focus() - activează butonul.

3.3.7. Obiectul Select


Acest obiect este asociat unei liste de selecție dintr-un formular HTML și
permite utilizatorului selectarea unor valori dintr-o listă predefnită. Aceasta

31
3. Despre obiectele JavaScript

poate fi de tipul listbox sau combobox. Dintr-o listă derulantă (combobox) se


poate selecta numai o singură valoare, iar dintr-o caseta (listbox) cu lista de
selectare se pot selecta mai multe valori.
Obiectul select poate apărea ca listă derulantă (în mod implicit) sau ca
listă de selectare dacă se specifcă proprietatea multiple cu valoarea de adevăr
TRUE.
Proprietățile obiectului Select sunt:
➔ form - returnează obiectul Form ce conține lista de selectare;
➔ length - returnează numărul de opțiuni din lista de selectare;
➔ name - returnează șirul specifcat în atributul name al etichetei HTML
corespunzătoare;
➔ type - returnează șirul specifcat în atributul type al etichetei HTML
(pentru instanțele select ce conțin atributul multiple returnează select-
multiple, iar pentru cele fără acest atribut returnează select-one);
➔ options - returnează un tablou ce conține toate elementele din caseta de
selectare. Elementele sunt defnite cu eticheta HTML <options>. Această
proprietate are două subproprietăți: length și selectedIndex;
➔ selectedIndex - returnează un numar care specifcă indicele opțiunii
selectate din caseta de selectare.
Metodele obiectului Select sunt următoarele:
 blur() - dezactivează caseta de selectare;
 click() - apelează un eveniment click pentru caseta de selectare;
 handleEvent() - transferă un eveniment handlerului de eveniment
corespunzător.
3.3.8. Obiectul Text
Acest obiect este reprezentarea casetei de tip editbox dintr-un formular
HTML. Obiectul text servește pentru preluarea datelor dintr-o casetă de tip text.
Proprietăție obiectului Text sunt următoarele:
➔ defaultValue - returnează valoarea casetei de text, specifcate de
atributul value. form - returnează obiectul Form ce conține caseta de text;
➔ name - returnează șirul specifcat în atributul name al etichetei HTML
corespunzătoare;
➔ type - returnează șirul specifcat în atributul type al etichetei HTML;
➔ value - returnează valoarea afșată în caseta de text.
Metode ale obiectului "Text" sunt următoarele:
 blur() - dezactivează caseta de text;
 focus() - activează caseta de tip text;
 handleEvent() - transferă un eveniment handlerului de eveniment
corespunzător;
 select() - selectează textul din caseta de text.

32
3.3.Obiecte de nivel 3 și 4

3.3.9. Obiectul Textarea


Asemănător cu obiectul Text, obiectul Textarea este reprezentarea
casetei de tip Memo dintr-un formular HTML. Această casetă permite adăugarea
mai multor linii de text în același câmp (casetă).
Proprietățile obiectului Textarea sunt următoarele:
➔ defaultValue - returnează valoarea zonei de text, specifcate între
etichetele <textarea>;
➔ form - returnează obiectul Form ce conține caseta textarea
➔ name - returnează șirul specifcat în atributul name al etichetei HTML
corespunzătoare;
➔ type - returnează șirul specifcat în atributul type al etichetei HTML;
➔ value - returnează valoarea afșată în caseta textarea;
Metodele obiectului Textarea sunt următoarele:
 blur() - dezactivează zona de text;
 focus() - activează zona de text;
 handleEvent() - transferă un eveniment handlerului de eveniment
corespunzător;
 select() - selectează textul din câmpul de text.

4. Evenimente JavaScript
Evenimentele sunt elemente importante în construcția interfețelor
grafce. Acestea sunt acțiuni provocate de cele mai multe ori de vizitatorul
paginii. Dacă vizitatorul apasă un buton din pagină, este generat evenimentul
Click. Dacă mouse-ul este deasupra unui link, se declanșează un eveniment
MouseOver. JavaScript poate reacționa la unele evenimente. Aceasta se poate
realiza cu ajutorul "event-handlers" (managerii de evenimente). Handlerele de
evenimente se adaugă ca atribute ale etichetelor HTML.
Principalele evenimente:
• onClick - Se execută la execuția unui click pe un obiect(document, link,
buton, checkbox, buton radio, buton reset sau submit);
• onDblClick - Execută acțiunea la efectuarea a două clickuri unul după
altul, fără a deplasa mouse-ul;
• on MouseOver - Acționează când se poziționează mouse-ul deasupra
unui link sau unei imagini;
• onMouseOut - Acționează când se mută mouse-ul de pe un hiperlink sau
imagine;
• onMouseMove - Acționează când se mișcă mouse-ul;
• onMouseDotwn - Acționează când este apăsat unul din butoanele
mouse-ului, pe un document, buton sau link;
• onMouseUp - Acțiunea se execută atunci când este eliberat unul din

33
4.Evenimente JavaScript

butoanele mouse-ului;
• onFocus - Acțiunea apare atunci când este activat un obiect de tipul:
caseta password, câmp text, bloc de text, câmp FileUpload etc. dintr-un
formular HTML.
• onChange - Acțiunea apare atunci când se modifcă conținutul unui
câmp dintr-un formular HTML (o parolă, text, bloc de text, FileUpload
etc.) și când acesta pierde focalizarea (selecția);
• onBlur - Este inversul lui onFocus(), este declanșat atunci când un obiect
nu mai este activ, prin trecerea la o altă resursă;
• onLoad - Acționează atunci când browserul a terminat de încărcat un
document, imagine sau toate frame-urile.

5. Cookie-uri
Valorile majorității variabilelor dintr-un script dispar atunci când
fereastra browser-ului este închisă. Spre deosebire de acestea, valorile variabilelor
cookie se pot păstra un timp indefnit. Pentru ca valorile lor să se poată păstra,
browser-ul utilizatorului stochează variabilele cookie în unitatea de hard-disc a
utilizatorului. Astfel, cookie-urile sunt fșiere care conțin diferite date despre un
anumit site vizitat și valori de variabile, salvate pe calculatorul vizitatorului. Un
cookie constă, în principal, dintr-o pereche nume = valoare, iar caracteristici
mai avansate permit stabilirea unei date de expirare și pot stabili un sistem de
management al acestora.
Unul dintre avantajele folosirii fșierelor cookie este persistența acestora.
Un fșier cookie poate persista luni de zile (sau ani), simplifcând vizitele
ulterioare ale utilizatorului pe site deoarece informațiile referitoare la vizite și
preferințele utilizatorului sunt salvate și preluate din cookie de fecare dată când
va reveni la site.
Fișierele de tip cookie sunt utile când sunt folosite cu JavaScript, deoarece
JavaScript are funcții pentru citirea, adăugarea și editarea fșierelor cookie.
Browserul poate fi setat pentru un anumit tip de management al acestor
fșiere, astfel se pot impune restricții privind dimensiunea și numărul de fșiere
cookie care pot fi stocate, iar fșierele cookie mai noi pot suprascrie pe cele vechi.
Când un utilizator trece de la un browser la altul, fșierele cookie salvate
de un browser nu sunt recunoscute de celălalt .
Cele mai multe browsere stochează informațiile cookie în fșiere text
necriptate, de aceea informațiile private precum parole, numere personale nu
trebuie stocate direct într-un cookie.
Utilizatorul poate confgura browserul astfel încât să interzică stocarea
informațiilor de tip cookie. În unele cazuri, acest lucru are ca rezultat
nefuncționalitatea aplicației.

34
5.Cookie-uri

Proprietățile și valorile dintr-un cookie sunt stocate și stabilite utilizând


proprietatea cookie a obiectului Document. Pentru a stoca șirul cookie într-o
variabilă se folosește o comandă de tipul:
var myCookie = document.cookie
JavaScript stochează fșierele cookie în formatul următor:
nume1=valoare1; nume2=valoare2; nume3=valoare3
unde "nume1", "nume2" și "nume3" reprezintă numele fecarui cookie, iar
"valoare1", "valoare2" și "valoare3" reprezintă valorile care vor fi adăugate și
stocate în fecare cookie.
Perechile nume=valoare sunt separate prin caracterul punct și virgula (;)
și un spațiu, iar după ultima pereche nu se mai pune caracterul punct și virgula.

6. Obiecte defnite de utilizator în JavaScript


Deși limbajul JavaScript este orientat pe obiecte, în condițiile în care
variabilele nu au tipuri predefnite nu există nici cuvântul cheie class ce ar fi
putut să defnească tipul de dată clasă. Practic orice variabilă poate acționa direct
ca un obiect. În acest caz avem moștenire la nivel de obiecte.
Tipurile de date: Number, String, Boolean și Date sunt coniderate tipuri
primitive.
Există trei moduri prin care putem defni un obiect.
6.1. Defnire obiecte prin utilizarea funcțiilor
Aceasta este, probabil, cea mai răspândită modalitate. Se poate defni o
funcție normală JavaScript și apoi se poate crea un obiect folosind denumirea
funcției. Defnirea proprietăților și metodelor pentru un obiect creat folosind
funcția se realizează precum în exemplul următor.
<!DOCTYPE html>
<html><body>
<script type="text/javascript">
function Persoana (nume) {
this.nume = nume;
this.varsta = 50;
//defnire funcție în interiorul ”funcției/obiectului”
this.getTelInfo = function() {
return this.nume + ' ; ' + this.varsta + ' ; 01xxxxxx';}
this.tel = this.getTelInfo;
}
var pers1 = new Persoana('Popescu');
pers1.varsta = 51;

35
6.Obiecte defn ite de utilizator în JavaScript

alert(pers1.getTelInfo());
</script>
</body></html>
Pentru a defni proprietăți și metode pentru un obiect creat folosind
funcții, se utilizează cuvântul cheie this.
Funcția getTelInfo() poate fi defnită și în afara obiectului prin utlizarea
cuvântului cheie prototype.
<!DOCTYPE html>mult
<html><body>
<script type="text/javascript">
function Persoana (nume) {
this.nume = nume;
this.varsta = 50;
}
Persoana.prototype.getTelInfo = function()
{ return this.nume + ' ; ' + this.varsta + ' ; 01xxxxxx';}

var pers1 = new Persoana('Popescu');


pers1.varsta = 51;
alert(pers1.getTelInfo());
</script>
</body></html>

6.2. Obiecte defnite literal


Defnirea literală este mult mai scurtă, se pot defni atât obiecte cât și
tablouri în JavaScript. Pentru a crea un obiect gol se poate scrie:
var z = { };
sau se poate scrie:
var z = new Object ();
Pentru un vector se poate scrie direct
var z = [ ];
în loc de:
var z = new Array ();
Pentru tablouri multidimensionale sunt necesare instanțieri separate pe
fecare dimensiune.
În acest caz defnirea unui obiect se realizează prin detalierea perechilor
de tip key:value, fe că sunt proprietăți, fe că sunt funcții.
<!DOCTYPE html>
<html><body>

36
6.2.Obiecte defn ite literal

<script type="text/javascript">
var pers1={
nume : 'Ionescu',
varsta : 51,
getTelInfo : function()
{ return this.nume + ' ; ' + this.varsta + ' ;
01xxxxxx';}
}
pers1.nume = 'Popescu';
alert(pers1.getTelInfo());
</script>
</body></html>

6.3. Obiecte ce utilizeză mecanismul singleton


Mecanismul singleton este întâlnit în programarea orientată pe obiecte
pentru cazurile în care este permisă o singură instanțiere a unei clase. Și în cazul
JavaScript putem defeni obiecte unice.
<!DOCTYPE html>
<html><body>
<script type="text/javascript" >
var pers1 = new function() {
this.nume = 'Ionescu';
this.varsta = 51;
this.getTelInfo = function()
{ return this.nume + ' ; ' + this.varsta + ' ; 01xxxxxx';};
}
pers1.nume = 'Popescu';
alert(pers1.getTelInfo());
</script>
</body></html>

6.4. Constructori în JavaScript


Constructorii sunt funcții ce pot avea unu, mai multe sau niciun
argument. Aceștia sunt apelați automat în momentul în care obiectul se constituie
în memoria dinamică.
<!DOCTYPE html>
<html><body>
<script>
function Persoana(nume){
this.nume = nume;
}

37
6.Obiecte defn ite de utilizator în JavaScript

var sir;
var pers1 = new Persoana('Pers1');
if(pers1 instanceof Persoana) sir='pers1 este de tip Persoana';
else sir='pers1 este nedefnit';
alert(sir);
</script>
</body></html>
Modifcarea constructorilor este ilustrată în exemplul următor, exemplu
care va afșa ”pers1 este de tip Vehicul”.
<!DOCTYPE html>
<html><body>
<script>
function Vehicul(marca){
this.marca = marca;
}
function Persoana(nume){
this.nume = nume;
return new Vehicul('dacia');
}
var sir;
var pers1 = new Persoana('Pers1');
if(pers1 instanceof Persoana) sir='pers1 este de tip Persoana';
else if (pers1 instanceof Vehicul) sir='pers1 este de tip Vehicul';
else sir='pers1 este nedefnit';
alert(sir);
</script>
</body></html>

6.5. Moștenirea în JavaScript


Ca și în limbajul C++ este permisă moștenirea. Un exemplu de moștenire
este dat de exemplul:
<!DOCTYPE html>
<html><body>
<script>
function Animal(nume) {
this.nume = nume;
this.alearga = function() {
alert(this.nume+' alearga!');
}
}
function Caine(nume){

38
6.5.Moștenirea în JavaScript

Animal.apply(this, arguments);
this.alearga = function(){
alert('Acest caine, pe nume '+this.nume+', alearga!');}
}
var catel = new Caine('Grivei');
catel.alearga();
</script>
</body></html>
Proprietatea nume nu apare decât în obiectul părinte. Doar constructorul
din obiectul părinte inițializează proprietatea nume cu valoarea transmisă prin
argument. Metoda apply asigură apelul costructorului din obiectul părinte.
O altă modalitate de a declara o moștenire este prin utilizarea __proto__ ,
refiefată în exemplul următor.
<!DOCTYPE html>
<html><body>
<script>
function Animal(nume) {
this.nume = nume;
this.alearga = function() {
alert('Un animal '+this.nume+' alearga!');
}
}
function Caine(nume){
var rasa;
this.nume=nume;
this.alearga = function(){
alert('Acest caine, pe nume '+this.nume+', alearga!');
}
}
Caine.__proto__ = Animal;
//identic cu a scrie Caine.prototype = Animal;
var catel = new Caine('Grivei');
alert(catel.nume);
catel.alearga();
</script>
</body></html>
De asemenea prin:
caine = Object.create(animal);
este creat obiectul caine , fără conținut, ce moștenește proprietățile obiectului
animal. În acest caz moștenirea este valabilă doar pentru proprietăți și nu pentru
funcții.
Asemeni funcțiilor virtuale din limbajul C++, este permisă redeclararea

39
6.Obiecte defn ite de utilizator în JavaScript

funcțiilor/metodelor din clasele derivate, astfel funcția alearga din obiectul


Animal a fost redefnită în obiectul derivat Caine.
În exemplul următor este apelată mai întâi medoda alert() din clasa
derivată, iar apoi este apelată din obiectul părinte.
<!DOCTYPE html>
<html><body>
<script>
function Animal(nume) {
this.nume = nume;
this.alearga = function() {
alert('Un animal '+this.nume+' alearga!');
}
}
function Caine(nume){
Animal.apply(this, arguments);
var parentAlearga = this.alearga;
this.alearga = function(){
alert('Acest caine, pe nume '+this.nume+', alearga!');
parentAlearga.apply(this);
}
}
var catel = new Caine('Grivei');
catel.alearga();
</script>
</body></html>

6.6. Specifcatori de acces


La fel ca și în alte limbaje avem specifcatorii de acces, valabili atât pentru
proprietățile obiectului, cât și pentru funcțiile (metodele acestuia)/ Astfel:
 private – vizibilitatea este asigurată doar la nivelul obictului (implicită);
 protected – datele și funcțiile din obiectele moștenite vor putea vedea
datele/proprietățile și funcțiile/metodele din obiectele părinte (acestea din
urmă având specifcatorul de acces protected);
 public – proprietățile și funcțiile sunt văzute și din afara obiectelor.
În exemplul următor variabila _varsta din obiectul Animal este de tip
protected și este văzută în clasa derivată Caine
<!DOCTYPE html>
<html><body>
<script type="text/javascript" >
function Animal(nume,varsta) {
this.nume = nume; //public

40
6.6.Specifc atori de acces

this._varsta = varsta; //protected


var inaltime; // private
}
function Caine(nume,varsta){
Animal.call ( this, nume, varsta);//se realizează moștenirea
this.varsta_caine = this._varsta;
var variabila_private = 'inaccesibila din afara obiectului!';
}
var catel = new Caine('Grivei',3);
alert(catel.nume+' : '+catel.varsta_caine);
</script>
</body></html>

6.7. Date și funcții de tip static


O variabilă de tip static este utilizată având numele obiectului în față, de
exemplu putem contoriza numărul total de animale (numărul de obiecte ce au la
bază obiectul Animal):
<!DOCTYPE html>
<html><body>
<script>
function Animal(nume) {
this.nume = nume;
Animal.cnt++;
}
//funcția se declară FARĂ prototype
Animal.afsCnt = function() {
alert(Animal.cnt);
}
function Caine(numeX){
Animal.apply(this, arguments);
}
Animal.cnt=0;
var lista_nume=['Azorel','Grivei','Ham','Bubu','Buf'];
var catei=[];
for(var i=0;i<lista_nume.length;i++)
catei[i]= new Caine(catei[i]);
Animal.afsCnt();
</script>
</body></html>
Funcțiile de tip static sunt independente de obiectele instanțiate și sunt
declarate fără prototype.

41
III.Implemementarea aplicațiilor pe parte de server
- Noțiuni introductive PHP

III. Implemementarea aplicațiilor pe parte de server -


Noțiuni introductive PHP
Notă: pentru testarea exemplelor se pot instala postgreSQL și ApachePHP (din
cadrul PostgreSQL Stack Builder): htp://twtwtw.postgresql.org. După instalare se
creează automat directorul twtwtw sau htdoc. Fșierele php se vor pune în acest
director sau într-un subdirector al acestuia. Exemplu de apel:
htp://localhost:8080/T1/test.php sau htp://nume_calculator/T1/test.php
PHP este prescurtarea de la Hypertext PreProcessor.
Când accesăm o pagină HTML, serverul care o găzduiește trimite pagina
HTML către browser spre afșare. În cazul unei pagini PHP, serverul citește codul
PHP, îl interpretează și generează dinamic pagina HTML, care este trimisă
browserului spre afșare. Acesta este motivul pentru care unii utilizatori folosesc
PHP și pentru construirea unor pagini cu conținut dinamic.
Fișierele PHP au extensia php, acestea pot fi scrise cu orice editor de
texte. Este preferat Notepad++ datorită faptului că pune în evidență sintaxa
limbajului. Există și editoare ce oferă mai multe facilități (help interactiv, apel
debugger etc.) cum ar fi eclipse php sau cele oferite de Zend.
Când PHP-ul parcurge un fșier, de fapt "citește" textul până când
întâlnește una dintre etichetele speciale, care-i spun să înceapă să interpreteze
textul ca pe cod PHP. Se execută codul până când este întâlnită eticheta de
închidere. Apoi se "citește" din nou textul mai departe. Acesta este motivul pentru
care se poate adăuga cod PHP în interiorul HTML-ului.
Câteva reguli de sintaxă:
 închiderea unui rând se face obligatoriu cu caracterul ” ;”;
 numele funcțiilor sunt CaseInsensitive (nu se face diferența între
utilizarea literelor mari și a celor mici);
 numele variabilelor sunt CaseSensitive (se face diferența între utilizarea
literelor mari sau mici).
Codul PHP este delimitat de unul din următoarele seturi de etichete de
deschidere și închidere:
<?php ?> etichete recomandate
<script
language="php"? </script>
>
<? ?> folosirea lor necesită anumite setări pe server
<% %> etichete tip ASP, folosirea lor necesită anumite setări
pe server
Ex: cel mai simplu script PHP este:
<?php

42
III.Implemementarea aplicațiilor pe parte de
server - Noțiuni introductive PHP
echo "Acesta este un script PHP";
?>
Funcția echo este folosită pentru afșarea informațiilor delimitate de
ghilimele. Similară funcției echo este funcția print.
În situația în care scriptul nu este scris corect, PHP-ul va afșa eroarea
indicând și locul unde aceasta apare. Erorile sunt afșate doar dacă serverul este
setat corespunzător (în fșierul php.ini este setat display_errors=On și
error_reporting=E_ALL).
Ex: în interiorul scriptului se pot insera și etichete HTML
<?php
echo "Acesta este un script <b>PHP</b><br>care contine si etichete HTML";
?>
Ex: fșierul PHP poate conține între etichetele <html> și </html> blocuri PHP
delimitate de <?php ?>
<html>
<head> <title>Ex</title>
</head>
<body>
Bloc HTML<br>
<?php
echo "Bloc PHP";
?>
</body>
</html>
În PHP există trei metode prin care se poate adăuga un comentariu.
Tot ce urmează dupa caracterele // sau # este considerat comentariu. De ex:
// Urmează un comentariu în PHP
# Urmează un comentariu în PHP
Utilizare:
echo "test"; // browser-ul va afșa test
echo "proba"; # browser-ul va afșa proba
Un comentariu format din mai multe linii este incadrat de /* și */. De ex:
/* Comentariul în PHP
scris pe doua linii */

1. Variabile PHP

Variabila, ca și în limbajul C, este un “container de date” care poartă un


nume și i se poate atribui o valoare care poate fi modifcată de mai multe ori sau

43
1.Var i a b i le P H P

salvată într-o baza de date. În php numele dat variabilei începe cu simbolul $
urmat de orice literă mica (a-z) sau mare (A-Z) sau cu caracterul _ , dar niciodată
cu o cifră și nu poate conține spații goale. De ex: $nume_variabila
$nume_variabila="valoare"
Ex: atribuim variabilei $program valoarea PHP și apoi o tipărim
<?php
$program="PHP";
echo $program;
?>
Modifcând valoarea variabilei, se modifca ceea ce este afșat de browser.
Într-un script se pot folosi mai multe variabile care pot fi adăugate în aceeași
construcție echo.
Ex:
<?php
$ziua="01";$luna="12";$anul="2012";
echo "Data este ".$ziua.".".$luna.".".$anul;
?>

1.1. Tipuri de variabile


În PHP sunt opt tipuri de variabile primitive:
 patru tipuri scalare: întregi, numere cu virgula fotantă, șiruri și booleene,
 două tipuri compuse: matrice și obiecte,
 două tipuri speciale: resurse și NULL.
Întreg (integer) este un simplu număr întreg exprimat în sistem zecimal,
hexazecimal sau octal, opțional putând purta și semn (+ sau -). În sistem octal
numărul trebuie precedat de 0, iar pentru hexazecimal precedat de 0x.
$a=13; //numar exprimat în sistem zecimal
$a=-13; //numar negativ exprimat în sistem zecimal
$a=0137; //numar octal
$a=0x1F; //numar hexazecimal
Numere reale (foat)
$a=-3.14; //numar zecimal negativ
$a=1.3e2; //130
$a=1E+3; //1000
Șirul (string) este o variabilă care conține o combinație de numere, litere,
simboluri și spații delimitate între două ghilimele simple sau duble. Șirurile pot
conține și nume de variabile.
Ex:
<?php

44
1.1.Tipuri de variabile

$nume="Ion";
$varsta=24;
echo "Numele persoanei este ".$nume." și are ".$varsta.” ani”;
?>
Cea mai simplă cale pentru a specifca un șir este să îl încadrăm între
ghilimele simple/apostrof ('), dar eventualele ghilimele simple conținute vor fi
precedate de caracterul \. În această situație variabilele și caracterele speciale vor
fi ignorate.
echo "acesta este un șir"; //acesta este un șir
echo "variabila $a"; //variabila $a
echo "rand1 \n rand2"; //rând1 \n rând2
Variabila booleană exprimă valoarea de adevăr: TRUE sau FALSE. Orice
valoare diferită de zero sau șir care nu este gol (conține cel putin un caracter) sunt
considerate ca TRUE.
Ca și în limbajul C, valoarea 0 corespunde cu FALSE, iar tot ce este diferit
de zero este TRUE.
Tablouri (array) - acestea utilizează chei sau indecși pentru a identifca
valorile stocate. Un tablou se creează folosind funcția array():
$vector = array('unu','doi','trei');
Ex: creăm un tablou și îi tiparim elementele folosind funcția print_r
<?php
$vector = array('unu','doi','trei');
print_r ($vector);
?>
Ex: utilizăm același tablou, dar folosim funcția var_dump(), care ne arată câte
elemente sunt în tablou și lungimea fecărei valori a sa.
<?php
$vector = array('unu','doi','trei');
var_dump ($vector);
?>
Primul index al unui vector are valoarea 0. Valorile indecșilor pot fi și
declarate manual.
Ex: creăm o matrice cu indecșii 1, 3 și 5
<?php
$ vector = array(1=>'unu',3=>'trei',5=>'cinci');
var_dump ($vector);
?>
Pentru a șterge o pereche cheie/valoare se folosește funcția unset()
unset($vector[2]); //sterge cheia 2 din matrice

45
1.Var i a b i le P H P

unset($vector); //sterge întregul vector


Tablouri multidimensionale: sunt o listă de tablori cu o dimeniune mai mică
Ex
<?php
$Romania = array(
"Bucuresti" => array("Cartier Unirea"," Cartier Crangasi","Cartier Militari",....),
"Brasov" => array(),
"Timisoara" => array(.........),
..................................
);
?>

1.2. Variabile predefnite


PHP oferă un mare număr de variabile predefnite oricărui script care
rulează și sunt funcție de serverul pe care funcționează. Începând cu versiunea
PHP 4.2.0, valoarea default pentru directiva register_globals este of. Această
afectează setul de variabile predefnite disponibile în scop global.
De exemplu, pentru a obține DOCUMENT_ROOT vom folosi
$_SERVER['DOCUMENT_ROOT'] în loc de $DOCUMENT_ROOT cum era în cazul
în care register_globals erau on.
PHP Superglobals sunt variabile disponibile oriunde în script:
$GLOBALS conține referințe către toate variabilele care sunt disponibile în scop
global scriptului
$_SERVER variabile furnizate scriptului de către serverul web
$_GET variabile furnizate scriptului via HTTP GET (provin dintr-un formular
în care method = "GET")
$_POST variabile furnizate scriptului via HTTP POST (provin dintr-un formular
în care method = "POST")
$_COOKIE variabile furnizate scriptului via HTTP cookies
$_ENV variabile furnizate scriptului de către mediu
Variabile globale uzuale:
$_SERVER['REMOTE_ADDR'] Ex: adresa IP a vizitatorului
$_SERVER['HTTP_USER_AGENT
Ex: informații despre browserul utilizat
']
$_SERVER['HTTP_REFERER'] Ex: pagina vizitată anterior
$_SERVER['SERVER_NAME'] Ex: numele serverului
$_SERVER['SCRIPT_NAME'] Ex: numele scriptului

46
1. 3.V i z i b i li ta te a var ia b i le lo r

1.3. Vizibilitatea variabilelor


Vizibilitatea variabilelor depinde de contextul în care sunt defnite.
Majoritatea variabilelor din PHP sunt vizibile doar în blocul curent de
instrucțiuni. Orice variabilă folosită în interiorul unei funcții este limitată doar la
blocul funcției.
Ex: deoarece funcția folosește o variabilă declarată în afara ei echo nu va afșa
nimic, iar dacă are o variabilă locală cu același nume va afșa variabila locală.
<?php
$a=10;
function f1() { $=15;
echo "Valoarea a= $a !";
}
f1();
?>
Ex: aceeași funcție, dar acum declarăm variabila de tip global, motiv pentru care
echo va afșa corect
<?php
$a=10;
function f1() {
global $a; //declarăm variabila $a de tip global
echo "Valoarea a= $a !";
}
f1();
?>

1.4. Variabile statice


O altă caracteristică importantă a domeniului de vizibilitate a variabilelor
(scope note) este dată de variabila statică care există doar în blocul funcției
locale, dar NU își pierde valoarea atunci când este reluată execuția funcției.
Variabila își pierde valoarea atunci când este incheiat scriptul curent.
Ex: executarea succesivă a funcției va afșa tot timpul valoarea ”0”.
<?php
function static1() {
$a=0; echo $a; $a++;
}
static1(); echo "<br>";
static1(); echo "<br>";
static1();
?>
Ex: aceeasi funcție, dar declaram variabila ca find statică. De câte ori funcția va fi

47
1.Var i a b i le P H P

executată, ea va incrementa valoarea anterioară a variabilei $a


<?php
function static1() {
static $a=0; echo $a; $a++;
}
static1(); echo "<br>";
static1(); echo "<br>";
static1();
?>

1.5. Variabile referință


Câteodată este util să avem un nume variabil pentru o variabilă.
Ex:
<?php
$a="Mihai"; $$a="Ionescu";
echo "$a $Mihai";
?>
”Mihai” va deveni la rândul său un nume de variabilă - ”Mihai Ionescu”.
1.6. Funcții de tipul typeof
Există funcții care determină tipul variabilei.
Ex: verifcăm dacă variabila $a este de tip întreg
<?php
$a=19;
if (is_integer($a)) { echo '$a este intreg';}
else { echo '$a nu este intreg';}
?>

Ex: verifcăm dacă variabila $a este de tip număr cu virgulă mobilă


<?php
$a=3.14;
if (is_foat($a)) {echo '$a este numar cu virgulă mobilă';}
else { echo '$a nu este numar cu virgulă mobilă';}
?>
Ex: verifcăm dacă variabila $a este un tablou
<?php
$a = array('unu','doi','trei');
if (is_array($a)) {echo '$a este un tablou';}
else {echo '$a nu este un tablou';}

48
1.6.Funcții de tipul typeof

?>
Ex: tipuri de date
<?php
//TIPURI DE DATE
//boolean - 0 false , restul adevărat -0.00000006001 este TRUE
$a=-0.00000006001;
if($a) echo "TRUE <br/>"; else echo "FALSE<br/>";
//integer
$a=-123;
//reale
$a=-343.656;
//șiruri
$a='un sir';
$b=" --- alt sir ce contine și pe a: $a";
echo $a.$b; // concatenare șiruri
$c="<br/> ---".$a." ---- ";
echo $c;
//ARRAY (TABLOURI)
$a=array();
$a[0]=5; $a[2]=7; $a[3]=8; echo("<br/>");
unset($a[2]); // sterge pe $a[2] // unset $a sterge conținutul întregului tablou
for($i=0;$i<4;$i++) echo(" a[$i]=$a[$i]; ");
$a[]=9;
$a["unu"]=10;
echo("<br/>");
for($i=0; $i<11; $i++) echo(" a[$i]=$a[$i]; ");
//echo "a[unu]=".$a["unu"];
//tablouri asociative
echo("<br/>");
$b=array("unu"=>"galben", "doi"=>"verde", 2 => "albastru", "trei" =>3);
echo $b["unu"]; echo" ";
echo $b[2]; echo" "; echo $b["trei"];
//tablou asociativ cu doua dimensiuni
$c=array("t2"=>array(1=>3, 2=>"alb", "negru"=>45, 9=>10),
"s2"=>array("a"=>"r1")
);
echo("<br/>");
echo $c["t2"][2]; echo " ";
echo $c["s2"]["a"];
?>

49
2.Funcții în php

2. Funcții în php
Funcția este o secvență de cod ce poate fi utilizată de mai multe ori în
interiorul scripturilor și este prezentată în script prin declarația acesteia.
Funcția apelată va conține același număr de argumente ca și în declarație.
function f1($arg_1,$arg_2, $arg_n) {
echo "Ex.\n";
return $val;
}
unde:
f1 - este numele funcției,
$arg_1, $arg_2, ... , $arg_n - sunt argumentele funcției,
$val - este valoarea returnată de funcție.
Ex: construim o funcție care adună valorile a două variabile
<?php
function adunare($a,$b) { $suma=$a+$b; return $suma; }
$rezultat=adunare(10,5); echo $rezultat;
?>
Ex: o funcție care generează un tabel HTML cu o singură coloană.
<?php
function tabel($lin)
{echo "<table border=\"1\">\n";
for ($i=0; $i<$lin; $i++)
{echo "<tr><td>rândul ".$i."</td></tr>\n";}
echo "</table>";
}
tabel(10); //tabel cu 10 rânduri
?>
În PHP funcţiile pot fi defnite de către utilizator folosind următoarea
sintaxă:
function numef ($param1, $param2, ..., $paramN)
{ // bloc instrucțiuni }
În PHP o funcţie poate fi defnită oriunde în cadrul script-ului şi în
interiorul unei funcţii poate să apară orice secvenţă validă de cod care include
defnirea de alte funcţii şi defniţii de clase. Argumentele unei funcţii sunt
separate prin virgulă, iar transferul acestora se realizează prin valoare. Pentru ca
funcţia să returneze un rezultat, se utilizează construcţia return care primeşte ca
parametru o expresie care reprezintă valoarea funcţiei. În momentul în care este
întâlnită instrucțiunea return, execuţia funcţiei se încheie.

50
2.Funcții în php

2.1.1. Transmiterea parametrilor prin referinţă


Pentru a transmite parametrii unei funcţii prin referinţă, fapt care implică
modifcarea valorii parametrilor şi păstrarea noilor valori după ce execuţia
funcţiei s-a încheiat, se foloseşte operatorul '&' înaintea numelui parametrului
formal, în momentul defnirii funcţiei.
Ex:
<?php
function p_valoare($a) { $a = 1;}
function p_referinta(&$a) { $a = 1;}
$b = 0; p_valoare($b); echo "<br /> \$b = $b";
$b = 0; p_valoare(&$b); echo "<br /> \$b = $b";
$b = 0; p_referinta($b); echo "<br /> \$b = $b";
?>
//Rezultat: $b = 0 $b = 1 $b = 1

2.1.2. Parametri cu valori implicite


În PHP parametrii formali pot avea valori implicite; în cazul în care
parametrul actual lipseşte se va considera că are valoarea implicită.
Ex:
<?php
function inceput($s='abc')
{ return "Sirul este ".$s.".";}
echo inceput(); echo "<br>"; echo inceput("xyz");
?>
/* Rezultat:
Sirul este abc.
Sirul este xyz */
În cazul în care se folosesc parametri cu valori implicite, este necesar ca
orice parametru care are o valoare implicită să se afe în partea dreaptă a tuturor
parametrilor pentru care nu se folosesc valori implicite – idem limbajul C, în caz
contrar interpretorul PHP nu poate să decidă cărui parametru să-i atribuie
valoarea.
2.2. Valorile returnate de funcţii
Rezultatul obţinut după apelarea unei funcţii poate avea orice tip. O
funcţie poate să returneze chiar şi liste sau obiecte. În PHP există un caz special
de rezultat numit referinţă. Pentru ca o funcţie să poată returna o referinţă,
aceasta trebuie declarată folosindu-se operatorul '&' înaintea numelui funcţiei.
Acest operator trebuie să apară înaintea numelui funcţiei şi în momentul când o

51
2.Funcții în php

variabilă primeşte ca valoare referinţa rezultată din apelul funcţiei. În exemplul


următor se defneşte o funcţie al cărui rezultat îl constituie o referinţă:
Ex:
<?php
function &f1() { $x1=5; return $x1; }
$x2 = &f1(); //este necesară specifcarea faptului că
//întoarce o referință
echo $x2;
?>
Rezultat:5.

2.3. Numere aleatoare


Funcția rand() generează automat numere aleatoare. Aceasta poate primi
ca și parametri limita minimă sau/și maximă a numerelor generate.
Ex:
<?php
echo "numar generat aleator: ".rand()."<br>";
echo "numar generat aleator din intervalul 1-100: ".rand(1,100);
?>

2.4. Funcția de rotunjire


Funcția round() este pentru rotunjire și poate primi ca parametru
numărul de zecimale după rotunjire.
Ex:
<?php
echo "12,345067 rotunjit este: "round(12.345067)."<br>";
echo " 12,345067 rotunjit cu 2 zecimale este: "round(12.345067,2);
?>

52
3.Instrucţiuni de decizie

3. Instrucţiuni de decizie

3.1. Instrucţiunea if
Sintaxa:
if(<expresie>) instr1;
[else instr2;]
unde [ ...] semnifcă faptul că este opţional.
Ramura else este opţională.

TRU FALSE
E if (<expresie>)

instr.1 instr.1

Fig. III.-1. Instrucțiunea if


La întâlnirea instrucţiunii if, se evaluează <expresie>. Dacă valoarea
expresiei este true ( diferită de zero), se execută instrucţiunea 1; dacă valoarea
expresiei este false (egală cu zero), se execută instrucţiunea 2. Se execută doar una
dintre cele două instrucţiuni: fe instr1, fe instr2. După execuţia instrucţiunii if se
trece la execuţia instrucţiunii care urmează acesteia.
Instr1 şi Instr2 pot fi instrucţiuni compuse (blocuri), sau chiar alte
instrucţiuni de tip if (if-uri imbricate).
Exemplu:
<?php
$a=4; $b=3;
echo "$a=4<br>";
echo "$b=3<br>";
if ($a>$b) {echo "$a>$b"; }
?>
sau
<?php
$a=2; $b=9;
echo "$a=2<br>";
echo "$b=9<br>";
if ($a>$b) { echo "$a>$b";}
else {echo "$a<$b";}

53
3.Instrucţiuni de decizie

?>
Instrucțiunea elseif este o combinație între if și else. În cazul în care
condiția if nu este îndeplinită se introduce elseif care testează încă o condiție.
Dacă nu este îndeplinită a doua condiție, se execută declarația introdusă prin else.
if (conditia1) {
instructiuni executate daca este indeplinita conditia 1;
} elseif (conditia2) {
instructiuni executate daca este indeplinita conditia
2;
} else {
instructiuni executate daca nu este indeplinita
conditia 2;
}
Ex:
<?php
$a=10; $b=15;
if ($a<$b) {
echo "$a<$b";
} elseif ($a==$b) {
echo "$a==$b";
} else {
echo "$a>$b";
}
?>

3.2. Instrucţiunea stwitch


În unele cazuri este necesară o decizie multiplă specială. Instrucţiunea
switch permite acest lucru.
Dacă expresie=expresie_const_1
instrucţiune1;
[ieşire;]
Dacă expresie=expresie_const_2
instrucţiune2;
[ieşire;]
........................
Dacă expresie=expresie_const_n
instrucţiune_n;
Altfel instrucţiune_m;

54
3 . 2 . I n s t r u c ţ i u n e a s tw i t c h

case default
test expresie

instrucţiune m

instrucţiune 1
break

instrucţiune 2
break

instrucţiune n

Fig. III.-2. Instrucțiunea switch


Se testează dacă valoarea pentru expresie este una dintre constantele
specifcate (expresie_const_1, expresie_const_2, etc.) şi se execută instrucţiunea de
pe ramura corespunzătoare. În schema logică test_expresie este una din condiţiile:
expresie=expresie_const_1, expresie=expresie_const_2, etc.
Sintaxa:
switch (<expresie>)
{
case expresie_const_1: instructiune_1;[break;]
case expresie_const_2: instructiune_2;[break;]
................... ....
case expresie_const_n: instructiune_n;
[ default:instructiune_n; ]
}
Este evaluată <expresie> (expresie aritmetică), iar valoarea ei este
comparată cu valoarea expresiilor constante 1, 2, n, etc. (expresii constante =
expresii care nu conţin variabile).
Se execută instrucţiunea corespunzătoare acelei ramuri (instrucţiune_k),
unde expresie_const_k este egală cu rezultatul evaluării <expresie>.
Dacă se întâlneşte instrucţiunea break, parcurgerea este întreruptă şi se
va ieşi din blocul dat de switch.
Dacă nu este întâlnită instrucţiunea break, se parcurge şi instrucţiunea
următoare. În cazul în care valoarea expresiei nu este găsită printre valorile

55
3.Instrucţiuni de decizie

expresiilor constante, se execută cazul marcat cu eticheta default (opţională).


Ex:
int a=3,b=4,luna;
cin>>luna;
switch(luna)
{ case 1: a++; break;
case 2: {a--;b++;} break;
case 3: {a--;b--;}
case 4: a--;
default: {a=0;b=0;}
}
pentru luna=1, obţinem a=4, b=4
pentru luna=2, obţinem a=2, b=5
pentru luna=3, obţinem a=1, b=3
pentru luna=4, obţinem a=2, b=4
pentru luna>4, obţinem a=0, b=0.

56
4.Implementarea structurilor repetitive (ciclice)

4. Implementarea structurilor repetitive (ciclice)


Există două categorii de instrucţiuni ciclice: cu test iniţial şi cu test fnal.
4.1. Implementarea structurilor ciclice cu test iniţial -
Instrucţiunea for
Structura ciclică cu test iniţial este implementată prin instrucţiunile for şi
twhile. Instrucţiunea for implementează structura ciclică cu număr cunoscut de
paşi .
evaluare expresie1
ATÂT TIMP CÂT expresie2 este TRUE REPETĂ
begin
instrucţiune
evaluare expresie3
end

evaluare <expresie1>
(de obicei iniţializare contori)

FALSE
evaluare <expresie2>

TRUE

Instrucţiune 1
(blocul instr. for)

evaluare <expresie3>
(de obicei incrementare contori)

Fig. III.-3. Instrucțiunea for


Sintaxa:
for (expresie1; expresie2; expresie3)
instructiune;
Nu este obligatorie prezenţa expresiilor, ci doar a instrucţiunilor vide.
Exemple:

57
4.Implementarea structurilor repetitive (ciclice)

int a = 0;
for( int i = 0; i < 100; i++ ) a++;

int i,j,m,n,a,b;
for( i = 0; i < n; i++)
for( j = 0 ; j < m; j++ )
{ a += i*j;
if( i < j ) b = a; else b =- a;
}

int i = 0, a = 0;
for( ;i < 100; ) { i++; a++; }

Construcția cu foreach funcționează doar cu un vector generând erori


când sunt folosite variabile cu tipuri de date diferite sau variabile neinițializate.
Sintaxa este:
foreach ($vector as $cheie => $valoare) {
instructiuni de executat;
}

4.2. Implementarea structurilor ciclice cu test iniţial -


Instrucţiunea twhile
Sintaxa:
while(<expresie>)
instr1;

evaluare <expresie>
FALSE

TRUE

Instrucţiune 1
(bloc instr.)

Fig. III.-4. Instrucțiunea while


La întâlnirea acestei instrucţiuni, se evaluează expresie. Dacă aceasta are

58
4.2.Implementarea structurilor ciclice cu test
i n i ţ i a l - I n s t r u c ţ i u n e a tw h i l e
valoarea TRUE (diferită de ZERO), se execută instrucţiunea instr1. Se
reevaluează din nou valoarea expresiei. Dacă ea este tot TRUE, se repetă
instrucţiunea, etc. Astfel, instrucţiunea (corpul ciclului) se repetă atât timp cât
expresie are valoarea de adevăr TRUE. În momentul în care <expresie> are
valoarea de adevăr FALSE (sau egal cu ZERO), se iese din ciclu şi se trece la
următoarea instrucţiune din afara buclei twhile.
În cazul în care la prima evaluare a expresiei, aceasta are valoarea de
adevăr FALSE, corpul instrucţiunii twhile nu va fi executat niciodată.
Instrucţiunea/blocul de instrucțiuni din corpul ciclului while trebuie să
modifce valoarea expresiei, altfel va fi un „ciclu infnit”.
4.3. Implementarea structurilor ciclice cu test fnal -
Instrucţiunea do while
Sintaxa:
do instr1;
while(<expresie>)
Se execută instrucţiunea instr1 sau blocul de instrucţiuni. Se evaluează
apoi <expresie>. Dacă aceasta are valoarea TRUE, se execută din nou instr1 altfel
se iese din buclă. Se testează din nou valoarea expresiei. Se repetă execuţia
instrucţiunii instr1 atâta cât timp valoarea expresiei este TRUE. În cazul
instrucţiunii do twhile, corpul ciclului se execută cel puţin o dată.

Instrucţiune 1
(bloc instr.)

evaluare <expresie>
TRUE

FALSE

Fig. III.-5. Instrucțiunea do while


4.4. Instrucţiunile break și continue
Instrucțiunea break forţează ieşirea din interiorul unei bucle fără a se mai
ţine seama de condiţia de menţinere în buclă. Instrucţiunile situate în corpul
buclei după instrucţiunea break nu vor mai fi executate.

59
4.Implementarea structurilor repetitive (ciclice)

Instrucţiunea continue duce la ignorarea instrucţiunilor din buclă,


situate după aceasta, şi testarea din nou a expresiei de menţinere în buclă. În
cazul buclelor for se realizează si evaluarea celei de a treia expresii responsabilă
cu incrementarea contorilor.

Include și require sunt două funcții asemănătoare folosite pentru


includerea în paginile php a unor fșiere externe. Diferența între cele două funcții
constă în faptul că dacă execuția include eșuează scriptul generează o avertizare
dar funcționează în continuare, în timp ce în cazul execuției require se termină
executarea scriptului.
include "fsier1.php";
require "fsier2.html";

5. Lucrul cu șiruri
PHP conține zeci de funcții care lucrează cu șiruri. Această secțiune
descrie câteva funcții frecvent utilizate. Aceste funcții permit construcția unui șir,
eliminarea de secvențe de caractere dintr-un șir, operații de tip trim (eliminare
spații) conversie de șiruri etc.
Ex:
<?php
$s = " Acesta este un șir ";
$n = strlen($s); echo "<br /> Lungimea șirului este: $n";
$n = strlen($trim); echo "<br /> Lungimea șirului este: $n";
$trim = ltrim($s); // Elimina spatiile albe din partea stanga a șirului
$n = strlen($trim); echo "<br /> Lungimea șirului este: $n";
$trim = rtrim($s); // Elimina spatiile albe din partea dreapta a șirului
$n = strlen($trim); echo "<br /> Lungimea șirului este: $n";
$trim = trim($s); // Elimina spatiile albe din ambele parți a șirului
$n = strlen($trim); echo "<br /> Lungimea șirului este: $n";
?>
PHP furnizează patru funcții pentru compararea șirurilor. Fiecare funcție
returnează o valoare al cărei semn determină rezultatul comparației.
Ex:
<?php
$s1 = "abcd"; $s2 = "ABCE";
$rezultat = strcasecmp($s1, $s2);
echo "<br /> Functia strcasecmp a returnat $rezultat";
$rezultat = strcmp($s1, $s2);
echo "<br /> Functia strcmp a returnat $rezultat";
$rezultat = strncasecmp($s1, $s2, 3);

60
5.Lucrul cu șiruri

echo "<br /> Functia strncasecmp returnat $rezultat";


$rezultat = strncmp($s1, $s2, 3);
echo "<br /> Functia strncmp a returnat $rezultat";
?>
Funcția strcasecmp() a identifcat șirul "abcd" ca find mai mic decât
"ABCE", în schimb, funcția strcmp(), la fel ca și funcția strncmp(), a identifcat
șirul "abcd" ca find mai mare decât "ABCE". Aceasta s-a datorat diferenței
codurilor ASCII pentru litere mici și litere mari, cele cu litere mici au în secvența
ASCII o poziție superioară literelor scrise cu majuscule; litera 'A' are valoarea
ASCII 65, iar litera 'a' are valoarea ASCII 97. De asemenea, datele de ieșire arată
că funcția strncasecmp() a identifcat șirul "s1" ca egal cu "s2", deoarece au fost
luate în considerare doar primele trei caractere.
PHP include funcții care identifcă subșiruri și extrag părți dintr-un șir.
Ex: funcția strchr(s1,s2) ce returnează toate șirurile 's1' de la prima apariție a
șirului 's2' și până la sfârșit. Dacă 's1' nu este găsit, funcția returnează FALSE.
Funcția strstr() execută aceeași operație.
O operație frecvent utilizată în programare constă în găsirea unui subșir
și înlocuirea sa cu o valoare nouă; în acest sens, PHP are două funcții:
str_replace( si substr_replace().
Funcția str_replace(cauta, înlocuire, subiect) - caută în șirul 'subiect'
subșirul 'cauta'; dacă subșirul este gasit, returnează valoarea 'subiect', înlocuindu-
se prima aparitie a șirului 'cauta' cu 'înlocuire'.
Funcția substr_replace(subiect, înlocuire, start, lungime) -
returnează valoarea 'subiect', înlocuind subșirul care începe de la 'start' și având
lungimea 'lungime' cu șirul 'înlocuire'.

6. Sesiuni PHP
Sesiunea reprezintă o modalitate prin care PHP păstrează informaţii
atunci când se trece de la o pagină la alta.
Odată cu iniţializarea unei sesiuni, utilizatorul poate păstra anumite
variabile, chiar dacă vizitează în continuare şi alte pagini ale site-ului. În mod
implicit informaţia se păstrează până la închiderea browser-ului sau până în
momentul în care utilizatorul distruge explicit sesiunea curentă.
În momentul în care un utilizator s-a logat la site, PHP atribuie acestuia
un identifcator unic de sesiune: SID. Acest SID este înglobat într-un coockie cu
numele PHPSESSID şi trimis apoi către browserul utilizatorului. Dacă browser-ul
nu suportă cookie-uri sau acestea sunt dezactivate, atunci acest SID este adăugat
la adresa URL. În acelaşi timp, se creează pe server, un fşier cu numele SID. În
continuare, dacă utilizatorul doreşte să stocheze anumite informaţii, acestea vor fi
scrise în fşierul SID de pe server.

61
6.Sesiuni PHP

Sesiunile au următoarele avantaje:


• Pot fi folosite chiar dacă browserul utilizatorului nu suportă cookie-uri,
sau dacă acestea sunt dezactivate;
• Permit stocarea unui volum mai mare de informaţii în comparație cu
cookie-urile;
• Sunt mai sigure în raport cu cookie-urile, deoarece informaţiile nu sunt
transmise în mod repetat între client şi server.
Iniţializarea unei sesiuni se face cu funcţia session_start(). Această
funcție trebuie apelată la începutul script-ului PHP, deoarece apelul acestei
funcţii trebuie facut înaintea transmiterii către browser-ul Web a codului HTML.
Instrucțiunea session_start() nu este necesară dacă în fşierul de
confgurare php.ini, variabila session.auto_start are valoarea TRUE.
Ex:
<?php
echo "<br /> Identifcatorul sesiunii curente SID este:". session_id();
// Initializeaza datele sesiunii
session_id('124abc');
session_start();
echo "<br /> Identifcatorul sesiunii curente SID = ". session_id();
// Sterge tabloul $_SESSION
unset($_SESSION);
// Sterge datele de sesiune din server
session_destroy();
echo "<br /> Sesiunea curenta a fost inchisa";
?>
<?php
error_reporting(E_ALL); ini_set('display_errors', '1');
session_id('119abc');
echo "<br /> Identifcatorul sesiunii curente SID este:". session_id();
session_id('120abc');
$a='8';
$y='TEST1';
session_start();
$_SESSION['a'] = $y;
$x=$_SESSION['a'];
echo "<br/>a=$a<br/>";
echo "<br/>a=$x<br/>";
echo "<br /> Identifcatorul noii sesiunii SID = ". session_id();
?>

62
I V. I n t r o d u c e r e î n t ra n s f e r u l d e d a t e c l i e n t - s e r v e r

IV. Introducere în transferul de date client-server


1. Preluarea datelor din formularele HTML

Eticheta form din HTML are atributele action și method, iar fecare
câmp din formular conține un nume name sau/și un identifcator id. Atributele
sunt:
 action indică fșierul care prelucrează datele introduse în formular când
este apăsat butonul Trimite
 method indică modul în care datele sunt transmise către server pentru
prelucrare și poate avea valorile:
➔ POST când datele trimise nu sunt vizibile utilizatorului;
➔ GET când datele sunt adăugate la adresa URL.
Metoda POST permite trimiterea unei cantități mai mari de date decât
metoda GET, însă metoda GET este mai rapidă.
 name este un atribut care identifcă datele introduse în fecare câmp al
formularului.
Pentru un câmp cu name="nume" și method="POST" fșierul indicat de
action va prelua datele introduse în câmpul "nume" prin: $_POST["nume"];
Ex: formular cu un câmp și scriptul php de preluare a datelor
<!-- t1.html -->
<html><body><form action="t1.php" method="POST">
Nume: <input type="text" name="nume"><br>
<input type="submit" value="Trimite">
</form></body></html>
/* urmează fșierul t1.php */
<?php
$nume=$_POST["nume"];
echo $nume;
?>

1.1. Verifcarea datelor introduse în formular


Verifcarea completării datelor se poate realiza și pe partea de server.
Ex: folosim același formular, dar adaugăm partea de verifcare
<?php
$nume=$_POST["nume"];
if ($nume=="") {echo "Campul nume nu este completat";}
else { echo $nume;}
?>

63
1.Preluarea datelor din formularele HTML

Partea de verifcare poate avea mai multe condiții simultane.


Ex: același formular, dar partea de verifcare are două condiții legate prin
operatorul || (OR)
<?php
$nume=$_POST["nume"];
if (($nume=="") || (strlen($nume)<2))
{echo "Campul nume nu este completat corect";}
else {echo $nume;}
?>
În acest mod se pot prelua date și realiza verifcări pentru fecare câmp
din cadrul formularului.
Ex:
fșierul fx1.html
<html><form action="fx1.php" method="post">
Nume: <input type="text" name="e_nume" /> <br/>
Varsta: <input type="text" name="e_varsta" /> <br/>
Inaltime: <input type="text" name="e_inaltime" /> <br/>
<input type="submit" name="b_trimite" value="Trimite date" />
</form></html>
fșierul fx1.php
<?php
$nume=$_POST['e_nume'];
$varsta=$_POST['e_varsta'];
$inaltime=$_POST['e_inaltime'];
echo
"<table border='1'>
<tr><td>DATE</td> <td>VALORI</td></tr>
<tr><td>Nume</td><td>$nume</td></tr>
<tr><td>Inaltime</td><td>$inaltime</td></tr>
<tr><td>Varsta</td><td>$varsta</td></tr>
</table>";
?>

2. Conexiunea cu bazele de date (conexiunea cu PostgreSQL)


Conexiunea cu PostgreSQL se poate realiza prin funcțiile din bibliotecile
PHP. Pentru aceasta considerăm un exemplu în care citim datele dintr-un form
HTML, le transmitem către server, iar server-ul creează o pagină HTML cu
tabelul pe care o transmite către client.
Pentru început, se lansează un bloc de instrucțiuni SQL pentru crearea
acestui tabel în PostgreSQL. Tabelul conține un câmp de tip ”autoincrement” -a,

64
2.Conexiunea cu bazele de date (conexiunea cu
PostgreSQL)
un câmp de tip șir de caractere -b și un câmp cu date de tip întreg -c.
CREATE SCHEMA cs;
CREATE TABLE cs.t1(a serial PRIMARY KEY, b varchar(30), c int);
-- adauga cateva valori în tabel
INSERT INTO cs.t1(b,c) VALUES('A1',10),('A2',11),('A3',13);
Construim un form HTML
<!--fșier ibd1.html -->
<html> <form action="ibd1.php" method="post">
B(text): <input type="text" name="e_b" /> <br/>
C(nr): <input type="text" name="e_c" /> <br/>
<input type="submit" name="b_adauga" value="Adauga" />
</form> </html>
Form-ul conține două controale/etichete de tip text (referite prin numele
e_b și e_c) și un buton de tip ”submit”- b_adauga ce transmite datele din cadrul
form-ului către server.
Acesta va afșa:

//fșier ibd1.php
<?php
error_reporting(E_ALL);ini_set('display_errors', '1');
function conexiune($host,$port,$dbname,$user,$password)
{ //pg_connect - funcție php ptr. conectarea la BD
$conexiune1 = pg_connect ("host=$host port=$port dbname=$dbname
user=$user password=$password") or
die("Nu se poate conecta: " .
pgsql_last_error());
// pgsql_last_error() -- întoarce descrierea erorii, de la serverul PostgreSQL,
//aceasta este concatenată cu șirul din față prin operatorul '.'
return $conexiune1;
}
$cda_sql="select * from cs.t1";
//realizare conexiune
$conexiuneR1 = conexiune ('localhost','5435','postgres','postgres','abcd');

65
2.Conexiunea cu bazele de date (conexiunea cu
PostgreSQL)
//adaugare
$b=$_POST['e_b'];$c=$_POST['e_c'];
pg_query($conexiuneR1,"INSERT INTO c13.t1(b,c)VALUES('".$b."',".$c." );");
//citire tabel
$rezultat = pg_query($conexiuneR1,$cda_sql);
//preluare număr înregistrări
$nr_inregistrari=pg_num_rows($rezultat);
//extrage numărul de câmpuri
$nr_campuri=pg_num_felds($rezultat); echo "Nr.inregistrari: $nr_inregistrari<br/>";
//extrage denumirile primelor trei câmpuri
$c1= pg_feld_name($rezultat,0); $c2= pg_feld_name($rezultat,1); $c3=
pg_feld_name($rezultat,2);
echo "Campurile: $c1 $c2 $c3<br/>";
//extrage datele din rezultatul interogării în tabloul $date_matrice
$date_matrice = pg_fetch_all($rezultat);
//test
echo $date_matrice[1]["b"];//al doilea rând, câmpul b;
//construiește un tabel HTML dinamic
echo" <table border='1'>"; echo"<tr>";
for($i=0;$i<$nr_campuri;$i++)
echo "<td>".pg_feld_name($rezultat,$i)."</td>";
echo"</tr>";
for($i=0;$i<$nr_inregistrari;$i++)
{ echo "<tr>";
for($j=0;$j<$nr_campuri;$j++)
echo "<td>".$date_matrice[$i][pg_feld_name($rezultat,$j)]."</td>";
echo "</tr>";
}
echo"</table>";
?>

După apăsarea butonului b_adauga , se va afșa:

66
2.Conexiunea cu bazele de date (conexiunea cu
PostgreSQL)

3. Noțiuni introductive despre AJAX


AJAX (Asynchronous JavaScript and XML) reprezintă un grup de
tehnologii ce au fost introduse în anul 2005 de către compania Google. Înainte de
AJAX, pentru fecare interacțiune a unei aplicații web client cu serverul, pagina
web client trebuia complet reîncărcată.
INTERNET

Eveniment Transmitere cerere Procesează


către client Informația
returnată
Constituire obiect
XMLHttpRequest Construiește
răspunsul Actualizează
Pagina HTML
Transmitere cerere
Procesează cererea
către server Client-Browser
HttpRequest
Client-Browser Server

INTERNET

Fig. IV.-1. Fluxul informațional pentru AJAX


Cu tehnologiile AJAX pot fi încărcate și modifcate doar anumite parți din
pagina web din browser-ul clientului fără a reîncărca întreaga pagină web de pe

67
3.Noțiuni introductive despre AJAX

server.
AJAX preia de la server structuri de tip text (plain, XML, HTML) și nu
are importanță limbajul utilizat pe partea de server. Toate script-urile Ajax
folosesc obiectul XMLHtpRequest. Scopul obiectului XMLHtpRequest este de a
permite JavaScript să formuleze cereri HTML și să le trimită către server, în
paralel cu execuția altor cereri.
3.1. Metode din cadrul obiectului XMLHttpRequest
Inițializarea comunicației cu server-ul presupune deschiderea
comunicației prin metoda open. Aceasta are sintaxa:
open(method, url, async)
unde:
 method poate fi ”GET” sau ”POST”. Metoda ”GET” este mai rapidă, însă
transferul parametrilor este realizat în clar și prezintă vulnerabilități din
punct de vedere al securității;
 url localizează fșierul de pe server ce preia mesajele;
 async are valoarea de adevăr true pentru transmisie asincronă și false
pentru transmisie sincronă.
Transmiterea către server a informației este asigurată de către funcția
membră:
send(string)
unde string conține informația de transmis în cazul metodei ”POST” (pentru
metoda ”GET” informația se transmite odată cu locația, în cadrul argumentului
url din metoda open).
Citirea rezultatului pentru transmisia sincronă ( async = false ) se
realizează direct prin citirea proprietății:
responseText / responseXML
din cadrul obiectului XMLHtpRequest, execuția aplicației find blocată până la
obținerea răspunsului.
Citirea rezultatului pentru transmisia asincronă ( async = true ) se
realizează după ce proprietatea status are valoarea 400, iar proprietatea
readyState are valoarea 4.
Valorile posibile pentru proprietatea readyState din cadrul obiectului
XMLHtpRequest sunt:
 0 – cerere neinițializată;
 1 – este realizată conexiunea cu serverul;
 2 – cerere transmisă către server;
 3 – cerere în curs de procesare de către server;
 4 – cerere fnalizată și răspunsul este fnalizat.
Valorile posibile pentru proprietatea status din cadrul obiectului

68
3.1.Metode din cadrul obiectului XMLHttpRequest

XMLHtpRequest sunt:
 200 – OK – adresa a fost găsită;
 404 – NOK – adresa nu a fost găsită.

3.2. Exemplu
Sunt preluate două numere și sunt transmise către server, sever ce
întoarce suma acestora. Actualizarea paginii client nu se va face prin reîncărcarea
acesteia în întregime ci doar se actualizează tag-ul ce conține rezultatul.
Exemplul este format din trei fșiere:
 ajx1.html conține form-ul ce preia cele două valori și afșează rezultatul
într-un tag cu id-ul rezultat;
 ajx2.js conține codul pentru implementare AJAX;
 ajx3.php efectuează operația cu cele două numere și transmite rezultatul
către client.
Conținutul fșerului ajx1.html este:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"htp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- defnește namespase pentru xml -->
<html xmlns="htp://www.w3.org/1999/xhtml">
<head>
<!-- titlul ferestrei -->
<title>Exemplu transfer cu ajutorul AJAX</title>
<!-- preluare funcție ce implementează tehnologiile AJAX -->
<script type="text/javascript" src="ajx2.js"></script>
</head>
<body> <!-- cele două controale de editare -->
A = <input type="text" id="id_A" />
B = <input type="text" id="id_B" />
<br />
<input type="submit" value="Calculeaza" onclick="javascript:calculeaza();" />
<br />
<!-- Afșarea rezultatului cu id-ul rezultat într-un tag de tip paragraf -->
<p id="rezultat" />
</body>
</html>

Fișierul de implementare AJAX - ajx2.js -conține funcțiile de comunicare


client-server și server-client și are structura:
var xmlHtp = creeazaXmlHtp();
//Creează obiectul XMLHtpRequest și apoi îl returnează
function creeazaXmlHtp()

69
3.Noțiuni introductive despre AJAX

{ var xmlHtp;
if(window.ActiveXObject) // pentru IE
{ try //încearcă execuția
{ xmlHtp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e) //în caz de eșec/eroare
{ xmlHtp = false;
}
}
//Pt browsere compatibile cu mozilla
else
{ try
{ xmlHtp = new XMLHtpRequest();
}
catch (e)
{ xmlHtp = false;
}
}
if (!xmlHtp)
alert("Nu s-a putut crea obiectul XMLHtpRequest!");
else
return xmlHtp;
}
//--------------------------------------------------------------------------------------------
//Explicitarea funcției calculează
function calculeaza()
{ // verifcăm dacă xmlHtp este liber
if (xmlHtp.readyState == 4 || xmlHtp.readyState == 0)
{ //obținem cele două valori ale numerelor
var val_A = document.getElementById('id_A').value;
var val_B = document.getElementById('id_B').value;
/* se execută script-ul php de calcul, valorile se transmit ca paramentri prin
metoda GET*/
xmlHtp.open("GET", "ajx3.php?id_A=" + val_A+"&id_B="+val_B, true);
/*defnim functia care se va ocupa de manipularea rezultatului primit de la
script-ul php */
xmlHtp.onreadystatechange = obtineRezultat;
// trimitem cererea catre server
xmlHtp.send(null);
}
}
//------------------------------------------------------------------------------------------------
//funcția callback care primeste rezultatul de la php - obtineRezultat

70
3.2.Exemplu

function obtineRezultat()
{ // daca rezultatul este obtinut
if (xmlHtp.readyState == 4)
{ // status = 200 =>> cererea a fost rezolvată cu succes
if (xmlHtp.status == 200)
{ // se extrage rezultatul
raspuns = xmlHtp.responseText;
//se modifcă valoarea tag-ului paragraf cu rezultatul
document.getElementById("rezultat").innerHTML = '<b> Suma =' + raspuns
+ '</b>';
}
// altfel Err.
else
{ alert("Eroare comunicare server: " +xmlHtp.statusText);
}
}
}
Calculele se realizează efectiv în fșierul PHP: ajx3.php.
<?php
echo $_GET['id_A']+$_GET['id_B'];
?>

71
V. E x e m p l u p r i v i n d a c c e s a r e a b a z e l o r d e d a t e
P o s t g r e S Q L d i n c a d r u l f r a m e tw o r k - u l u i q o o x d o o

V. Exemplu privind accesarea bazelor de date PostgreSQL


din cadrul frametwork-ului qooxdoo
Pentru exemplifcare, se va construi un tabel ce rva fi interogat și
actualizat prin utilizarea mecanismelor RPC (Remote Procedure Call) puse la
dispoziție atât prin clase javascript din cadrul qooxdoo, cât și prin clase PHP.
Pentru acest exemplu s-au utilizat clasele qooxdoo ver.5.01.
În vederea testării este necesară instalarea unui server de baze de date
PostgreSQL și a unui server Apache+PHP. Server-ul Apache+PHP poate fi
instalat prin lansarea utilitarului din cadrul pachetelor PostgreSQL: Application
Stack Builder. Directorul, pe server, în care vor fi copiate aplicațiile, poate fi cel
implicit: ../PostgreSQL/apache/twtwtw.

1. Dezvoltarea pe partea de server - dezvoltarea claselor PHP


în vederea comunicației prin RPC
Pentru comunicarea cu server-ul de date PostgreSQL sunt utilizate
funcțiile native de comunicație cu PostgreSQL din cadrul PHP. Clasele prezentate
au la bază dezvoltările date de Sergio Vaccaro <sergio@inservibile.org>. Codul
de interfațare adaptat qooxdoo – PHP - PostgreSQL este structurat în două
fșiere de tip PHP. Primul fșier (jevi_server.php) rezolvă problema apelului. Este
instanțiată clasa jevi_clase și este apelat handler-ul de evenimente pentru
mecanismul RPC.
//jevi_server.php
<?php
require_once 'jsonRPCServer.php';// preluare de la <sergio@inservibile.org>
require 'jevi_clase.php';

$x = new jevi_clase();
jsonRPCServer::handle($x)
or print 'nici o cerere';
?>
Celălalt fșier asigură formarea și execuția comenzilor SQL. Acesta
cuprinde funcții precum:
function conexiune($host,$port,$dbname,$user,$passtword) –
asigură conectarea cu baza de date ce are parametrii de conexiune dați în cadrul
argumentelor;
function recCount($db_conn,$pageNo,$pageSize,$cda_sql) -
întoarce numărul total de înregistrări;
function sel($db_conn,$pageNo,$pageSize,$cda_sql) - lansează o

72
1.Dezvoltarea pe partea de server - dezvoltarea
claselor PHP în vederea comunicației prin RPC
interogare și întoarce rezultatul corespunzător paginii selectate;
public function selectie($par) - preia comanda pentru selecție
(SELECT), realizează legătura cu serverul de baze de date și construiește
interogarea SQL pentru selecție (SELECT);
public function comanda($par) - preia comanda pentru o operație
SQL de tip INSERT/UPDATE/DELETE, realizează legătura cu serverul de baze de
date și construiește interogarea SQL pentru INSERT/UPDATE/DELETE.
Pentru legătura cu serverul PostgreSQL au fost utilizate funcțiile PHP:
• pg_connect("sir conexiune”) - funcție conectare la serverul PostgreSQL,
întoarce o structură ce conține datele specifce conexiunii;
• pgsql_last_error() - întoarce ultima eroare generată de server;
• pg_query($db_conn, $cda_sql) – lansează comenzile din string-ul
identifcat prin variabila $cda_sql pentru conexiunea dată de variabila
$db_conn, întoarce rezultatul interogării, (rezultatul conține atât datele
rezultate în urma interogării, cât și informații auxiliare rezultatului – de
exemplu denumirile câmpurilor, numărul acestora, tipul de date etc.);
• pg_num_rotws($result) – extrage numărul de înregistrări din variabila
setată în urma apelului funcției pg_query();
• pg_num_felds($result) – extrage numărul de câmpuri din variabila setată
în urma apelului funcției pg_query();
• pg_fetch_result($result, $i, $j) – extrage valoarea din tabloul rezultat
pentru câmpul j și înregistrarea i din rezultatul interogării;
• pg_afected_rotws($result) – întoarce numărul de înregistrări ce au fost
procesate în urma unei comenzi de tip UPDATE sau DELETE.
Fișierul este detaliat în cele ce urmează:
//jevi_clase.php
<?php
/**
* Interfata WEB PostgreSQL
* @*/
error_reporting(E_ALL); ini_set('display_errors', '1');
header('Content-type:text/javascript;charset=UTF-8');
//-------------------------------------------------------------------------------------------
function conexiune($host,$port,$dbname,$user,$password)
{$db_conn=null;
$db_conn = pg_connect("host=$host port=$port dbname=$dbname
user=$user password=$password") or
die("Conectare esuata: " . pgsql_last_error());
return $db_conn;
}
//------------------------------------------------------------------------------------------------

73
1.Dezvoltarea pe partea de server - dezvoltarea
claselor PHP în vederea comunicației prin RPC
//numărul de înregistrări
function recCount($db_conn,$pageNo,$pageSize,$cda_sql)
{$result = pg_query($db_conn,$cda_sql);
//nr. toatal de înreg. în vederea realizării paginației
$totalRec=pg_num_rows($result);
return $totalRec;
}
//-------------------------------------------------------------------------------------------------
---
//funcția de interogare
function sel($db_conn,$pageNo,$pageSize,$cda_sql)
{$retArray=array();
$ax=array();
if($pageSize>0)
{$totalRec=recCount($db_conn,$pageNo,$pageSize,$cda_sql);
//$ax[0]=$totalRec;
if($totalRec<1) return null;
if($totalRec<$pageSize) $nrInreg=$totalRec; else $nrInreg=$pageSize;
if($pageNo<1||$pageNo>ceil(($totalRec/$pageSize))) { $pageNo = 1;}
/* refacerea interogarii doar pentru pagina solicitata de client prin daugarea
comenzilor SQL OFFSET (nr. primei linii din cadrul rezultatului selectat) si LIMIT
(nr. max de inreg ce poate f transmis catre client) */
$sql_ = $cda_sql." OFFSET " . ($pageNo - 1)*$pageSize . " LIMIT " . $pageSize;
}
else
$sql_ = $cda_sql;
//executie interogare fnală
$result = pg_query($sql_);
$eroare=array();
if(!$result)
{$eroare[0]=pg_last_error($db_conn); return $eroare;}
$nrCampuri=pg_num_felds($result);
//if (!$result) { return null;}
//preluarea într-un array a datelor din resursa cu rezultatul
for($i=0;$i<$nrInreg;$i++)
for($j=0;$j<$nrCampuri;$j++)
$ax[$i][$j]=pg_fetch_result($result, $i, $j);
return $ax;
}
//-----------------------------------------------------------------
//NOTA: 1. Nu se pot executa apeluri imbricate ale fct. din clasa serviciu
// 2. NU se pot transmite param. array initializati prin =>
//-------------------------------------------------------------------------------------------------

74
1.Dezvoltarea pe partea de server - dezvoltarea
claselor PHP în vederea comunicației prin RPC
--
class jevi_clase{
//-----------------------------------------------------------------------------------
//test comunicatie server php
public function testphp($p)
{$c=array();
$c[0]=$p[0]+$p["unu"]; $c["minus"]=$p[0]-$p["unu"];
return $c; }
//-------------------------------------------------------------------------------------------
function conexiune2($host,$port,$dbname,$user,$password)
{$db_conn=null;
$db_conn = conexiune($host,$port,$dbname,$user,$password);
return $db_conn;
}
//-------------------------------------------------------------------------------------------------
--
//select
public function selectie($par)
{$arr=array(); $arr[0]=55; //in cazul in care interogarea esueaza
$db_conn=null;
$db_conn=conexiune($par["host"],$par["port"],$par["dbname"],$par["user"],
$par["password"]);
if(!db_conn) return null;
$arr[0]=$par["port"];
$arr=sel($db_conn,$par["pageNo"],$par["pageSize"],$par["cda_sql"]);
return $arr;
}
//--------------------------------------------------------------------------------
//intoarce nr. de inreg. afectate: insert,update,delete
public function comanda($par)
{ $arr=array(); $db_conn=null;
$db_conn=conexiune($par["host"],$par["port"],$par["dbname"],$par["user"],
$par["password"]);
if(!db_conn) return null;
$result = pg_query($par["cda_sql"]); if (!$result) { return null;}
$cmdtuples = pg_afected_rows($result);
return $cmdtuples;
}
}
?>
Pentru utilizarea acestora se va crea un director ce va conține fșierele
jevi_clase.php și jevi_server.php: ../PostgreSQL/apache/twtwtw/jevi_php . Tot în acest

75
1.Dezvoltarea pe partea de server - dezvoltarea
claselor PHP în vederea comunicației prin RPC
director se vor copia și fșierele jsonRPCServer.php și jsonRPCClient.php oferite
de Sergio Vaccaro <sergio@inservibile.org> .
Din interfața client or fi lansate funcțiile de tip public din cadrul clasei
jevi_clase: selectie și comanda.
Pentru crearea tabelului - din aplicația de test:
CREATE DATABASE test_qooxdoo;
CREATE SCHEMA s1;
CREATE TABLE s1.t1( a1 character varying(20) NOT NULL, a2 integer, a3
numeric, a4 date, CONSTRAINT t1_pkey PRIMARY KEY (a1);
Se va testa trasferul de date pentru date de tip: șir de caractere, întreg,
real și dată calendaristică.

2. Dezvoltarea pe partea de client – dezvoltarea interfeței prin


utilizarea claselor qooxdoo
Aplicația javascript va conține un tabel ce poate fi editat. Interfața
realizată este arătată în fgura următoare.
Sunt implementate operațiile:
• Interogare prin utilizarea modului RPC asincron (Qery ASINCRON);

Fig. V.-1. Interfață testare comunicarție prin utilizarea RPC


• Interogare prin utilizarea modului RPC sincron (Qery SINCRON);
• Salvarea liniei selectate ca o nouă linie (SALVEAZA O NOUA LINIE);
• Sterge linia selectată (STERGE LINIA);
• Adaugă o linie nouă în tabel;
• Actualizează linia curentă cu noile date.

76
2.1.Noțiuni introductive privind crearea
scheletului unei aplicații qooxdoo
2.1. Noțiuni introductive privind crearea scheletului unei aplicații
qooxdoo
Framework-ul qooxdoo cuprinde un set de clase dezvoltate în javascript
ce permite creare unei aplicații WEB client. Acesta este opensource și poate fi
descărcat de la adresa www.qooxdoo.org. Framework-ul qooxdoo utilizează rutine
scrise în pyton 2.7 în vederea optimizării aplicației.
În acest sens se lansează comanda pentru crearea scheletului aplicației
qooxdoo:
create-application.py --name untabelpg --out "D:/PostgreSQL/apache/www"
Aceasta s-a creat în directorul …/twtwtw pentru o testare mai simplă. De
exemplu, în debuger-ul din cadrul Google Chrome se pot urmări datele din fecare
obiect rezultat prin instanțierea claselor ce moștenesc clase din cadrul qooxdoo.
Din cadrul directorului cu scheletul aplicației se lansează comanda:
generate.py source-all
Această comandă va colecta clasele qooxdoo necesare pentru aplicația
”template”. În urma acestei execuții se poate deschide aplicația de start
(”template”) prin fșierul ..twtwtw/untabelpg/source/index.html.
Pentru testarea claselor php este necesar ca deschiderea aplicației, în
browser, să se realizeze la adresa: htp://localhost:8080/untabelpg/source/.
La fnalizarea aplicației, aceasta poate fi optimizată pentru ca atunci când
este pusă pe server să nu necesite și kit-ul qooxdoo, ci numai fșierul javascript
rezultat și resursele aferente. Chiar dacă aplicația cuprinde mai multe fșiere
javascript, rezultatul va fi într-un singur fșier javascript optimizat prin utilizarea
unor rutine în pyton 2.7. Directorul ce se va copia pe server va fi cel apărut în
urma execuției comenzii:
generate.py build
și va avea numele implicit twtwtw/untabelpg/build (ulterior se poate redenumi).
Stuctura directoarelor din cadrul qooxdoo poate fi schimbată prin
modifcarea fșierelor de confgurare din cadrul kit-ului qooxdoo.
Fiecare clasă javascript creată va moșteni una dintre clase qooxdoo, iar
pentru fecare clasă vom avea un fșier cu același nume cu clasa.
2.2. Descrierea codului aplicației ”untabelpg”
Aplicația are două clase: untabelpg.Application și untabelpg.w_main0,
deci vor fi două fșiere ce vor conține codul sursă: Application.js și w_main0.js.
2.2.1. Clasa ”untabelpg.Application”
Aceasta este clasa din care este lansată aplicația. Codul clasei este:

77
2.Dezvoltarea pe partea de client – dezvoltarea
interfeței prin utilizarea claselor qooxdoo
qx.Class.defne("untabelpg.Application",
{/*clasa provine din qx.application.Standalone
specifcă interfețelor WEB ce au ferestre cu aspect DESKTOP*/
extend : qx.application.Standalone,
members :
{ /*funcția principală a clasei - este apelată
în momentul instanțierii clasei */
main : function()
{ // apel constructor clasa de bază
this.base(arguments);
//creare obiect fereastra principală (unica fereastră)
var win_main0 = new untabelpg.w_main0;
// setare mod afșare fereastră (Grow -permite redimensionarea automată)
win_main0.setLayout(new qx.ui.layout.Grow());
//lățimea inițială a ferestrei - în pixeli
win_main0.setWidth(300);
//înălțimea inițială a ferestrei - în pixeli
win_main0.setHeight(600);
// ascunde butonul de minimizare
win_main0.setShowMinimize(false);
// adăugare obiect fereastră
this.getRoot().add(win_main0, {left:20, top:20});
//deschidere fereastră
win_main0.open();
}
}
});

2.2.2. Clasa ”untabelpg.w_main0”


Această clasă este specifcă ferestrei principale și are codul:
qx.Class.defne("untabelpg.w_main0",
{ //moștenește clasa fereastră din qooxdoo
extend : qx.ui.window.Window,
//constructorul clasei
construct : function()
{//apel constructor clasa de bază
this.base(arguments, "untabelpg");
//se defnește un mod de prezentare format din 4 linii și 2 coloane
var layout3 = new qx.ui.layout.Grid(4, 2);
layout3.setRowFlex(1, 1);layout3.setColumnFlex(1, 1);
//pentru fecare control este necesar un mod de prezentare (layout
)

78
2.2.Descrierea codului aplicației ”untabelpg”

//layout -ul stabilește cum sunt afșate controalele din interiorul acestuia
var layoutTabX = new qx.ui.layout.Grow();
//gestionar de controale
var container = new qx.ui.container.Composite(layoutTabX);
this.add(container, {edge: 0});
//se instanțiază o clasă pentru afșarea unui control de tip ”NOTE-TAB”
var tabX=new qx.ui.tabview.TabView();
container.add(tabX);
//instanțierea primului control de tip ”TAB” din cadrul ”NOTE-TAB”
var page3 = new qx.ui.tabview.Page("TEST");
page3.setLayout(layout3);page3.setPadding(10);tabX.add(page3);
this.add(container, {left:40, top:40});
//comunicatia - funcție defnită în cadrul constructorului clasei
var showDetails = function(details) {
window.alert(
"origin: " + details.origin +
"; code: " + details.code +
"; message: " + details.message
);
};
//instanțierea și adăugarea butoanelor
var b1 = new qx.ui.form.Buton("ADAUGA LINIE NOUA", "");
page3.add(b1,{row:0,column:0});
var b2 = new qx.ui.form.Buton("ACTUALIZEAZA LINIA", "");
page3.add(b2,{row:0,column:1});
var b3 = new qx.ui.form.Buton("STERGE LINIA", "");
page3.add(b3,{row:1,column:1});
var b4 = new qx.ui.form.Buton("SALVEAZA O NOUA LINIE",
"").set({allowShrinkX: true,allowShrinkY: true,paddingTop: 3});
page3.add(b4,{row:1,column:0});
var b5 = new qx.ui.form.Buton("Qery ASINCRON", "").set({allowShrinkX:
true,allowShrinkY: true, padding: 3 });b5.addState("default");
page3.add(b5,{row:2,column:1});
var b6 = new qx.ui.form.Buton("Qery SINCRON", "").set({allowShrinkX:
true,allowShrinkY: true, padding: 3 });
page3.add(b6,{row:2,column:0});
/*crearea modelului pentru controlul de tip tabel/grid - acesta gestionează modul de
afșare a datelor*/
untabelpg.w_main0.tableModelX = new qx.ui.table.model.Simple();
//sunt defnite afșările pentru coloanele tabelului
untabelpg.w_main0.tableModelX.setColumns([ "No", "Data char", "Data
int","Data foat","Data date"]);
//este instanțiat și controlul tabel și este asociat cu modelul instanțiat anterior

79
2.Dezvoltarea pe partea de client – dezvoltarea
interfeței prin utilizarea claselor qooxdoo
untabelpg.w_main0.table = new
qx.ui.table.Table(untabelpg.w_main0.tableModelX).set({ decorator: null,
allowGrowX: true});
untabelpg.w_main0.tableModelX.setColumnEditable(1, true);
untabelpg.w_main0.tableModelX.setColumnEditable(2, true);
untabelpg.w_main0.tableModelX.setColumnEditable(3, true);
untabelpg.w_main0.tableModelX.setColumnEditable(4, true);
untabelpg.w_main0.tableModelX.setColumnEditable(5, true);
/*este adăugat tabelul pe rândul al patrulea și prima coloană și se va extinde în
dreapta cu încă două coloane */
page3.add(untabelpg.w_main0.table,{row:3,column:0, colSpan: 2});
//-------------------------------------------------------------------------------------------
//funcție ce răspunde la evenimentul de ”apăsare” pentru butonul b1
b1.addListener("execute", function(e) {
/*defnește variabila c ca find un tablou și se inițializează cu valoarea unei
înregistrări */
var c=[[0,'-',0,0,new Date(),true]];
//adaugă în cadrul modelului înregistrarea dată prin variabila c
untabelpg.w_main0.tableModelX.addRows(c);
});
//-------------------------------------------------------------------------------------------

//funcție ce răspunde la evenimentul de ”apăsare” pentru butonul b2


b2.addListener("execute", function(e) {
// sunt defniți parametrii de conectare
var par={"host":"localhost", "port":"5437", "dbname":"test_qooxdoo",
"user":"postgres", "password":"abcd", "pageNo":"1", "pageSize":"0", "cda_sql":"---"};
//Se va pune pageSize:0 pentru UPDATE, DELETE, INSERT, RAISE EXCEPTION !
//identifcă înregistrarea selectată
var recno=untabelpg.w_main0.table.getFocusedRow();
//preia în variabila recdata un tabel
var recdata=[];
recdata.push(untabelpg.w_main0.tableModelX.getRowData(recno));
//actualizează valorea comenzii SQL din cadrul tabloului
par["cda_sql"]="UPDATE s1.t1 SET a2="+recdata[0][2]+",
a3="+recdata[0][3]+",a4='"+recdata[0][4]+"' WHERE a1='"+recdata[0][1]+"' ";
//window.alert(par["cda_sql"]);
//creează obiect comunicație RPC
var rpc = new qx.io.remote.Rpc();
rpc.setTimeout(106000);
rpc.setUrl("htp://localhost:8080/jevi_php/jevi_server.php");
rpc.setServiceName("jevi_clase");
try {

80
2.2.Descrierea codului aplicației ”untabelpg”

var result;
//apelează funcția pentru comunicație asincronă
var handler = function(result, exc) {
if (exc == null)
{ window.alert("Nr. inregistrari afectate: " +result);}
}
} catch (exc) {
showDetails(exc.rpcdetails);
}
/*asociază pentru comunicația asincronă funcția PHP ”comanda” din cadrul clasei
PHP "jevi_clase" */
rpc.callAsync(handler, "comanda",par);
});
//-------------------------------------------------------------------------------------------------
----------
//funcție ce răspunde la evenimentul de ”apăsare” pentru butonul b3
b3.addListener("execute", function(e) {
//sunt preluați în obiectul par parametrii de conectare
var par={"host":"localhost", "port":"5437", "dbname":"test_qooxdoo" ,
"user":"postgres", "password":"abcd", "pageNo":"1", "pageSize":"0", "cda_sql":"---"};
//!!!ATENTIE pageSize:0 pentru UPDATE, DELETE, INSERT, RAISE EXCEPTION
//preia numărul înregistrării selectate
var recno=untabelpg.w_main0.table.getFocusedRow();

//adaugă datele din tabel corespunzătoare selecției în tabloul recdata


var recdata=[];
recdata.push(untabelpg.w_main0.tableModelX.getRowData(recno));
//actualizează obiectul ce conține parametrii transmiși către server
par["cda_sql"]="DELETE FROM s1.t1 WHERE a1='"+recdata[0]
[1]+"' ";
//window.alert(par["cda_sql"]);
// creează obiectul pentru comunicația RPC
var rpc = new qx.io.remote.Rpc();
rpc.setTimeout(106000);
rpc.setUrl("htp://localhost:8080/jevi_php/jevi_server.php");
//stabilește clasa ce asigură serviciul utilizat în cadrul comunicației
rpc.setServiceName("jevi_clase");
try {
var result;
//construcție funcție comunicație asincronă
var handler = function(result, exc) {
if (exc == null)
{ window.alert("Nr. inregistrari afectate: " +result);}

81
2.Dezvoltarea pe partea de client – dezvoltarea
interfeței prin utilizarea claselor qooxdoo
}
} catch (exc) {
showDetails(exc.rpcdetails);
}
//apel funcție PHP ”comanda” pentru operațiile de INSERT / UPDATE / DELETE
rpc.callAsync(handler, "comanda",par);
});
//-------------------------------------------------------------------------------------------------
-----
//funcție ce răspunde la evenimentul de ”apăsare” pentru butonul b4
b4.addListener("execute", function(e) {
var par={"host":"localhost", "port":"5437", "dbname":"test_qooxdoo",
"user":"postgres", "password":"abcd", "pageNo":"1", "pageSize":"0", "cda_sql":"---"};
var recno=untabelpg.w_main0.table.getFocusedRow();
var recdata=[];
recdata.push(untabelpg.w_main0.tableModelX.getRowData(recno));
par["cda_sql"]="INSERT INTO s1.t1(a1,a2,a3,a4) VALUES
('"+recdata[0][1]+"',"+recdata[0][2]+","+recdata[0][3]+",'"+recdata[0][4]+"') ";
//window.alert(par["cda_sql"]);
var rpc = new qx.io.remote.Rpc();
// timp de încercare ptr. stabilire conexiune :10 sec
rpc.setTimeout(106000);
rpc.setUrl("htp://localhost:8080/jevi_php/jevi_server.php");
rpc.setServiceName("jevi_clase");
try {
var result; //result = rpc.callSync("comanda",par);
var handler = function(result, exc) {
if (exc == null)
{ window.alert("Nr. inregistrari afectate: " +result);}
}
} catch (exc) {
showDetails(exc.rpcdetails);
}
rpc.callAsync(handler, "comanda",par);
});
//-------------------------------------------------------------------------------------------------
-
//funcție ce răspunde la evenimentul de ”apăsare” pentru butonul b3
b5.addListener("execute", function(e) {
var par={"host":"localhost", "port":"5437", "dbname": "test_qooxdoo",
"user":"postgres", password":"abcd", "pageNo":"1", "pageSize":"1006000",
"cda_sql":"---"};
/* row_number() OVER() afșează numărul liniei afșate în urma aplicării

82
2.2.Descrierea codului aplicației ”untabelpg”

restricțiilor*/
par["cda_sql"]="SELECT row_number() OVER() , a1, a2, a3, a4
FROM s1.t1 ";//cu spatiu si fara ';' */
var rpc = new qx.io.remote.Rpc();
rpc.setTimeout(106000);
rpc.setUrl("htp://localhost:8080/jevi_php/jevi_server.php");
rpc.setServiceName("jevi_clase");
try {
var result;
var handler = function(result, exc) {
if (exc == null) //dacă nu a apărut vreo eroare
untabelpg.w_main0.tableModelX.setData(result);
}
} catch (exc) {
showDetails(exc.rpcdetails);
}
rpc.callAsync(handler, "selectie",par);
});
//-----------------------------------------------------------------------------------------
//funcție ce răspunde la evenimentul de ”apăsare” pentru butonul b6
b6.addListener("execute", function(e) {
var par={"host":"localhost", "port":"5437", "dbname":"test_qooxdoo",
"user":"postgres", "password":"abcd", "pageNo":"1","pageSize":"1006000",
"cda_sql":"---"};
par["cda_sql"]="SELECT row_number() OVER() , a1, a2, a3, a4
FROM s1.t1 ";//cu spațiu și fără ';'
var rpc = new qx.io.remote.Rpc();
rpc.setTimeout(106000);
rpc.setUrl("htp://localhost:8080/jevi_php/jevi_server.php");
rpc.setServiceName("jevi_clase");
try {//apel funcție de comunicație sincronă
var result = rpc.callSync("selectie",par);
if(result == null) window.alert("Nu exista date!");
else untabelpg.w_main0.tableModelX.setData(result);
}catch(err){
window.alert("Eroare la interogare :"+err);
}
});
},//end constructor
members:{
},
statics:{tableModelX:null,table:null },
events : //evenimente predefnite pentru tabel

83
2.Dezvoltarea pe partea de client – dezvoltarea
interfeței prin utilizarea claselor qooxdoo
{"reload" : "qx.event.type.Event", //refresh
"post" : "qx.event.type.Data" //validare
}

});

84
VI.Aplicație – Construcția unei hărți pentru
dispersie

VI. Aplicație – Construcția unei hărți pentru dispersie


1. Formulare cerințe
O aplicație ce implementează modele pentru poluare (ApPol) furnizează
datele într-o imagine grafcă cu dispersia poluării (fără harta geografcă ) și într-
un fșier de tip log (datele din fșierul utilizat în prezentare sunt de test).
Tema acestei aplicații o constituie găsirea unei soluții pentru afșarea
datelor rezultate pe o hartă geografcă. În acest sens, se va dezvolta o aplicație
sofware, denumită în continuare - DSP (Dispersie poluare). Imaginea rezultată
va fi stocată într-un fșier de tip imagine standard.

2. Analiza aplicației
În vederea rezolvării acestei teme au fost abordate următoarele soluții:
2.1. Preluarea și mixarea celor două imagini
Preluarea imaginii cu dispersia poluării obținute de aplicația ApPol și
mixarea cu o hartă geografcă locală. Aceasta se va face prin stabilirea unei
opacități pentru imaginea cu dispersia poluării.
Avantaje:
✔ Este o metodă ce pare simplă,
✔ Disponibilitatea imediată a fișerului rezultat.
Dezavantaje:
✗ Este necesară existența unei clase sau metode pentru realizarea opacității.
Este posibilă dezvoltarea unui asemenea modul, dar necesită resurse de
timp.
✗ Cele două imagini vor trebui să fe la aceeași scară și va fi necesară
găsirea unei soluții pentru interfața cu utilizatorul.
✗ Centrarea celor două imagini presupune dezvoltarea unui modul adecvat
pentru interfața cu utilizatorul.
✗ Este necesar un sistem de management pentru relaționarea fșierelor
hartă – imagine poluare.
2.2. Preluarea datelor din fșierul de tip log – aplicație de tip
desktop
În fșierul de tip log, furnizat de ApPol, sunt date cu care se poate
construi harta pentru dispersie a poluării. Se poate încărca harta geografcă
dintr-un fșier local într-un control de tip canvas, iar dispersia poluării se va

85
2.Analiza aplicației

construi tot în acest canvas prin utilizarea primitivelor grafce 2D.


Preluarea datelor din fșierul de tip log se poate realiza direct din fșier cu
condiția introducerii unor secvențe de separare a datelor sau prin intermediul
memoriei clipboard prin copierea datelor într-un control de editare de tip
area/memo.
Avantaje:
✔ Aplicație independentă ce mixează informații despre poluare cu o hartă
geografcă;
✔ Trecere relativ simplă din controlul de tip canvas în fșier imagine.
Dezavantaje:
✗ Dezvoltarea unui modul pentru realizarea scalabilității între date și hartă.
Aceasta presupune cunoașterea exactă a coordonatelor pentru marginile
hărții, altfel este necesar un modul de calibrare interactivă cu utilizatorul;
✗ Presupune o eventuală prelucrare prealabilă a fșierelor cu hărțile
geografce.
2.3. Preluarea datelor din fșierul de tip log – aplicație de tip WEB
Preluarea datelor din fșierul de tip log se poate realiza direct din fșier cu
condiția introducerii unor secvențe de separare a datelor din fșier sau prin
intermediul memoriei clipboard, prin copierea datelor furnizate de ApPol într-un
control de editare de tip area/memo. Datele citite vor fi afșate grafc într-un
canvas în care a fost încărcată inițial harta geografcă. Harta geografcă va putea fi
obținută din Google Maps.
Avantaje:
✔ Utilizarea hărților existente din Google Maps;
✔ Varietate mare de hărți (teren, satelit, roadmap etc);
✔ Sunt cunoscute dimensiunile hărții.
Dezavantaje:
✗ Necesitatea unei conexiuni internet;
✗ Nu pot fi descărcate în vederea salvării decât hărțile de tip static, iar
acestea sunt limitate la 640 x 640 pixeli (există și o versiune comercială
pentru o dimensiune dublă);
✗ Extinderea hărții de la 640 x 640 pixeli la 1280 x 1280 pixeli crește
complexitatea aplicației și în timp pot apărea noi restricții de la Google
Map;
✗ Pe o imagine preluată via WEB pot apărea restricții privind modifcarea
acesteia și ca urmarea se complică generarea imaginii fnale.

3. Proiectarea aplicației
În urma analizei a fost aleasă soluția Preluarea datelor din fșierul de tip

86
3.Proiectarea aplicației

log – aplicație de tip WEB. Pentru a simplifca dezvoltarea se va utiliza un


framework open souce – qooxdoo.
Date de intrare:
➔ secvența din fșierul de tip log;
➔ cunoașterea locației și alegerea interactivă a sursei de poluare pe hartă.
Dată de ieșire: fșier de tip imagine, ce reprezintă harta geografcă cu dispersia
poluării.
Principalele module ale aplicației sunt date de diagrama următoare:
INTERNET Date din fșierul de tip log

Selectare pe Harta GOOGLE Map


Preluare date dispersie
a sursei pentru poluare

Stabilire opacitate +
Afșare hartă dispersie
Salvare imagine
Fig. VI.1 – Fluxul princiapal de date

Utilizatorul va trece în starea ”selecție sursă” și va selecta pe harta


GoogleMap sursa pentru harta de dispersie. Prin această selecție aplicația va
prelua coordonatele sursei (latitudine și longitudine). După această operație,
utilizatorul va prelua valorile pentru harta de dispersie. Din motive de simplitate
se va prelua prin copierea într-un control de editare de tip ”area”. În urma
procesării acestor date se obțin limitele minime și maxime și este afșat tabelul cu
datele preluate. De asemenea se calculează și valorile corespunzătoare pentru
1% ...80%.
În acest moment se poate solicita afșarea hărții de dispersie, imaginea cu
dispersia va fi desenată peste patru secțiuni de hartă statică.
În continuare sunt prezentate mai multe diagrame de reprezentare pentru
arhitectura aplicației.

87
3.Proiectarea aplicației

3.1. Diagrama de secvență


Diagrama de secvență permite urmărirea în timp a succesiunii operațiilor.
Hartă Hartă Hartă statică
Date dispersie
Google Map Dispersie Dispersie
Utilizator procesate
dinamică (canvas) (pagină nouă) WEB

Încărcare hartă dinamică


Click st.

Poziție sursă + zoom + .tip hartă


Preluare date.

Date dispersie procesate


Încărcare 4 hărți statice
Cda: Afșare hartă dispersie
Stabilire opacitate Salvare hartă

Afșare hartă dispersie


Fișier cu harta dispesiei
Încărcare hartă dinamică
Click .

Poziție sursă + zoom + tip hartă


Încărcare 4 hărți statice
Cda: Afșare hartă dispersie
Stabilire opacitate Salvare hartă

Afșare hartă dispersie


Fișier cu harta dispersiei

Fig VI.2. Diagrama de secvență (exemplu de scenariu)


Au fost constituite șase obiecte: utilizator, harta google map dinamică, date
dispersie procesate, hartă dispersie (canvas), hartă statică dispersie, web. Obiectul
WEB poate să fe activ doar în momentul încărcării hărților.
Diagrama de secvență poate fi foarte utilă în momentul în care este

88
3.1.Diagrama de secvență

necesară punerea în evidență a ordinii mesajelor dintre obiecte în timp. Aceasta


este alcătuită din linia de viață a obiectelor (linia întreruptă) și punctele de
control (capetele dreptunghiurilor), ce corespund acțiunii obiectelor.
3.2. Diagrama de colaborare
Dacă în diagrama de secvență aveam succesiunea utilizării obiectelor,
legăturile dintre obiecte sunt date de diagrama de colaborare. Această diagramă
pune în evidență legăturile dintre obiecte și mesajele ce se transmit între acestea.
Diagrama de colaborare cuprinde calea și numărul de secvență.

Hartă 6.C
:WEB Dispersie da
. Sa
rtă

(canvas) ve

5.Co
ha

hart sie
disp
am are

Hartă statică

nstr
din cărc

ă
ică

er

Dispersie
ucție
1.În

(pagină nouă)
Date poluare
pacitate

Hartă
Google Map procesate
dinamică 4.Coordonate sursă re
l va
6.Setare o

ate

+ zoom + tip hartă a i ne


es ag
re d

r
e re im
7.C i er
e

ș
opi

i
8.F
3.C

:Utilizator

Fig VI.3. Diagrama de colaborare


3.3. Diagrama activităților
Pentru a cuprinde trecerea obiectelor dintr-o stare în alta se utilizează
diagrama de activități. Aceasta pune în evidență aspectele dinamice ale
sistemului.

89
3.Proiectarea aplicației

Utilizator Aplicație client Acces


internet

Încărcare hartă
Google Map dinamică
Selectarea pe Harta
harta a Google
sursei de
poluare

Reține coordonatele punctului Reține zoom-ul


Sursa ( latitudine, longitudine) hărții curente
Date din
fșierul Construiește șirurile pentru obținerea
de tip log celor 4 hărți statice google map

Preluare date dispersie


Separarea datelor preluate prin copiere
Editare
Determinarea valorilor MIN și MAX
date dispersie
Determinarea valorilor ptr.: 1% ... 80%
Afșarea datelor preluate

Obținerea celor patru hărți


Solicită și alipirea acestora într-un canvas
generare Harta
hartă dispersie Construcția ariilor ce reprezintă poluarea Google

Generare imagine statică – hartă dispersie

Stabilire
Afșare hartă dispersie
opacitate

Salvare imagine
Fig.VI.4 – Diagrama activităților

90
3.3. Diagrama activităților

Aceasta cuprinde: stări de activitate/acțiune (reprezintă executarea unei


acţiuni – acțiunile nu mai pot fi descompuse), obiecte, tranziții (trecerea de la o
stare la alta), ramuri (specifcă o cale alternativă, bazată pe o expresie booleană),
bifurcații/îmbinări (pentru procese concurente), culuoare (împarte stările de
activitate în grupuri – sunt separate prin bare verticale).
3.4. Diagrama stărilor
Diagrama de tranziție a stărilor este asemănătoare unei ”mașini de stare”.
Este utilizată în modelarea unor aspecte dinamice ale activităților. Aceasta
specifcă secvenţa de stări prin care trece un obiect, pe parcursul vieţii sale, ca
răspuns la evenimente/mesaje. Starea este reprezentată de o situaţie în viața unui
obiect, când acesta satisface anumite condiţii, realizează anumite activităţi sau
aşteaptă anumite evenimente/mesaje.
Editare date dispersie
Încarcă hartă dinamică entry/preluare date dispersie
Google Map do/separarea datelor preluate;
determinarea valorilor ptr. intervale

Cda: Selectare Cda: Preluare Date


Locație sursă Așteaptă comandă
do/ execută cda.
Afșare date preluate
Selecție Cda: Afșare do/afșare date în
locație sursă tabel

Căutare sursă poluare pe hartă


entry/schimbare formă cursor Afșare hartă dispersie
exit/reține coordonatele do/obținerea celor patru hărți și alipirea
punctului sursă ( latitudine, acestora într-un canvas; construcția
Longitudine); reține zoom-ul ariilor ce reprezintă poluarea; generare
hărții curente. imagine statică – hartă dispersie

Salvare imagine Cda: Salvare


Execută comanda din
meniul generat
prin click buton st.()
Fig.VI.5 – Diagrama stărilor
Diagrama de tranziție a stărilor conține: stări simple și stări complexe
(fecare stare poate fi reprezentată printr-o altă diagramă), tranziții, evenimente și
acțiuni. O stare poate fi descrisă prin: nume (poate fi și anonimă), acțiuni la

91
3.Proiectarea aplicației

intrarea în stare, acțiuni realizate la ieșirea din stare, tranziții interne (realizate
fără a schimba starea).

4. Implementarea aplicației
Varianta aleasă constă în implementare client-side prin utilizarea
JavaScript și a framework-ului qooxdoo. Aplicația are acronimul DSP, scheletul
aplicației qooxdoo este generat cu acest nume. În acest sens avem următoarele
fșiere sursă JavaScript (în qooxdoo fecare clasă corespunde unui fșier JavaScript
– având același nume cu clasa):
➔ Application – intrarea în aplicație;
➔ twharta – conține meniul principal și harta dinamică, conține metodele
pentru salvarea poziției sursei de dispersie precum și construcția șirurilor
de accesare pentru cele patru hărți 640x640;
➔ Wsharta – conține fereastra pentru preluarea și afșarea datelor, conține
funcții de conversie a coordonatelor, conține funcții pentru procesarea
datelor;
➔ twdharta – conține fereastra cu harta de dispersie, cu metodele de
desenare a hărții de dispersie.
4.1. Clasa ”dsp.Application”
Clasa dsp.Application derivă din clasa qooxdoo
qx.application.Standalone. Din cadrul acestei clase se lansează fereastra
wharta.
qx.Class.defne("dsp.Application",
{ extend : qx.application.Standalone,
members :
{ main : function()
{ this.base(arguments); //apel constructor bază
var doc = this.getRoot(); // accesează clasa de bază
var win = new dsp.wharta(); // instantierea
win.setShowMinimize(false);// dezactivează minimizarea
doc.add(win, {left:20, top:15}); // adaugă fereastra
win.open();// deschide fereastra
}
}});

4.2. Clasa ”dsp.twharta”


Această clasă derivă din clasa qx.ui.window.Window și are structura:
qx.Class.defne("dsp.wharta",

92
4 . 2 . C l a s a ” d s p . tw h a r t a ”

{ extend : qx.ui.window.Window,
construct : function() //funcția constructor a clasei
{ this.base(arguments, "dsp"); // apel constructor clasă de bază
.................................................................................................................
},
members: { }, // date membre
statics: { mapX:null, S_Mark:false, locationSRS:null, locationSRS1:null,
locationSRS2:null, locationSRS3:null, locationSRS4:null, markerSRS:null,
infoMsrs:null, qxHartaG:null, imgS1:null, imgS2:null, imgS3:null, imgS4:null,
sirX:null, titlu:null, DIM2:1280,
tx:[], tz:[], min:+1.e+100, max:-1.e+100,
retine_c: function(location, mapR) { //funcție de tip static
....................................................................................................................
},
setare_cursor : function(tip) { //funcție de tip static
.....................................................................................................................
}
}});
dsp.wharta.prototype._creeazaHartaG = function() //funcție protected
{
.....................................................................................................................
}
Obiectul static dsp.wharta.mapX reprezintă harta dinamică. Pentru a ști
dacă este afșat marker-ul ce conține locația sursei este utilizat fag-ul S_Mark.
Variabila locationSRS va conține coordonatele sursei pentru dispersie,
iar locationSRS1, locationSRS2, locationSRS3 și locationSRS4 vor conține
coordonatele corespunzătoare centrelor celor 4 hărți de 640x640 pixeli. Harta cu
dispersia va fi centrată pe orginea dispersiei și va avea dimensiunea de 1280x1280
pixeli. Numerele corespunzătoare celor patru hărți reprezintă numărul cadranului
din cercul trigonometric în momentul alipirii acestora.
Tabloul tx va conține valorile dispersiei, iar tabloul ty va conține
numărul de încadrare (categoria) pentru valoarea dispersiei. Ambele tablouri sunt
cu două dimensiuni (matrice), însă declararea se realizează similar tablourilor
unidimensionale (vectori). Variabilele min și max vor conține valorile de minim și
maxim detectate din datele de dispersie. Variabilele imgS1, imgS2, imgS3 și imgS4
conțin șirurile necesare accesării celor patru hărți statice. Variabila sirX va
conține datele copiate prin clipboard. Acestea se vor stoca sub forma unui vector.
Funcția de tip static retine_c() memorează noua poziție pe harta dinamică., iar
funcția setare_cursor() schimbă forma cursorului în momentul alegerii opțiunii de
selectare sursă dispersie și după încheierea selecției. Funcția de tip protected
._creeazaHartaG() construiește și afșează o hartă dinamică google map.
Constructorul clasei "dsp.wharta" conține codul:

93
4.Implementarea aplicației

construct : function()
{ this.base(arguments, "dsp");
this.setCaption="HARTA DISPERSIE";
this.setWidth(600); this.setHeight(600);
this.setLayout(new qx.ui.layout.Canvas());
var butonPanel = new qx.ui.container.Composite().set({height:30});
butonPanel.setLayout(new qx.ui.layout.HBox(4));
this.add(butonPanel,{left:0,top:0,right:0});
var b1 = new qx.ui.form.Buton("Sursa Poluare", ""); butonPanel.add(b1);
b1.addListener("execute", function(e)
{ dsp.wharta.setare_cursor(1); dsp.wharta.S_Mark=true;});
var b2 = new qx.ui.form.Buton("Preluare date", "");
butonPanel.add(b2);
b2.addListener("execute", function(e) {
var winS = new dsp.wsharta("Preluare date dispersie");
winS.setShowMinimize(false); winS.open();
});
var b3 = new qx.ui.form.Buton("Generare harta", "");butonPanel.add(b3);
b3.addListener("execute", function(e)
{
..........................................................................................................................
});
var ci= new qx.ui.container.Composite(new qx.ui.layout.Grow());
ci.add(this._creeazaHartaG()); //comp.add(ci,{edge :0});
this.add(ci,{left:0,botom:0,right:0,top:32});//
}
După apelul constructorului clasei de bază this.base(arguments, "dsp");
este asignat titlul ferestrei this.setCaption="HARTA DISPERSIE". Prin apelul
metodelor de tip seter/geter :this.setWidth(600); this.setHeight(600); este
stabilită dimensiunea inițială a ferestrei (600 x 600 pixeli).
Prin apelul this.setLayout(new qx.ui.layout.Canvas()); este stabilit modul
de afșare al controalelor din cadrul ferestrei. Metoda qx.ui.layout.Canvas()
creează un obiect de tip Layout – Canvas, în care putem adăuga controalele prin
specifcarea marginilor: lef, right, top și botom față de suprafața pe care sunt
așezate.
Prin execuția liniei:
var butonPanel = new qx.ui.container.Composite().set({height:30});
este creat un container (suprafață virtuală pe care se vor atașa alte controale).
Tipul Composite() este un model general pe care pot fi adăugate mai multe
controale. Totodată, prin metoda set() se pot stabili diverse proprietăți ale
obiectului. Având ca argument un obiect cu proprietăți, în acest caz proprietatea
height este setată cu valoarea 30.

94
4 . 2 . C l a s a ” d s p . tw h a r t a ”

Același efect se putea obține cu instrucțiunile:


var butonPanel= new qx.ui.container.Composite(); butonPanel.setHeight(30);
Apelul butonPanel.setLayout(new qx.ui.layout.HBox(4)); stabilește layout-
ul (modul de afșare) pentru controalele afate în cadrul container-ului
butonPanel. În acest caz afșarea controalelor se va face pe orizontală (metoda
qx.ui.layout.Hbox()), iar distanța minimă dintre două controale va fi de 4 pixeli.
Metoda this.add(butonPanel,{lef:0,top:0,right:0}); adaugă container-ul în
fereastra referită prin cuvântul cheie this, în zona defnită de {lef:0,top:0,right:0},
container-ul se va întinde între cele două margini laterale stânga–dreapta, dar va
fi aliniat doar cu marginea de sus (top:0).
Prin execuția:
var b1 = netw qx.ui.form.Buton("Sursa Poluare", ""); butonPanel.add(b1);
se construiește un control de tip buton având eticheta ”Sursa Poluare” și este
adăugat în container-ul butonPanel.
Metoda b1.addListener() adaugă un eveniment pentru controlul buton
dat de variabila b1. Prin b1.addListener("execute", function(e) {….}); se stabilește
legătura între funcție (anonimă) și comanda de apăsare a butonului (”execute”).
Butoanele referite prin variabilele b2 și b3 sunt adăugate în același
container ce conține și butonul b1.
Pentru harta dinamică a fost defnit un container, identifcat prin variabila
ci. Layout-ul pentru acest container este Grow(), aceasta înseamnă că
dimensiunea acestuia poate să crească dacă controalele din acesta nu încap pe
suprafața curentă. Acest container (ci) este adăugat în fereastră și aliniat cu toate
cele patru margini, astfel față de marginea de sus va păstra 32 de pixeli, însă va fi
lipit față de celelalte margini, chiar dacă fereastra își schimbă dimensiunile.
Prin lansarea funcției de execuție, pentru apăsarea butonului referit de
variabila b2 se lansează fereastra pentru preluarea datelor. În acest sens prin:
var winS = new dsp.wsharta("Preluare date dispersie");
se instanțiază clasa dsp.wsharta corespunzătoare ferestrei pentru preluarea
datelor. Instanțierea clasei este urmată de funcția pentru deschiderea ferestrei
winS.open().
Butonul b3 este asociat acțiunii de generare a hărții. În acest sens, se
efectuează operații în vederea pregătirii pentru încărcarea celor patru hărți
statice, de alipire a acestora, urmate de desenarea dispersiei pe baza datelor
încărcate. În fnal este instanțiată clasa dsp.wdharta. Aceste operații de pregătire
s-au realizat pentru a reduce volumul de date transferate între cele două clase.
Funcția ce răspunde la apăsarea butonului b3 are următorul cod:
b3.addListener("execute", function(e)
{ var pct_cp = dsp.wsharta.LatLngToPoint(dsp.wharta.locationSRS);
dsp.wharta.locationSRS1 = dsp.wsharta.PointToLatLng(pct_cp.x +

95
4.Implementarea aplicației

dsp.wharta.DIM2/4-1, pct_cp.y-dsp.wharta.DIM2/4);
dsp.wharta.locationSRS2 = dsp.wsharta.PointToLatLng(pct_cp.x-
dsp.wharta.DIM2/4, pct_cp.y - dsp.wharta.DIM2/4);
dsp.wharta.locationSRS3 = dsp.wsharta.PointToLatLng(pct_cp.x-
dsp.wharta.DIM2/4, pct_cp.y + dsp.wharta.DIM2/4 - 1);
dsp.wharta.locationSRS4 = dsp.wsharta.PointToLatLng(pct_cp.x +
dsp.wharta.DIM2/4-1, pct_cp.y + dsp.wharta.DIM2/4-1);
var sir_harta_statica = "htps://maps.googleapis.com/maps/api/staticmap";
sir_harta_statica = sir_harta_statica + "?center=" +
dsp.wharta.locationSRS1.lat().toString() + "," +
dsp.wharta.locationSRS1.lng().toString();
sir_harta_statica = sir_harta_statica + "&zoom=" +
dsp.wharta.mapX.zoom.toString() + "&size=640x640%20";
sir_harta_statica = sir_harta_statica + "&maptype=" +
dsp.wharta.mapX.mapTypeId;
sir_harta_statica = sir_harta_statica + "&markers=size:mid
%7Ccolor:0xFFFF00%7Clabel:1%7C" + dsp.wharta.locationSRS1.lat().toString() +
"," + dsp.wharta.locationSRS1.lng().toString();
dsp.wharta.imgS1 = sir_harta_statica;
sir_harta_statica = "htps://maps.googleapis.com/maps/api/staticmap";
sir_harta_statica = sir_harta_statica + "?center=" +
dsp.wharta.locationSRS2.lat().toString() + "," +
dsp.wharta.locationSRS2.lng().toString();
sir_harta_statica = sir_harta_statica + "&zoom=" +
dsp.wharta.mapX.zoom.toString() + "&size=640x640%20";
sir_harta_statica = sir_harta_statica + "&maptype=" +
dsp.wharta.mapX.mapTypeId; sir_harta_statica = sir_harta_statica +
"&markers=size:mid%7Ccolor:0xFFFF00%7Clabel:2%7C" +
dsp.wharta.locationSRS2.lat().toString()+ "," +
dsp.wharta.locationSRS2.lng().toString();
dsp.wharta.imgS2 = sir_harta_statica; sir_harta_statica =
"htps://maps.googleapis.com/maps/api/staticmap";
sir_harta_statica = sir_harta_statica + "?center=" +
dsp.wharta.locationSRS3.lat().toString() + "," +
dsp.wharta.locationSRS3.lng().toString();
sir_harta_statica = sir_harta_statica + "&zoom=" +
dsp.wharta.mapX.zoom.toString() + "&size=640x640%20";
sir_harta_statica = sir_harta_statica + "&maptype=" +
dsp.wharta.mapX.mapTypeId;
sir_harta_statica=sir_harta_statica + "&markers=size:mid
%7Ccolor:0xFFFF00%7Clabel:3%7C" + dsp.wharta.locationSRS3.lat().toString() +

96
4 . 2 . C l a s a ” d s p . tw h a r t a ”

"," + dsp.wharta.locationSRS3.lng().toString();
dsp.wharta.imgS3 = sir_harta_statica;
sir_harta_statica = "htps://maps.googleapis.com/maps/api/staticmap";
sir_harta_statica = sir_harta_statica + "?center=" +
dsp.wharta.locationSRS4.lat().toString() + "," +
dsp.wharta.locationSRS4.lng().toString();
sir_harta_statica = sir_harta_statica + "&zoom=" +
dsp.wharta.mapX.zoom.toString() + "&size=640x640%20";
sir_harta_statica = sir_harta_statica + "&maptype=" +
dsp.wharta.mapX.mapTypeId; sir_harta_statica = sir_harta_statica +
"&markers=size:mid%7Ccolor:0xFFFF00%7Clabel:4%7C" +
dsp.wharta.locationSRS4.lat().toString()+ "," +
dsp.wharta.locationSRS4.lng().toString();
dsp.wharta.imgS4 = sir_harta_statica;
var winD = new dsp.wdharta("Harta Dispersie fnala");
winD.setShowMinimize(false);
winD.open(); winD.close();winD.open();
});
Variabila pct_cp va conține coordonatele în pixeli ale centrului hărții,
funcția ce realizează acest lucru este detaliată în clasa dsp.wsharta. Sunt
determinate coordonatele (latitudine, longitudine) pentru centrele celor patru
hărți adiacente (dsp.wharta.locationSRS1 - 4 ). Utilizând metode din JavaScript se
construiesc adresele pentru obținerea celor patru hărți statice (de exemplu,
dsp.wharta.locationSRS4.lng().toString() preia valoarea longitudinii sursei
pentru harta din cadranul 4 -numerică- și o convertește în șir de caractere în
scopul concatenării). În fnal este instanțiată clasa ce se ocupă de defnitivarea
construcției hărții de dispersie:
var winD = new dsp.wdharta("Harta Dispersie fnala");
Fereastra este deschisă prin apelul funcției winD.open(). Harta dinamică
este generată prin apelul funcției de tip protected creeazaHartaG funcție
membră a clasei dsp.wharta.
dsp.wharta.prototype._creeazaHartaG = function()
{ dsp.wharta.qxHartaG = new qx.ui.core.Widget().set({ width: 640, height:
640 }); dsp.wharta.qxHartaG.setDecorator("main");
dsp.wharta.qxHartaG.addListenerOnce("appear", function() {
try { dsp.wharta.mapX = new
google.maps.Map(dsp.wharta.qxHartaG.getContentElement().getDomElement(), {
zoom: 14, mapTypeId: google.maps.MapTypeId.ROADMAP });
google.maps.event.addListener(dsp.wharta.mapX, 'click', function(event) {
dsp.wharta.retine_c(event.latLng,dsp.wharta.mapX);
dsp.wharta.locationSRS=event.latLng;

97
4.Implementarea aplicației

});
var infowindow = new google.maps.InfoWindow({content: 'Zoom harta' });
infowindow.open(dsp.wharta.mapX);
google.maps.event.addListener(dsp.wharta.mapX, 'click', function(event) {
infowindow.setContent('Zoom: ' + dsp.wharta.mapX.getZoom());
});
dsp.wharta.mapX.setCenter(new google.maps.LatLng(44.835,24.906)); } catch(ex) {
var msg = "Nu poate f creata HARTA Google !<br/>" + ex.toString();
dsp.wharta.qxHartaG.getContentElement().getDomElement().innerHTML +=
msg;
} });
return dsp.wharta.qxHartaG;
}
Se creează un control generic ce va fi referit prin dsp.wharta.qxHartaG.
Acest control va avea dimensiunea 640 x 640 pixeli și va fi utilizat pentru
preluarea hărții dinamice. Asociat controlului se defnește funcția pentru tratarea
evenimentului de afșare: dsp.wharta.qxHartaG.addListenerOnce ce este
atașată evenimentului "appear".

98
4 . 2 . C l a s a ” d s p . tw h a r t a ”

Fig. VI.6. Fereastra dsp.wharta cu harta dinamică


Încărcărea hărții google dinamice se va realiza într-o secțiune try {}
catch(...){}, ce permite tratarea erorilor/excepțiilor apărute. Harta este încărcată
prin apelul: new google.maps.Map( ... , {...}); având argumentele:
dsp.twharta.qxHartaG.getContentElement().getDomElement() și
{ zoom: 14, mapTypeId: google.maps.MapTypeId.ROADMAP }, ce reprezintă
proprietățile hărții.
Evenimentul pentru click buton stânga mouse este tratat de funcția:
google.maps.event.addListener(dsp.wharta.mapX, 'click', function(event) {..});
Funcția apelează o altă funcție (dsp.twharta.retine_c()) ce memorează coordonatele
curente. Valoarea zoom-ului este de asemenea memorată și afșată într-o

99
4.Implementarea aplicației

fereastră de tip infowindow.


4.3. Clasa ”dsp.twsharta”
Această clasă se ocupă de preluarea și prelucrarea datelor de dispersie. Ea
derivă din clasa qx.ui.window.Window și are structura:
qx.Class.defne("dsp.wsharta",
{ extend : qx.ui.window.Window,
construct : function()
{ this.base(arguments, "dsp");
.......................................................
},
statics:{containerS:null, tableModel:null, t1:null, eMIN:null, eMAX:null,
ariapr:[0,1,20,40,60,80,100], ariaval:[], opacitate:0.3, colN_m:['DD', 50, 100, 200,
300, 400, 500, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000, 2500], razaN_gd:[]}
});
dsp.wsharta.prel=function(textArea)
{
..........................................................
}
dsp.wsharta.destinationPoint = function(ddeg, dist) {
..........................................................
}
dsp.wsharta.LatLngToPoint = function(latlng) {
.......................................................
};
dsp.wsharta.LatLngToPointAbs = function(latlng) {
........................................................
};
dsp.wsharta.PointToLatLng = function(x,y) {
.......................................................
};
Variabila statică dsp.wsharta.containerS referă un container de tip stivă
cu două pagini (panelD1 și panelD2). Obiectul de tip static
dsp.wsharta.tableModel reprezintă modelul cu date pentru tabel. Variabila
numerică de tip static dsp.wsharta.opacitate reprezintă opacitatea pentru
desenarea dispersiei în raport cu harta obținută prin alipirea celor patru hărți.
Tabloul bidimensional dsp.wsharta.ariaval conține valorile dispersiei –
coloanele reprezintă distanța față de sursa dispersiei (50 – 2500 m), iar rândurile
reprezintă variația 0-350 grd decimale, parcurse cu un pas de 10 grd decimale.
Tabloul bidimensional dsp.wsharta.ariapr conține procentele ce delimitează
intervalele din cadrul grupărilor.
Variabilele statice eMIN și eMAX conțin limitele detectate.

100
4 . 3 . C l a s a ” d s p . tw s h a r t a ”

Constructorul clasei are codul:


construct : function()
{ this.base(arguments, "dsp");
this.setCaption="FISIER LOG";
this.setWidth(600); this.setHeight(600);
this.setLayout(netw qx.ui.layout.Canvas());
dsp.wsharta.containerS=netw
qx.ui.container.Stack().set({dynamic:true });
this.add(dsp.wsharta.containerS,{lef:0,right:0,botom:0,top:0});
var panelD1 = netw qx.ui.container.Composite().set({decorator: "main",
backgroundColor: "#DEEAF7",alignX:"lef"});
panelD1.setLayout(netw qx.ui.layout.Canvas());
dsp.wsharta.containerS.add(panelD1);
var b_prel = netw qx.ui.form.Buton("PRELUARE DATE",
"").set({height:20,width:80});
panelD1.add(b_prel,{lef:100,top:0,right:100});
var textArea = netw qx.ui.form.TextArea().set({ wrap:false, value: '',
backgroundColor: "#DEEAF7"});
panelD1.add(textArea,{lef:5,botom:5,right:5,top:30});
b_prel.addListener("execute", function(e) { dsp.wsharta.prel(textArea); });
var panelD2 = netw qx.ui.container.Composite().set({decorator: "main",
allowGrowX:true, backgroundColor: "#FEECFF",alignX:"lef"});
dsp.wsharta.containerS.add(panelD2);
panelD2.setLayout((netw qx.ui.layout.Grid(5,4)).setColumnFlex(3,1));
dsp.wsharta.t1=netw qx.ui.basic.Label("---").set({ allowShrinkX: false,
paddingTop: 3});
panelD2.add(dsp.wsharta.t1, {row:0, column:0});
dsp.wsharta.t1.setLayoutProperties({colSpan: 3});
panelD2.add(netw qx.ui.basic.Label("Coordonate SURSA DISPERSIE
X,Y[m]:").set({ allowShrinkX: false, paddingTop: 3}), {row:1, column:0});
var X=netw qx.ui.form.TextField(); panelD2.add(X, {row:1, column:1});
X.setValue((dsp.wharta.locationSRS.lat()).toString());
var Y=netw qx.ui.form.TextField(); panelD2.add(Y, {row:1, column:2});
Y.setValue((dsp.wharta.locationSRS.lng()).toString());
panelD2.add(netw qx.ui.basic.Label("Parametru-val MIN|
MAX:").set({ allowShrinkX: false, paddingTop: 3}), {row:2, column:0});
dsp.wsharta.eMIN=netw qx.ui.form.TextField();
panelD2.add(dsp.wsharta.eMIN, {row:2, column:1});
dsp.wsharta.eMAX=new qx.ui.form.TextField();
panelD2.add(dsp.wsharta.eMAX, {row:2, column:2});
dsp.wsharta.tableModel = new qx.ui.table.model.Simple();

var colS=[];

101
4.Implementarea aplicației

for(var i=0;i<16;i++) colS[i]=dsp.wsharta.colN_m[i].toString();


dsp.wsharta.tableModel.setColumns(colS);
var table = new qx.ui.table.Table(dsp.wsharta.tableModel).set({ decorator:
null});
panelD2.add(table, {row:4, column:0});
table.setLayoutProperties({colSpan: 4});
dsp.wsharta.containerS.setSelection([ dsp.wsharta.containerS.getChildren()
[0]]);
//conversie coordonate locale -> coordonate harta
for(var i=0;i<36;i++) dsp.wsharta.razaN_gd[i]=(i*10).toString();
}
Variabila panelD1 reprezintă container-ul ce conține caseta de editare de
tip area și butonul pentru preluarea datelor. Acest container are atașat un layout
de tip canvas ce permite atât pozitionarea relativă, față de margini, a controalelor
cât și poziționarea absolută a acestora. Variabila panelD2 reprezintă container-ul
ce realizează afșarea datelor preluate și procesate. Layout-ul pentru acest
container este de tip grid, fecare control este adăugat într-o celulă, acestea
suportând și operații de unire a mai multor celule pe linii sau coloane succesive
(rowSpan sau colSpan).
Prin funcția:
dsp.wsharta.containerS.setSelection([dsp.wsharta.containerS.getChildren()[0]]);
containerul de tip STACK selectează prima pagină (panelD1).
Execuția var X=new qx.ui.form.TextField(); creează un nou control de
tip editare , iar prin panelD2.add(X, {row:1, column:1}); acest control este
adăgat în celula de la rândul 1 coloana 1 din cadrul containeru-lui panelD2.
În vederea adăgării datelor în tabel se creează modelul asociat tabelului:
dsp.wsharta.tableModel= new qx.ui.table.model.Simple();
Denumirile coloanelor tabelului sunt stocate în vectorul colS[] și după
inițializare prin dsp.wsharta.tableModel.setColumns(colS); acesta este atașat
modelului.
Funcția de preluare este explicitată prin:
dsp.wsharta.prel=function(textArea)
{ dsp.wharta.sirX=textArea.getValue();//window.alert("Au fost preluate
"+dsp.wharta.sirX.length+" caractere!");
var n = dsp.wharta.sirX.search("---");
var sx =
dsp.wharta.sirX.split("-------------------------------------------------------------------------
------------------------");
dsp.wharta.titlu = sx[0]; dsp.wsharta.t1.setValue(dsp.wharta.titlu);
sx =
dsp.wharta.sirX.split("-------------------------------------------------------------------------

102
4 . 3 . C l a s a ” d s p . tw s h a r t a ”

------------------------------------------------------------------------");
var sxx; sxx=sx[2];
for(var k=0;k<1000;k++)
{sxx=sxx.replace(" "," "); sxx=sxx.replace("E+","e+");
sxx=sxx.replace("E-","e-");
}
sxx=sxx.trim(); //elimină spații - stânga+dreapta
var yx=sxx.split(" ");
var ty=[];
for(var i=0;i<36;i++)
for(var j=0;j<16;j++)
{ if (!ty[i]) ty[i] = []; //nu este posibilă defnirea directă a unei matrice 2D
ty[i][j]=parseFloat(yx[i*16 + j]);
}
//determinarea valorilor minime și maxime
var min=new Number(+1.e+100),max = new Number(-1.e+100);
for(var i = 0; i<36; i++)
for(var j = 1; j<16; j++)
{ if(ty[i][j] < dsp.wharta.min) dsp.wharta.min = ty[i][j];
if(ty[i][j] > dsp.wharta.max) dsp.wharta.max = ty[i][j];
}
//stabilirea domeniilor
for(var k=0;k<7;k++)
dsp.wsharta.ariaval[k] = dsp.wharta.min + (dsp.wharta.max –
dsp.wharta.min) * dsp.wsharta.ariapr[k] / 100.0;
//cuantifcarea domeniilor
var tz=[];
for(var i=0; i<36; i++)
for(var j=0; j<16; j++)
{ if (!tz[i]) tz[i] = []; //nu este posibilă defnirea directă a unei matrice 2D
if( j == 0) { tz[i][j]= -1; continue;}//nu face parte din valori
for(var k=1;k<7;k++)
if(ty[i][j] >= dsp.wsharta.ariaval[k-1] && ty[i][j] <=
dsp.wsharta.ariaval[k]) tz[i][j]=k-1;
}
dsp.wsharta.eMIN.setValue(dsp.wharta.min.toString());
dsp.wsharta.eMAX.setValue(dsp.wharta.max.toString());
dsp.wharta.tx=ty; dsp.wharta.tz=tz;
dsp.wsharta.tableModel.setData(dsp.wharta.tx);
dsp.wsharta.containerS.setSelection( [dsp.wsharta.containerS.getChildren()
[1]] );
}
Funcția identifcă începutul tabelului și citește în tabloul ty valorile

103
4.Implementarea aplicației

dispersiei, acestea find în prealabil transformate din șiruri de caractere în valori


numerice prin intermediul funcției parseFloat(). După aceasta, sunt identifcate
valorile extreme. Sunt determinate valorile corespunzătoare celor din vectorul
ariapr[] și din vectorul ariaval[]. Această operației este urmată de completarea
tabloului tz cu grupele obținute prin încadrarea valorilor în ariaval[].
În continuare sunt funcții membre ale clasei pentru transformarea din
grade decimale în radiani și invers.
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
Number.prototype.toDeg = function() {
return this * 180 / Math.PI;
}
Funcția dsp.wsharta.destinationPoint(ddeg, dist) preia unghiul și
distanța față de sursa de de poluare și întoarce coordonatele punctului (latitudine,
longitudine). Funcția este o adaptare după [5]
dsp.wsharta.destinationPoint = function(ddeg, dist) {
dist = dist / 6371; // aprox. raza P.[6371 km]
ddeg = ddeg.toRad();
var lat1 = dsp.wharta.locationSRS.lat().toRad(),
lon1 = dsp.wharta.locationSRS.lng().toRad();
var lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) +
Math.cos(lat1) * Math.sin(dist) * Math.cos(ddeg));
var lon2 = lon1 + Math.atan2(Math.sin(ddeg) * Math.sin(dist) *
Math.cos(lat1),
Math.cos(dist) - Math.sin(lat1) *
Math.sin(lat2));
if (isNaN(lat2) || isNaN(lon2)) return null;
return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
}
Funcția dsp.wsharta.LatLngToPoint(latlng) preia longitudinea și
latitudinea unui punct și întoarce coordonatele în pixeli raportate la canvas-ul cu
harta. Funcția este o adaptare după [6].
dsp.wsharta.LatLngToPoint = function(latlng) {
var x = (latlng.lng() + 180) / 360 * 256;
var x_c=(dsp.wharta.locationSRS.lng() + 180) / 360 * 256
var y = ((1 - Math.log(Math.tan(latlng.lat() * Math.PI / 180) + 1 /
Math.cos(latlng.lat() * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, 0)) * 256;
var y_c = ((1 - Math.log(Math.tan(dsp.wharta.locationSRS.lat() * Math.PI /
180) + 1 / Math.cos(dsp.wharta.locationSRS.lat() * Math.PI / 180)) / Math.PI) / 2 *
Math.pow(2, 0)) * 256;

104
4 . 3 . C l a s a ” d s p . tw s h a r t a ”

x=x-x_c; y=y-y_c;
x=x*Math.pow(2, dsp.wharta.mapX.zoom); y=y*Math.pow(2,
dsp.wharta.mapX.zoom);
x=dsp.wharta.DIM2/2+x; y=dsp.wharta.DIM2/2+y;
return {x:x,y:y};
};

Fig. VI.7. Panel-ul pentru preluare date (panelD1)

105
4.Implementarea aplicației

Fig. VI.8 – Afșarea datelor preluate (panelD2)


Funcția dsp.wsharta.LatLngToPointAbs(latlng) preia longitudinea și
latitudinea unui punct și întoarce coordonatele în pixeli, fără a se raporta la
canvas-ul curent. Acestă funcție ține cont și de zoom și este o adaptare după [6].
dsp.wsharta.LatLngToPointAbs = function(latlng) {
var x = (latlng.lng() + 180) / 360 * 256;
var y = ((1 - Math.log(Math.tan(latlng.lat() * Math.PI / 180) + 1 /
Math.cos(latlng.lat() * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, 0)) * 256;
x=x*Math.pow(2, dsp.wharta.mapX.zoom); y=y*Math.pow(2,
dsp.wharta.mapX.zoom);
return {x:x,y:y};
};

106
4 . 4 . C l a s a ” d s p . tw d h a r t a ”

4.4. Clasa ”dsp.twdharta”


Această clasă se ocupă de desenarea hărții de dispersie, ea derivă din
clasa qx.ui.window.Window și are structura:
qx.Class.defne("dsp.wdharta",
{ extend : qx.ui.window.Window,
construct : function()
{ this.base(arguments, "dsp");
.............................................................................................................
},
statics:{canvas1:null, img1:null, img2:null, img3:null, img4:null, opac:0.1, ariafll:[]}

});
Obiectul dsp.wdharta.canvas1 reprezintă suprafața de desenare, iar
dsp.wdharta.img1-4 reprezintă cele patru obiecte imagine cu cele patru sectoare
ale hărții. Vectorul dsp.wdharta.ariafll[] va conține codul culorii pentru
fecare grup valoric al dispersiei.
Constructorul clasei are codul:
construct : function()
{ this.base(arguments, "dsp");
this.setCaption="HARTA";
this.setWidth(500); this.setHeight(530);
this.setLayout(new qx.ui.layout.Canvas());
var panelZ1 = new qx.ui.container.Composite().set({decorator: "main",
backgroundColor: "#DEEAF7",height:30,alignX:"left"});
panelZ1.setLayout(new qx.ui.layout.HBox(4).set({alignY:"middle"}));
this.add(panelZ1,{top:0,left:0,right:0});
var b_save = new qx.ui.form.Buton("SALVARE HARTA",
"").set({height:20,width:80}); panelZ1.add(b_save);
b_save.addListener("execute", function(e) { dsp.wdharta.salveaza(); });
panelZ1.add(new qx.ui.basic.Label(" Opacitatea:"));
var slider1 = new qx.ui.form.Slider("horizontal").set({ minimum:0,
maximum:100, pageStep:10, value:10, height:8, width:300}); panelZ1.add(slider1);
slider1.addListener("changeValue", function(e)
{ dsp.wdharta.opac=slider1.getValue()/100.0;
dsp.wdharta.canvas1.update();});
var panelZ2 = new qx.ui.container.Scroll();
var panelZ2_1=new qx.ui.container.Composite(new
qx.ui.layout.Canvas()).set({width:dsp.wharta.DIM2,height:dsp.wharta.DIM2});
panelZ2.add(panelZ2_1);
this.add(panelZ2,{left:0,top:32,botom:0,right:0});
if (!qx.core.Environment.get("html.canvas"))

107
4.Implementarea aplicației

{ dsp.wdharta.canvas1 = new
qx.ui.container.Composite(new qx.ui.layout.HBox());
dsp.wdharta.canvas1.add(new qx.ui.basic.Label("Acest
browser nu suporta suprafete de desenare!").set({rich : true,alignX: "center", alignY:
"middle" }));
}
else
{ dsp.wdharta.canvas1 = new
qx.ui.embed.Canvas().set({
syncDimension: true, allowStretchX : false,
allowStretchY : false, width:dsp.wharta.DIM2, height:dsp.wharta.DIM2
});
dsp.wdharta.canvas1.addListener("redraw", this.draw, this);
dsp.wdharta.img1 = new Image();
dsp.wdharta.img1.alt="Imaginea nu a putut f incarcata!";
dsp.wdharta.img1.setAtribute('crossOrigin', 'anonymous');
dsp.wdharta.img1.src =dsp.wharta.imgS1;
dsp.wdharta.img2 = new Image();
dsp.wdharta.img2.setAtribute('crossOrigin', 'anonymous');
dsp.wdharta.img2.src =dsp.wharta.imgS2;
dsp.wdharta.img3 = new Image();
dsp.wdharta.img3.setAtribute('crossOrigin', 'anonymous');
dsp.wdharta.img3.src =dsp.wharta.imgS3;
dsp.wdharta.img4 = new Image();
dsp.wdharta.img4.setAtribute('crossOrigin', 'anonymous');
dsp.wdharta.img4.src =dsp.wharta.imgS4;
}
panelZ2_1.add(dsp.wdharta.canvas1,{left:0,top:0,botom:0,right:0});
}
Layout-ul asociat ferestrei va fi de tip canvas. Container-ul panelZ1 are
un layout de tip Hbox și conține controalele: un buton pentru salvare, o etichetă
cu conținutul ”Opacitate” și un control de tip slider. Acest container are înălțime
fxă (30 pixeli), iar restul este aliniat la marginile stânga, dreapta și sus.
Fereastra mai conține și un container -panelZ2- cu un layout de tip Grow.
Acest container va conține un singur control cu imaginea hărții de dispersie.
Acest container are înălțime variabilă și este aliniat la marginile stânga, dreapta,
sus și jos.
dsp.wdharta.canvas1 = new qx.ui.embed.Canvas()
Opțiunea setAtribute('crossOrigin', 'anonymous'); dă posibilitatea
modifcării imaginii inițiale.
Redesenarea hărții în urma modifcării opacității desenului cu dispersia se
realizează prin funcția dsp.wdharta.canvas1.update(); .

108
4 . 4 . C l a s a ” d s p . tw d h a r t a ”

Funcția membră a clasei ce se ocupă cu realizarea hărții de dispersie este


dsp.wdharta.draw() și răspunde la evenimentul redraw al controlului canvas1.
dsp.wdharta.prototype.draw = function(e)
{var data = e.getData();
var ctx = data.context; ctx.save();
ctx.drawImage(dsp.wdharta.img1, dsp.wharta.DIM2/2, 0);
ctx.drawImage(dsp.wdharta.img2, 0, 0);
ctx.drawImage(dsp.wdharta.img3, 0, dsp.wharta.DIM2/2);
ctx.drawImage(dsp.wdharta.img4, dsp.wharta.DIM2/2, dsp.wharta.DIM2/2);
dsp.wdharta.ariafll=["rgba(0, 0, 0,","rgba(0, 0, 255,","rgba(0, 255, 0,","rgba(255, 128,
0,","rgba(255, 0, 0,","rgba(255, 0, 255, "];
for(var i=0;i<6;i++) dsp.wdharta.ariafll[i] = dsp.wdharta.ariafll[i] +
dsp.wdharta.opac.toString() + ")";
var raza=[], pctR=[];
for(var i=0;i<36;i++)
for(var j=1;j<16;j++)
{var pct;
if (!pctR[i]) pctR[i] = [];
if(j>1) pct =
dsp.wsharta.destinationPoint(10*i,0.001*dsp.wsharta.colN_m[j]);
else pct = dsp.wharta.locationSRS;
pctR[i][j]=dsp.wsharta.LatLngToPoint(pct);
if ( i == 0 )
{if( j > 0 ) raza[j] = Math.sqrt((pctR[i][j].x – pctR[i][1].x)*(pctR[i]
[j].x – pctR[i][1].x) + (pctR[i][j].y – pctR[i][1].y) * (pctR[i][j].y - pctR[i][1].y));
else raza[j]=0;}
}
//ariile
for(var i=0;i<36;i++)
for(var j=2;j<16;j++)//j>=2
{ var i1=i-1; if(i1<0) i1=35;
ctx.beginPath();
ctx.strokeStyle = '#0f000f'; ctx.lineWidth=0.5;
ctx.fllStyle = dsp.wdharta.ariafll[dsp.wharta.tz[i][j]];
ctx.arc(pctR[0][1].x, pctR[0][1].y, raza[j-1], (i-1-9)*2*Math.PI/36, (I – 9) * 2 *
Math.PI/36, false);
ctx.lineTo(pctR[i][j].x, pctR[i][j].y);
ctx.arc(pctR[0][1].x, pctR[0][1].y, raza[j], (i – 1 – 9) * 2 * Math.PI/36, (i – 9) *
2 * Math.PI/36, false);
ctx.lineTo(pctR[i1][j].x, pctR[i1][j].y);
ctx.fll();
ctx.stroke();
ctx.closePath();

109
4.Implementarea aplicației

}
dsp.wdharta.drawLegenda(ctx);
}
Pentru desenare se constituie un nou obiect var ctx = data.context; unde
data se obține din referința preluată de funcție (var data = e.getData(); ) în
urma evenimentului redraw pentru canvas1.
Obiectul ctx preia imaginile celor patru hărți 640x640 pixeli
dsp.wdharta.img1-4 și le afșează în canvas pe poziția celor patru cadrane.
Se construiește vectorul cu nuanțele de culoare pentru fecare grup de
date ale dispersiei dsp.wdharta.ariafll[]. Acesta preia culoarea de bază în
format Red-Green-Blue și adaugă valoarea opacitații preluată din cursorul de tip
Slider.
Următorul pas este determinarea coordonatelor ce delimitează fecare
sector. În acest sens se cunosc coordonatele sursei, distanțele față de sursă (în
metri) și unghiurile fecărui punct (fgura VI.9 - Anexă). Funcția utilizată este
dsp.twsharta.destinationPoint.
Pentru realizarea sectoarelor se utilizează primitive grafce, precum arcul
de cerc și linia. Liniile și contururile trasate se activează prin funcția ctx.stroke().
Fiecare secvență ctx.beginPath() - ctx.closePath() are atașat un anumit mod de
umplere pentru contururile obținute - ctx.fllStyle. În fnalul funcției este apelată
funcția dsp.wdharta.drawLegenda(ctx); ce realizează desenarea legendei.
Funcția pentru desenarea legendei are codul:
dsp.wdharta.drawLegenda = function(cty)
{ var xLeg=10, yLeg=20;
for(var k=0;k<6;k++)
{cty.beginPath();
cty.rect(xLeg+k*30,yLeg,30,30);
cty.fllStyle = dsp.wdharta.ariafll[k];
cty.fll();
cty.stroke();
cty.closePath();
}
cty.beginPath();
cty.fllStyle="black";cty.font="12px Arial";
for(var k=0;k<7;k++)
{cty.fllText(dsp.wsharta.ariaval[k].toFixed(1).toString(),xLeg-5+k*30,yLeg-2);
cty.fllText(dsp.wsharta.ariapr[k].toString()+"%",xLeg-7+k*30,yLeg+46);
cty.stroke();
}
cty.closePath();
}
Desenul se execută direct pe canvas1 prin obiectul de desenare ctx.

110
4 . 4 . C l a s a ” d s p . tw d h a r t a ”

În vederea salvării imaginii obținute, se creează o nouă fereastră, de data


aceasta de tip HTML, ce conține imaginea atașată controlului canvas1.
dsp.wdharta.salveaza = function(){
var canvasDOMElement =

dsp.wdharta.canvas1.getContentElement().getDomElement();
window.open(canvasDOMElement.toDataURL("imagez/png"));
}

5. Testarea aplicației
Testarea aplicației DSP s-a realizat doar pe browser-ul Google Chrome,
testarea pe alte browsere punând probleme la încărcarea hărților google map.
Pentru testare, în cursul dezvoltării se putea utiliza un modul specializat
în testare oferit de dezvoltatorii de la qooxdoo, însă se poate utiliza și modul debug
al browser-elor, în acest caz a fost utilizat modulul debug din cadrul Google
Chrome.
În cazul în care în debuger apar erori ce sunt difcil de interpretat, se
recomandă execuția comenzii din linia de comandă generate.py source-all ce are
ca efect și o analiză lexicală, sintactică și semantică a textului JavaScript.
Implementarea aplicației a început prin comanda din cadrul qooxdoo
create. Structura aplicație a fost creată în urma comenzii:
create-application.py - - name=dsp - - out=”D://”
Versiunea JavaScript optimizată, ce include și clasele din qooxdoo, este
obținută prin comanda: generate.py build.

111
Bibliografe

Bibliografe

[1] htp://www.w3schools.com/ (activ aug.20155)


[2] htp://qooxdoo.org/ (activ aug.20155)
[3] htp://www.marplo.net/ (activ aug.20155)
[4] htp://javascript.info/ (activ aug.20155)
[5] htp://stackoverfow.com/questions/266376023/how-to-calculate-the-
latlng-of-a-point-a-certain-distance-away-from-another (activ
aug.20155)
[6] htp://gis.stackexchange.com/questions/666247/what-is-the-formula-
for-calculating-world-coordinates-for-a-given-latlng-in-google
(activ aug.20155)
[7] www.postgresql.org (activ aug.20155)

112
ANEXE

ANEXE
Operatori javascript/php
Operatori unari
SIMBO FORMA FORMA Operaţia realizată Exemplu
LUL PHP JS
- -$a -a negarea lui a -3
+ +$a +a valoarea lui a 3
$a++ a++ Postincrementare: $a=3++;
preia valoare, apoi creste cu 1 $a are val. 3
++ Preincrementare: $a=++3;
++$a ++a mai întâi creşte cu 1, apoi preia $a are val. 4
valoarea
$a-- a-- Postdecrementare: $a=3--;
preia valoarea, apoi scade cu 1 $a are val. 3
-- Predecrementare: $a=--3;
--$a --a mai întâi scade cu 1, apoi preia $a are val. 2
valoarea
Operatori binari aritmetici
SIMBO FORMA FORMA Operaţia realizată Exemplu
LUL PHP JS
+ $a+$b a+b a adunat cu b 3.7+5.3
- $a-$b a-b b scăzut din a 3.1-5.0
* $a*$b a*b a înmuţit cu b 1.2*4.1
/ $a/$b a/b a împărţit la b 1.2/4.1
% $a%$b a%b a modulo b (restul împărţirii) 5%4
Operatori de atribuire aritmetici
SIMBOLUL FORMA FORMA Operaţia realizată
PHP JS
= $a=$b a=b a preia valoarea lui b
+= $a+=$b a+=b a=a(fostul conţinut)+b
-= $a-=$b a-=b a=a-b
/= $a/=$b a/=b a=a/b
%= $a%=$b a%=b a=a%b
Operatori relaţionali
SIMBOLUL FORMA FORMA Operaţia realizată
PHP JS
> $a>$b a>b dacă a>b, atunci true, altfel false
>= $a>=$b a>=b dacă a>=b atunci true, altfel false
< $a<$b a<b dacă a<b atunci true, altfel false
<= $a<=$b a<=b dacă a<=b atunci true, altfel false

113
Operatori javascript/php

SIMBOLUL FORMA FORMA Operaţia realizată


PHP JS
== $a==$b a==b dacă a identic cu b (pot să nu fe de același
tip de ex. 3=='3'este true), atunci true, altfel
false
=== $a===$b a===b dacă a identic cu b și sunt de același tip de
data, atunci true, altfel false
!= $a!=$b a!=b dacă a diferă de b, atunci true, altfel false
(nu tine cont de tip)
<> $a<>$b a<>b dacă a diferă de b, atunci true, altfel false
(nu tine cont de tip)
!== $a!=$b a!=b dacă a diferă de b, atunci true, altfel false
(tine cont de tip)
Asemănător cu limbajul C, valoarea 0 este considerat false, iar diferit de 0 este
true/adevărat,. De exemplu - 0.00050007 este adevărat / are valoare de adevăr true.
Operatorii logici
SIMBOLUL FORMA FORMA Operaţia
PHP JS
&& $a&&$b a&&b ŞI/AND
and $a and $b a and b ŞI/AND
|| $a||$b a||b SAU/OR
or $a or $b a or b SAU/OR
! !$a !a NEGAT/NOT
xor $a xor $b a xor b SAU exclusiv/XOR
(T – true, F - false)
x y x&&y x||y !x x xor y
F F F F T F
F T F T T T
T F F T F T
T T T T F F

114
Harta obținută

Harta obținută

Fig. VI.9 Harta de dispersie

Fig. VI.10 Control opacitate

115
Harta obținută

Fig. VI.11. Salvarea hărții de dispersie ( harta de bază provine din Google Maps )

116
View publication stats

S-ar putea să vă placă și