Filehost.ro - gazduire fisiere
RSB_Team
Ne-am mutat pe http://forum.rsb-team.com
Nou pe simpatie:
Profil Ank_beleaua
Femeie
25 ani
Bucuresti
cauta Barbat
35 - 51 ani
RSB_TeamReguliInregistrareLoginPozeNu sunteti logat. Lista Forumurilor Pe Tematici
RSB_Team / Tutoriale /

AHAH - Solutie simpla la probleme vechi de cand lumea

Pagini: 1  
#1
Child
Membru RSB
Din: HELL
Postari: 85
De cand s-a nascut Perl-ul sau alte prafuite limbaje de scripting server-side, oare s-a intrebat cineva de cate ori am scris linii de redirectare? Sau de cate ori a reincarcat pagina un vizitator sau un content admin? Sunt sigur ca nimeni, dar refresh-ul e o introducere buna la problema noastra de astazi. Aceea este: cum sa scapam de refresh?

Ma gandesc ca ati auzit de AJAX. Tehnica prin care Flickr sau Gmail s-au inzorzonat cu titluri ca „super-accesibil” si au devenit foarte faimoase este insa pentru multi cam greu de pus in practica; mai ales cand deja se discuta despre unobtrusive JavaScript, adica separarea codului JS de structura HTML a documentului, iar componenta de baza a implementarii AJAX este tocmai JavaScript. In mare, AJAX presupune schimbarea continutului unui div. Da, suna floare la ureche. Dar AJAX executa query-uri catre baza de date ori de cate ori userul o cere, fara sa fie necesar refresh-ul intregii pagini. Incearca asta prin JS simplu si ai sa vezi ca nu prea e posibil.

Fara sa ne abatem prea mult de la tema, sa vedem cum functioneaza teoretic AJAX. Prin JavaScript se preia cererea de la user si se transfera unui mic engine XML, care va executa un request HTTP si va inapoia ca rezultat un fisier. Acel fisier va fi executat pe server si deci poate contine scripting. De exemplu, un query catre SQL. Rezumand, AJAX vine de la Asynchronous JavaScript And XML, insemnand afisarea continutului in mod asincron (fara refresh) folosind JS si XML.

Micul AJAX
Acum, n-am studiat prea mult AJAX si s-ar putea sa nu simt nevoia acestui lucru, pentru doua motive. Unul ar fi ca mie chiar imi place refresh-ul si n-as vrea sa incurc oamenii prezentandu-le o pagina care se face din ce in ce mai mare. Alt motiv este existenta functiilor AHAH. Micul AHAH vine ca o solutie eleganta la problemele ridicate de AJAX. Sau cel putin mie asa mi se pare.

Sunt pus in fata unei probleme de accesibilitate. Doresc sa implementez in CMS-ul meu posibilitatea de a sterge un articol. Userii lui sunt content admini sau chiar manageri de firma, din cei care dau click-uri aiurea si ies din birou urland ca cine a sters din „sait”. As vrea ca atunci cand apasa pe butonul de sters, sa il fac sa se gandeasca de doua ori. Asa ca voi afisa o casuta de tip „Esti sigur?”. Nu ar fi prea greu, tot ce am de facut este sa scriu cateva randuri de JavaScript. Insa exista doua probleme. Prima e legata de design, pentru ca pana astazi nu am auzit pe nimeni ca ar putea modifica in vreun fel casuta de dialog pe care o arati din JS. A doua problema este cu redirectarea. Nu as vrea sa o folosesc. Totul as vrea sa decurga rapid, pentru ca deja maresc timpul de actiune prin introducerea casetei de dialog.

Wordpress rezolva elegant aceasta problema, desi nu la fel de elegant precum o vom face noi. Si daca ne gandim la platformele de blogging, deducem si un aspect legat de server, pe care o intuiti deja: daca respectiva stergere s-ar desfasura pe un sistem cu mii de utilizatori, cum ar fi blogger.com, un redirect ar insemna recalcularea intregii pagini, ceea ce ar incarca inca putin serverul. Sa vedem cum am rezolva mica noastra problema folosind AHAH.

Asynchronous HTTP And HTML
Pe scurt, AHAH. Sa trecem in sfarsit la fapte si sa analizam functiile de baza ale acestei tehnici. Vom folosi putin PHP, o baza MySQL si desigur JavaScript.


function ahah(url, target, delay) {
document.getElementById(target).innerHTML = '<span style="border:5px solid black;background-color:purple;color:white;">loading</span>';
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
if (req != undefined) {
req.onreadystatechange = function() {ahahDone(url, target, delay);};
req.open("GET", url, true);
req.send("");
}
}


Aceasta este prima functie. Am spus ca AHAH se va ocupa cu inlocuirea contentului unui block HTML cu un alt content, obtinut dintr-un fisier extern, care este in prealabil rulat de server. Parametri:


<ul>
<li><i>url</i> - calea catre fisierul care va fi incarcat </li>
<li><i>target</i> - id-ul blockului unde se va afisa continutul fisierului de la <i>url</i></li>
<li><i>delay</i> - intervalul pentru retrimiterea aceluiasi continut � util de exemplu pentru un chat HTML</li>
</ul>



Incepem cu identificarea block-ului tinta si inlocuirea lui cu o secventa de „loading”, pe timpul incarcarii noului content. Putem sa sarim acest pas:


document.getElementById(target).innerHTML = '<span style="border:5px solid black;background-color:purple;color:white;">loading</span>';


Urmatoarea secventa de cod initiaza un request HTTP fie prin DOM, fie prin ActiveX. Apoi, daca am reusit initierea cererii, urmeaza chemarea celei de a doua functii, care va schimba continutul blockului <i>target</i> cu noul continut:


function ahahDone(url, target, delay) {
if (req.readyState == 4) { // only if req is "loaded"
if (req.status == 200) { // only if "OK"
document.getElementById(target).innerHTML = req.responseText;
} else {
document.getElementById(target).innerHTML="ahah error:n"+req.statusText;
}
if (delay != undefined) {
setTimeout("ahah(url,target,delay)", delay); // resubmit after delay
//server should ALSO delay before responding
}
}
}


Sa vedem cum folosim aceste functii pentru a ne rezolva mica problema legata de bloguit.

AHAH la lucru
Inainte de a incepe, iata sql-ul pentru baza de date pe care o vom folosi:


CREATE TABLE `employees` (
`id` int(11) NOT NULL auto_increment,
`name` text NOT NULL,
`salary` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM;


HTML-ul de care avem nevoie in index.php se rezuma la doua div-uri:


<div id="target">
<?php include "table.php"; ?>
</div>
<div id="dialog">
</div>


In primul div am inclus table.php, unde citim intregul tabel de articole din baza de date. Daca vom avea nevoie de un fisier care sa initializeze baza de date, este bine sa il includem astfel in fiecare fisier care va lucra cu baza:


include_once ("db.php");


include_once il impiedica sa fie inclus de mai multe ori. Este nevoie de acest lucru deoarece fisierele sunt parsate de PHP singure, deoarece sunt cerute astfel prin HTTP request. Aceasta problema se aplica din pacate si la orice alte functii ar putea folosi acel fisier.

O data incarcat tabelul, vom avea nevoie de casuta de dialog. Pentru ea, am setat urmatorul stil:


#dialog{
position:absolute;
top:35%;
left:35%;
background-color:#f3f3f3;
border:5px solid green;
padding:20px;
display:none;
z-index:100;
}


Sa includem casuta de dialog folosind AHAH. Motivele, mai tarziu.


function dialogue(){
show('dialog');
ahah('yesno.php','dialog');
}


Fisierul pe care il incarcam aici, yesno.php, are contentul casutei de dialog. La un click pe “Nu”, casuta de dialog se ascunde:


<input type="button" value="Nu" onclick="hide('dialog')" />


Iata-ne deci casuta(fisierul yesno.php):


<center><h1>Sunteti sigur?</h1>
<input type="submit" name="delete" value="Da" />
<input type="button" value="Nu" onclick="hide('dialog')" />
</center>


Casuta de dialog va fi afisata la click pe fiecare din butoanele “delete” pe care le afisam in tabel, in fisierul table.php:


<td><a onclick="dialogue();" class="hand">delete</a></td>


Astfel, tabelul va arata in final astfel(fisierul table.php):


<table>
<tr>
<th>Titlu</th>
<th>Categorie</th>
<th>Functii</th>
</tr>
<?php
include_once ("db.php");
$data=select('employees');//functia face un query SELECT * FROM �parametru� si inscrie rezultatul intr-un array
foreach($data as $value){
echo '<tr>
<td>'.$value['name'].'</td>
<td>$ '.$value['salary'].'</td>
<td><a onclick="dialogue();" class="hand">delete</a></td>
</tr>';
}
?>
</table>


Iata functiile auxiliare care ne-au ajutat la v-ati ascunselea, show(target) si hide(target):


function hide(target){
document.getElementById(target).style.display='none';
}
function show(target){
document.getElementById(target).style.display='block';
}


Pana acum avem un tabel legat la o baza de date si o casuta de dialog care apare si dispare. Singurul lucru pe care il mai avem de facut este ca la click pe “Da” in casuta de dialog, serverul sa stearga entry-ul si sa reintoarca tabelul, pentru a afisa entry-urile ramase.

Adevarata munca
Vom crea un alt fisier, delete.php, pentru a rula un query DELETE. Nu uitati sa includeti fisierul care ofera acces la baza de date cu include_once. Insa, pentru a putea determina entry-ul care trebuie sters, ne trebuie cheia lui primara (primary key), in speta, ID-ul. Acesta va fi preluat de casuta de dialog, caci ea este legatura noastra intre click-ul pe “delete” si script. Vom trimite id-ul prin URL:


<td><a class="hand" onclick="dialogue('.$value['id'].')">delete</a></td>


Asa. Acum trebuie sa mergem sa schimbam functia dialogue, adaugandu-i un parametru: id.


function dialogue(id){
show('dialog');
ahah('yesno.php?id='+id,'dialog');
}


Astfel, atasam fisierului cerut prin AHAH parametrul id: yesno.php?id=id. Fisierul yesno.php va chema apoi fisierul delete.php cu acest parametru:


<input type="submit" name="delete" value="Da" onclick="go('<?=$_GET['id']?>')" />


Sa analizam ultima functie pe care o vom folosi, go(id). Ea ascunde casuta de dialog si apoi cheama pe rand fisierele delete.php?id= si table.php.


function go(id){
hide('dialog');
ahah('delete.php?id='+id, 'target');
ahah('table.php','target');
}


Gata, s-a facut.

Si asta a fost: tabelul este reafisat, iar daca apasam pe “Da”, respectivul entry este sters.

Puteti descarca codul integral sau puteti vedea rezultatul nostru online.


_______________________________________


 
   
Pagini: 1  
Mergi la