Projekti Lista e Detyrave me PHP, MySQL dhe jQuery

Albforumi

Primus registratum
Projekti Lista e Detyrave me PHP, MySQL dhe jQuery

<p style="text-align: center;">
shkarko-kodin.png
shiko-demon.png
</p>


Ideja për të koduar një aplikacion ku të ruaja detyrat më erdhi nga kërkesat e punës, sepse klientët shpesh më kërkonin në telefon ndryshime/shtime në faqet e tyre dhe ndonjëherë më qëllonte mos t’i mbaja mend të gjitha. Pasi morra Mac, gjeta “The Hit List“, një aplikacion që ofronte më tepër se çdo tentativë që mund të bëja unë, prandaj e lashë si projekt. Tashmë ju riktheva sepse mu duk interesant të përfshihet në një guidë, sepse është i thjeshtë për tu ndërtuar, por përmban disa funksionalitete nga të cilat mund të mësoni.</p>


Për ta nisur mbarë, më duhet t’ju them se aplikacioni varet tërësisht nga Javascript (me jQuery) dhe nuk punon tek përdoruesit që e kanë të çaktivizuar. E pranoj, jam treguar dembel dhe nuk doja ta komplikoja kodin më tepër. Ndërsa disa mund të argumentojnë se Javascript është tashmë standart dhe shumë pak njerëz e kanë të çaktivizuar, përsëri s’mund t’ja lini gjërat në dorë rastësisë. Gjithmonë ofroni përmbajtje dhe funksionalitet alternativ ndaj atyre Javascript.</p>
Kujt i shërben guida


Ndërsa të gjithë mund të mësojnë diçka nga kjo guidë, ata që do mund të përfitojnë më tepër janë programuesit me eksperiencë. Kodi PHP dhe ai Javascript janë të një kompleksiteti normal, por sidoqoftë ju duhet të njihni mirë ambjentin dhe të orientoheni pa problem me teknologjitë në fjalë që të përfitoni maksimalisht. Guida do i shërbejë edhe atyre që njohin mirë PHP por jo Javascript, sepse do ju paraqesë fuqinë dhe thjeshtësinë e jQuery: selektimin e elementëve HTML, marrjen dhe vendosjen e atributeve, shtimi dhe heqja dinamike e klasave, thërritje AJAX, etj.</p>
Disa fjalë rreth organizimit të kodit


E gjithë logjika e aplikacionit ndodhet në 4 skedarë:</p>

index.php =&gt; ndodhet kodi bazë HTML dhe krijimi i objektit.
klasa/detyrat.php =&gt; klasa e detyrave me funksione për të listuar, shtuar dhe ndryshuar gjendjen e detyrave.
rifresko.php =&gt; kodi PHP që thërritet me AJAX për të shtuar dhe ndryshuar gjendjen e detyrave.
js/logjika.js =&gt; kodi Javascript (jQuery) që krijon funksionalitetet nga kahu-klientit.



Për secilin nga këto skedarë do krijoj nga një seksion ku do ju shpjegoj logjikën e funksionimit dhe kodin e komentuar.</p>
Kodi bazë


Në index nuk kemi asgjë të veçantë. Ashtu si çdo faqe, krijohet struktura themelore HTML dhe përfshihen skedarët CSS dhe Javascript. Kodi më poshtë është pjesa ku kam shkruar kodin HTML të inputit e butonit dhe kam thërritur një funksion për të listuar detyrat.</p>

&lt;div id=&quot;mbajtesi&quot;&gt;
&lt;div id=&quot;shkruaj&quot;&gt;
&lt;input type=&quot;text&quot; name=&quot;shto-detyre&quot; id=&quot;shto-detyre&quot; /&gt;
&lt;button type=&quot;button&quot; id=&quot;shto-detyre-butoni&quot;&gt;Shto Detyre&lt;/button&gt;
&lt;/div&gt;
&lt;div id=&quot;mbajtesi-detyrave&quot;&gt;
&lt;?php echo $detyrat-&gt;listoDetyrat(); ?&gt;
&lt;/div&gt;
&lt;/div&gt;



Për ta bërë gjithçka të shfaqet bukur, kam shkruar disa rregulla CSS të cilat nuk kam ndërmend ti përfshij në këtë guidë, por mund t’i shihni duke shkarkuar kodin në fillim të faqes.</p>
Klasa e detyrave


Mua më pëlqen të kodoj me objekte dhe e ruaj këtë praktikë edhe në projekte të vogla. Në këtë rast kam krijuar një klasë të vogël që ka vetëm 4 variabla private, __construct() dhe 3 funksione. Pra një klasë shumë e vogël dhe ku kodimi me objekte mund edhe të ishte mënjanuar. Megjithatë, nëse ju lind nevoja ta zgjeroni e ta përdorni për projekte tuajat, implementimi është fare i thjeshtë.</p>

&lt;?php
class Detyrat{
//Variablat me te dhenat e databazes.
private $db_host = 'localhost';
private $db_emri = 'root';
private $db_fjalekalimi = '';
private $db_databaza = 'test';

//Variabel per te ruajtur emrin e tabeles. Nese do me duhet ta
//ndryshoj me vone, thjeshte ndryshoj variablen dhe jo te gjitha
//queryt qe do bej.
private $tb_detyrat = 'projekti_detyrat';

//Funksioni __construct() therritet ne momentin qe klasa krijohet me fjalen
//kyce 'new'. Ne kete rast kam bere lidhjen me databazen.
function __construct(){
$lidhja = mysql_connect($this-&gt;db_host, $this-&gt;db_emri, $this-&gt;db_fjalekalimi);
mysql_select_db($this-&gt;db_databaza);
}

//Funksion qe liston detyrat.
public function listoDetyrat(){
//Variablat $html do mbaje html-ne e gjeneruar nga funksioni.
$html = '';
//Bejme nje query per te marre te gjitha detyrat nga databaza te
//renditura sipas dates ne rend zbrites (data me e re ne krye).
$rezultatet = mysql_query(&quot;SELECT id, titulli, data, mbaruar, anuluar FROM $this-&gt;tb_detyrat ORDER BY data DESC&quot;);
//mysql_num_rows() kthen numrin e rreshtave te zgjedhur nga query.
$numri_rezultateve = mysql_num_rows($rezultatet);
//$numeruesin do e perdor per te pare nese rreshti aktual ne loop-en while()
//me poshte eshte i barabarte me numrin e rezultateve te kthyera.
$numeruesi = 1;
//Nese $numri_rezultateve nuk eshte 0 (qe perkthehet edhe si FALSE),
//do te thote se kemi te pakten nje detyre ne databaze.
if($numri_rezultateve){
//Bejme loop ne rreshtat e kthyer.
while($vlerat = mysql_fetch_array($rezultatet)){
//Tre variablat jane per te ruajtur disa klasa CSS qe do te shtohen dinamikisht,
//per te shenuar detyrat si te mbaruara dhe per ti caktivizuar checkbox-et.
$shto_klase = array();
$mbaruar = '';
$caktivizuar = '';

//Data dhe ora ne MySQL ruhet ne formatin YYY-MM-DD HH:MM:SS. Ne na duhet
//ne formatin DD/MM/YY HH:MM:SS. explode() i pare e ndan daten dhe oren sipas karakterit &quot; &quot;
//duke kthyer nje vektor me 2 element (data dhe ora) te cilet kapen nga list().
//explode() i dyte e ndan daten sipas karakterit &quot;-&quot; duke kthyer nje vektor me 3 elemente
//(viti, muaji, dita) qe kapen nga list(). Ne fund i bashkoj variablat per te marre daten
//ne formatin qe dua.
list($data, $koha) = explode(' ', $vlerat['data']);
list($viti, $muaji, $dita) = explode('-', $data);
$data = &quot;$dita/$muaji/$viti $koha&quot;;

//Nese $numeruesi eshte sa numri i rezultateve te kthyera, atehere jemi ne rreshtin e fundit.
//Shtojme klasen &quot;pa-kontur&quot; ne vektor e cila heq konturin &quot;border-bottom&quot;. Thjeshte nje prekje
//e kendshme vizuale.
if($numeruesi == $numri_rezultateve){ $shto_klase[] = 'pa-kontur'; }
//Nese detyra eshte e anuluar, shtojme klasen &quot;anuluar&quot; ne vektor dhe variables $caktivizuar
//i japim vlere atributin HTML qe caktivizon checkbox-in.
if($vlerat['anuluar'] == 1){ $shto_klase[] = 'anuluar'; $caktivizuar = 'disabled=&quot;disabled&quot;'; }
//Nese detyra eshte shenuar si e mbaruar, variables $mbaruar i japim vlere atributin HTML qe e
//shenon (me tick) checkbox-in.
if($vlerat['mbaruar'] == 1){ $mbaruar = 'checked=&quot;chkecked&quot;'; }

//Ndertojme kodin HTML me atributet dhe vlerat e duhura. Div-it mbajtes i vendosim klasat qe
//ndodhen ne vektor me implode (qe bashkon elementet e vektorit ne tekst duke i ndare me nje
//karakter te caktuar) dhe i japim nje &quot;id&quot; sa id-ja e rreshtit ne databaza. ID-ja do te perdoret
//ne kodin Javascript per te kuptuar cfare rreshti eshte.
$html .= '&lt;div id=&quot;' . $vlerat['id'] . '&quot;&gt;';
//Checkbox-it i vendosim variablat $mbaruar dhe $caktivizuar qe jane respektivisht shenimi (tick)
//dhe caktivizimi.
$html .= '&lt;input type=&quot;checkbox&quot; ' . $mbaruar . ' ' . $caktivizuar . ' /&gt; ';
$html .= '&lt;span&gt;' . $data . '&lt;/span&gt;';
$html .= '&lt;p&gt;' . stripslashes($vlerat['titulli']) . '&lt;/p&gt;';
//Ky eshte butoni i anulimit te detyres.
$html .= '&lt;a href=&quot;#&quot;&gt;&lt;img src=&quot;images/fshi.png&quot; /&gt;&lt;/a&gt;';
$html .= '&lt;/div&gt;';

//Numeruesi inkrementohet me 1 per cdo loop te while().
$numeruesi++;
}
//Kthejme kodin $html qe kemi gjeneruar.
return $html;
//Ky else egzekutohet nese ne databaze nuk ka asnje detyre.
} else{
return 'Nuk keni shtuar akoma asnje detyre. Filloni te shtoni tani!';
}
}

//Funksion per te shtuar detyre. I vetmi parameter eshte titulli.
public function shtoDetyre($titulli){
//Vendosim timezone-en e Shqiperise ne menyre qe ora mos te varet
//nga ora e serverit.
date_default_timezone_set('Europe/Berlin');
//Pastrojme titullin nga karakteret qe mund te prishin query-n.
$titulli = mysql_real_escape_string($titulli);
//Krijojme daten dhe oren ne formatin e MySQL.
$data = date('Y-m-d H:i:s');
//Per siguri kontrollojme qe titulli te mos jete bosh.
if($titulli != ''){
//Shtojme detyren ne databaze.
$rezultatet = mysql_query(&quot;INSERT INTO $this-&gt;tb_detyrat (titulli, data) VALUES ('$titulli', '$data')&quot;);
}
}

//Funkion per te ndryshuar gjendjen e mbarimit dhe anulumit. Parametrat jane
//ID e rreshtit dhe tipi i gjendjes (anulo ose mbaro).
public function ndryshoGjendjen($id, $tipi){
//Per siguri e kthejme ID-ne ne integer (numer).
$id = (int) $id;
//Nese tipi eshte 'anulo', atehere vendosim fushen 'anuluar' ne 1 per rreshtin
//me ID-ne e dhene.
if($tipi == 'anulo'){
$rezultatet = mysql_query(&quot;UPDATE $this-&gt;tb_detyrat SET anuluar = 1 WHERE id=$id&quot;);
//Nese tipi eshte 'mbaro' atehere invertojme vleren e fushes 'mbaruar'. Pjesa &quot;mbaruar = NOT mbaruar&quot;
//ben invertimin. Psh, nese mbaruar eshte nje, shprehja kthehet ne: mbaruar = NOT 1 =&gt; mbaruar = 0.
} elseif($tipi == 'mbaro'){
$rezultatet = mysql_query(&quot;UPDATE $this-&gt;tb_detyrat SET mbaruar = NOT mbaruar WHERE id=$id&quot;);
}
}
}
?&gt;



Guida do të zgjatej pambarimisht nëse do ju shpjegoja çfarë bën çdo rresht, prandaj duhet të kënaqeni me komentimin, të cilin jam munduar ta bëj sa më të qartë. Për t’a thënë shkurt, klasa ka 3 funksione, ku më kompeksi është ai i listimit të detyrave. Në të, marr rreshtat e detyrave nga databaza dhe gjeneroj kod HTML për ti vendosur si duhet në faqe. Kam përdorur një teknikë të trashëguar nga Javascript, atë të shtimit të klasave për të përcaktuar gjëndje të ndryshme për detyrat (e plotësuar, anuluar, etj). Në vend që të bëja zinxhire me if() dhe ti lidhja kodet HTML në mënyra totalisht të pa-kuptueshme, kam krijuar disa variabla të cilave u shtohen emra klasash CSS për gjendje të ndryshme. Në fund i bashkoj bashkë dhe i vendos në pozicionet e duhura të kodit HTML dhe dal me një kod të lexueshëm e të thjeshtë për t’u mirëmbajtur. Dy funksionet e tjera, ai i shtimit dhe ndryshimit të gjendjes duhet të jenë të lehtë për tu kuptuar.</p>


Kodi HTML që gjenerohet nga funksioni listoDetyrat() është si më poshtë. Elementët stilohen dhe pozicionohen me CSS për t’i bërë më interesant.</p>

&lt;!-- div me klase &quot;detyrat&quot; dhe id sa ID-ja e rreshtit ne databaze --&gt;
&lt;div class=&quot;detyrat&quot; id=&quot;49&quot;&gt;
&lt;!-- checkbox-i ku zgjidhet nese eshte mbaruar apo jo detyra --&gt;
&lt;input type=&quot;checkbox&quot; checked=&quot;chkecked&quot;  /&gt;
&lt;!-- data e detyres --&gt;
&lt;span&gt;06/08/2010 18:40:54&lt;/span&gt;
&lt;!-- titulli i detyres --&gt;
&lt;p&gt;Mendo nje guide interesante per Feniksi.com&lt;/p&gt;
&lt;!-- butoni qe anulon detyren --&gt;
&lt;a href=&quot;#&quot;&gt;&lt;img src=&quot;images/fshi.png&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;

Kodi i rifreskimit


Ky është një skedar që krijon një “API” eksluzivisht për thërritjet AJAX dhe nuk del asnjëherë në skenë sepse punon në sfond. Përmes disa parametrave që kalohen si variabla GET (të cilat dërgohen nga kodi Javascript; më pas për të), përcaktohet veprimi që do të kryhet në sfond. Kodi është i thjeshtë e s’duhet t’ju lërë pa qartësi.</p>

&lt;?php
include('klasa/detyrat.php');
$detyrat = new Detyrat;
//Nese jane vene variablat GET 'id' dhe 'veprimi atehere
//therritja AJAX vjen per te ndryshuar gjendjen e mbarimit ose anulimit.
if(isset($_GET['id']) &amp;&amp; isset($_GET['veprimi'])){
$id = $_GET['id'];
$veprimi = $_GET['veprimi'];
//Kontrollojme nese veprimi eshte nje nga 2 alternativat e mundshme
//dhe therrasim funksionin.
if($veprimi == 'mbaro' || $veprimi == 'anulo'){
$detyrat-&gt;ndryshoGjendjen($id, $veprimi);
}
//Nese eshte vendosur titulli atehere therritja AJAX vjen per
//te shtuar nje detyre te re.
} elseif(isset($_GET['titulli'])){
//urldecode() e kthen titullin ne nje tekst normal, pa karakteret
//e futura nga URLEncode() ne kodin Javascript.
$titulli = urldecode($_GET['titulli']);
//Nese titulli nuk eshte bosh, therrasim funksionin e shtimit te detyres
//dhe ate te listimit te detyrave, ne menyre qe detyrat te rifreskohen.
if($titulli != ''){
$detyrat-&gt;shtoDetyre($titulli);
echo $detyrat-&gt;listoDetyrat();
}
}
?&gt;



Si mund ta shikoni, nuk kam bërë asgjë më shumë se sa kontrollimi i variablave GET dhe thërritja e funksionit të duhur nga klasa e detyrave. Praktikisht është një ndërfaqe midis thërritjeve AJAX dhe egzekutimit të funksioneve PHP.</p>
Logjika jQuery


jQuery është ndër të paktat teknologji që unë njoh që më habit sa herë kodoj me të. Gjithmonë zbuloj diçka të re dhe më përforëcohet mendimi që ndodhet në majën e librarive/framework, e jo vetëm për Javascript. Ndërsa librari të tjera mundohen të lehtësojnë funksionalitete dhe të ofrojnë pattern-a për kodim të organizuar që [për mendimin tim totalisht personal] nuk janë asgjë më tepër se sa një dozë e tepërt kompleksiteti, jQuery i shton Javascript një shtresë aq të fuqishme sa e bën të duket një gjuhë komplet e re. Ju kujtoj që Javascript ka qenë thjeshtë një gjuhë skriptimi nga kahu-klientit për të krijuar ndonjë efekt të lezetshëm për kohën dhe vetëm si pasojë e librarive ka aksesueshmërinë dhe fuqinë e sotshme për të qenë e pandarë në çdo faqe interaktive. Nëse nuk ju ka pëlqyer ideologjia e Javascript më parë, jepini një shans jQuery dhe ju siguroj që do ndryshoni mendim.</p>


Të kthehemi në realitet! Kodi Javascript që unë kam shkruar përdor disa funksione të jQuery për të zgjedhur relativisht elementë (pra jo zgjedhje direkte, por duke përdorur funksione si parent() apo children()), për të marrë dhe modifikuar vlerat e atributëve HTML dhe për të bërë disa thërritje AJAX. Gjithçka është e thjeshtë dhe intuitive, por thërritjet AJAX janë idiotisht të lehta. Me vetëm një funksion mund të thërritet një url me parametra GET dhe të merret rezultati i kthyer. Mund të shtohen gjithashtu edhe evente nëse thërritja është e sukseshme, kur nis apo përfundon për të bërë përshembull njoftues statusi (në pritje, përfundoi, etj). Këto të fundit mua nuk mu nevojitën, por hidhini një sy dokumentimit të jQuery.</p>


Një gjë që doja t’ju sqaroja është funksioni live(). Unë e kam mësuar këtë “the hard way” kur nisa të merrem me jQuery, prandaj po ju kursej pak dhembje koke. Normalisht, eventet e elementëve të caktuar HTML funksionojnë për elementë të krijuar tashmë në DOM (Document Object Model). Nëse eventet i përkasin elementëve të krijuar dinamikisht apo rezultateve të marra me AJAX, kodi nuk do funksionojë. Kjo është sjellje e Javascript, por për fat të mirë jQuery ofron alternativa. Në vend që të shkruajmë $(‘elementi’).click(), shkruajmë $(‘elementi’).live(‘click’). Funksioni live() i krijon eventet për elementët egzistues dhe për ato që do të krijohen në të ardhmen. Zgjidhje e thjeshtë, pa telashe dhe që funksionon për mrekulli.</p>


E fundit, kam përdorur një plugin për jQuery që quhet urlencode”. E vetmja gjë që plugini bën (dhe që jQuery duhet ta kishte në bazën e tij) është t’i enkodojë tekstet dhe t’i bëjë gati për tu përdorur si variabla GET dhe unë e kam përdorur për të enkoduar titullin e detyrës kur shtohet. Të njëjtën gjë bën funksioni urlencode() në PHP, ndërsa urldecode() – prapë në PHP – bën të kundërtën; i heq karakteret e enkoduara dhe e kthen tekstin në normalitet.</p>

$(document).ready(function(){
//Eventi 'click' i checkbox-it te detyrave. Marrim id-ne e rreshtit
//permes atributit &quot;id&quot; te div-it meme dhe bejme nje thirrje AJAX
//ku kalojme id-ne dhe veprimin 'mbaro'. parent() zgjedh elementin
//meme te inputit ndersa attr() merr vleren e nje atributi.
$('div.detyrat input').live('click', function(){
var id = $(this).parent().attr('id');
$.get('rifresko.php?id=' + id + '&amp;veprimi=mbaro');
});

//Eventi mouse-i siper dhe mouse-i jashte per div-in e detyrave. Nese vendoset
//mouse-i siper, shfaqim imazhin e anulumit, ndersa per mouse-i jashte e heqim
//imazhin. Kam kontrolluar me hasClass() nese div-i ka klasen 'anuluar' ne menyre
//qe mos ta shfaq imazhin per detyra te anuluar. children() zgjedh element femije
//te div-it, ndersa fadeIn dhe fadeOut bejne shfaqje dhe zhdukje te animuar.
$('div.detyrat').live('hover', function(eventi){
if(eventi.type == 'mouseover'){
if(!$(this).hasClass('anuluar')){
$(this).children('a').fadeIn(150);
}
} else{
$(this).children('a').fadeOut(150);
}
});

//Eventi 'click' i butonit te anulimit. Kam marre vleren e atributit &quot;id&quot; te
//elementit meme, i kam shtuar klasen 'anuluar' elementit meme me addClass(),
//i kam shtuar nje atribut 'disabled' checkbox-it dhe ne fund kam bere nje
//therritje AJAX me veprimin 'anulo'. Kam shkruar gjithashtu &quot;return false&quot;
//qe te caktivizoj linkun nga veprimi normal.
$('div.detyrat a').live('click', function(){
var id = $(this).parent().attr('id');
$(this).parent().addClass('anuluar');
$(this).parent().children('input').attr('disabled', 'disabled');
$.get('rifresko.php?id=' + id + '&amp;veprimi=anulo');
return false;
});

//Eventi 'click' i butonit te shtimit te detyrave. Kam kontrolluar fillimisht nese vlera e inputit
//nuk eshte bosh. Me pas e kam bere inputin bosh me attr(), e kam enkoduar titullin (me nje plugin te
//jQuery qe quhet &quot;urlencode&quot; dhe ne fund kam bere therritje AJAX qe te shtoj detyren dhe rezultatin e kthyer
//(lista e detyrave e rifreskuar) e fus ne div-in mbajtes te detyrave.
$('button#shto-detyre-butoni').click(function(){
var elementi = $('input#shto-detyre');
var titulli = elementi.val();
if(titulli != ''){
elementi.attr('value', '');
titulli = $.URLEncode(titulli);
$.get('rifresko.php?titulli=' + titulli, function(kthimi) {
$('div#mbajtesi-detyrave').html(kthimi);
});
}
});

//Nje funksion i cili e shton detyren nese shtypet butoni &quot;enter&quot; ne input. Butoni
//&quot;enter&quot; ka kodin 13 dhe kur shtypet, kam therritur funksionin &quot;click&quot; te percaktuar
//me siper.
$('input#shto-detyre').keypress(function(eventi){
if(eventi.keyCode == 13){
$('button#shto-detyre-butoni').click();
}
});
});

Përfundimi


Aplikacioni që kam krijuar, duke përfshirë kodin PHP dhe Javascript është i një kompleksiteti që duhet ti pëlqejë programuesëve më një farë eksperience. Në jetën reale një aplikacion i tillë mund të mos ishte edhe aq i nevojshëm, por funksionalitetet që ai ofron, sidomos ato Javascript duhet të jenë interesante për tu implementuar në projektet tuaja. Sidomos, shërben për t’ju prezantuar me jQuery, AJAX dhe kombinimin e Javascript me PHP.</p>


Shpresoj t’ju ketë pëlqyer ky mësim/aplikacion dhe të përfitoni sa më shumë prej tij. Mos hezitoni të komentoni për çdo koment, pyetje apo nëse ndonjë gabim në funksionalitetet e Listës së Detyrave.</p>


Mësim të mbarë.</p>



</p>




Projekti “Lista e Detyrave” me PHP, MySQL dhe jQuery &euml;sht&euml; nj&euml; postim nga: Feniksi.Com - Thesari i Njohurive</p>
abPDhOa8eCU

Per me shume artikuj te ngjashem vizitoni: http://www.feniksi.com/?p=1532
 
Top