Sistem simplu de votare (rating)

În urmă cu câțiva ani s-a făcut mare tam tam cu web 2.0. Internetul s-a reinventat, gradul de implicare al utilizatorului a crescut, iar tehnologiile au început să fie folosite la adevărata loc capacitate. Dacă înainte de 2003-2004 termenul de aplicație web nu exista decât pe hârtie (probabil), după 2004 google a dat startul cu binecunoscutul gmail, ducând web mailul la un nivel la care hotmail sau yahoo! nici nu visau (începând de la organizarea mesajelor – care între noi fie vorba, a fost preluată de microsoft în office 2010 – și terminând cu capacitatea de stocare).

Ce a reprezentat această revoluție 2.0? În principiu, modul în care utilizatorul final interacționează cu un site. Astfel au apărut wikipedia (un site unde utilizatorii pot scrie articole), youtube (unde utilizatorii generează conținutul) sau blogurile (unde vizitatorii pot comenta pe marginea unui articol). O altă funcție care a apărut pe multe site-uri sunt voturile. Steluțele alea mici prin care apreciezi calitatea articolului sau a filmului postat. Și cum sunt mulți care nu știu să le folosească, m-am hotărât să scriu un mic articol. Metoda mea mi se pare cea mai curată (din punct de vedere al codului folosit) din cele existente. De asemenea, îți voi arăta și cum să faci un request ajax (se poate să vorbim de web 2.0 fără să amintim de ajax? :D ) pentru a trimite serverului ce a votat utilizatorul și să returnezi un mesaj din partea serverului folosindu-te de JSON. Desigur, va trebui să faci procesarea voturilor pe server, cu limbajul preferat (php, asp, ruby etc) deoarece cunoștințele mele de programare server side sunt destul de limitate.

Avem nevoie de o imagine cu „stările” steluțelor (pot fi frunze, pisici, pahare, etc). De ce trei? Una pentru background (cea albă), una pentru hover (cea galbenă) și una pentru a arăta votul curent (cea roșie). Desigur, dimensiunile rămân la discreția fiecăruia, ajustându-le în funcție de necesități. De asemenea, se pot folosi și trei imagini separate, chiar dacă nu este recomandat.

Folosind această imagine (și încă una, mai mare), îți voi arăta cum să încropești rapid un sistem de vot foarte simplu.

Markup

Fie că vrei să faci un sistem de votare, fie că vrei doar să afișezi media voturilor, markup-ul e același: două span-uri :

<span class="rating"><span style="width:25%"></span></span>

<span class="rating small"><span style="width:52%"></span></span>

Am specificat width inline din motive de… afișare. Fiecare stea înseamnă 20%. Astfel, trei stele înseamnă 60%, patru 80%, două 40% șamd.

Css-ul în schimb, e un pic mai lung de atât:

.rating,
.rating span {
	float:left;
	height:64px;
	width:320px;
	background:url(../images/stars.png) repeat-x left top;
	margin-right:1em;
}
.rating.small,
.rating.small span {
	height:16px;
	width:80px;
	background-image:url(../images/stars_mici.png)
}
	.rating span,
	.rating.small span {
		float:none;
		display:block;
		height:64px;
		background-position:left -129px
	}
	.rating.small span {
		height:16px;
		background-position:left -32px
	}

Ce se întâmplă?

  1. .rating & .rating span:
  2. Setăm fie float fie display:block pentru elementul ce conține stelele. Astfel, putem specifica și dimensiunile elementului
  3. Setăm înalțimea unei stele și lățimea a cinci stele.
  4. Setăm imaginea de fundal
  5. .rating.small & .rating.small span
  6. Fiind vorba de stele ceva mai mici, specificăm alte dimensiuni și altă imagine

Cum votăm?

Avem două posibilități:
1) ne complicăm cu ceva cod html
2) ne complicăm cu ceva cod js ce injectează html

Mie îmi place mai mult cea de-a doua variantă. Prin urmare, modificăm puțin markup-ul inițial în:

<span class="rating" id="stars-1"><span style="width:25%"></span></span>

S-a aduăugat id-ul din motive de… identificare. Vrem să trimitem serverului ce ID are fiecare stea. De aici, începe distracția cu javascript :D

var removeThanks ='';
$('.rating:not(.ignore)').each(function(){
	var t = $(this);
	for(var i=1;i<=5;i++){
		$(document.createElement('a')).attr('href', '#').addClass('vot-'+i).appendTo(t);
	}
	t.addClass('active').find('a').click(function(){
		$.ajax({
			type: "GET",
			url: "vot.php",
			data: { nota:t.find('a').index(this), id:t.attr('id') },
			dataType:'json',
			cache: false,
			success: function(data){
				t.addClass('votat').find('span').width(data.votNou+'%');
				window.clearTimeout(removeThanks);
				$('.thanksForVoting').remove();
				$(document.createElement('div')).addClass('thanksForVoting').css({
					left:t.offset().left+t.width(),
					top:t.offset().top
				}).text(data.raspuns).appendTo('body');
				removeThanks = window.setTimeout(function(){
					$('.thanksForVoting').fadeOut(function(){$(this).remove()})
				}, 2000);
			}
		});
		return false;
	});
});
&#91;/js&#93;

<h4>Explicații</h4>
<ul>
	<li>Iterăm fiecare element cu clasa <code>rating</code> dar fără clasa <code>ignore</code>. Astfel putem avea și doar stelele afișate, fără să se întâmple nimic la click (de exemplu, stelele votate)</li>
	<li>În fiecare element <code>rating</code> injectăm cinci link-uri</li>
	<li>La fiecare link atașăm un event click ce va face un request ajax spre server. Deoarece linkul de vot nu variază (sau cel puțin așa ar fi normal), acesta este specificat direct în codul JS (vot.php)</li>
	<li>Trimitem către server <code>ID</code>-ul și nota (de la 0 la 4) pe care s-a făcut click și specificăm să primim datele înapoi în format <code>json</code></li>
	<li>Actualizăm nota curentă (lățimea span-ului) și afișam noua notă (dacă s-a modificat)</li>
	<li>Dacă nu vrei să afișezi niciun mesaj, te poți opri aici, <strong>ai terminat</strong> :) </li>
	<li>Pentru a afișa un mesaj, cea mai la îndemână soluție (de care poți fi sigur că nu-ți strică layout-ul) este de a insera un mic tooltip la sfârșitul documentului și a-l poziționa absolut. Prin urmare, îl construim, îl umplem (cu text, desigur), îl injectăm și îl ascundem (și ștergem) după X secunde. În cazul de față două</li>
</ul>

<h5>document.createEle... ce?</h5>
Folosind jQuery ai trei posibilități de a include elemente în DOM:
<ol>
	<li>$('&lt;a&gt;&lt;/a&gt;').appendTo(element)</li>
	<li>$('&lt;a/&gt;').appendTo(element)</li>
	<li>$(document.createElement('a')).appendTo(element)</li>
</ol>
Chiar dacă cea de-a treia variantă pare mai lungă, este un pic mai rapidă. Am listat metodele în funcție de viteză, prima fiind cea mai înceată.

Deoarece injectăm cod <code>html</code> nou, trebuie să-l stilizăm cu puțin CSS suplimentar (ce nu cred că are nevoie de explicații suplimentare):


Răspunsul de la server (care am zis la început că este json) :

({
	raspuns : 'Mulțumim pentru vot',
	votNou	:	'50' // în procente
})

Atenție! Nu uita să faci escape la ghilimelele din text (dacă folosești).

Cam asta e tot. Š¢i-am arătat cum poți face un simplu sistem de vot cu câteva linii (și jQuery, desigur), fără să încarci inutil codul HTML. Dezavantajul MAJOR al acestei metode este că, în cazul în care nu se încarcă vreun fișier javascript, votul NU va funcționa. Soluția? Pui codul (da, cel pe care îl injectăm) direct în html :)

3 Comentarii to “Sistem simplu de votare (rating)”

  1. Niceee, o sa incerc si eu niste jucarele. Multumesc.

  2. N-am sa mai comentez si la tutorialul asta pentru ca iar ma trezesc ca-mi sar ceilalti vizitatori in cap! :D
    E ok facut, dar functioneaza cam ca si celelalte tutoriale existente pe net.

    Eu l-as fi abordat altcumva, adica as fi pus in HTML un formular cu 5 inputuri de tip radio, care sa functioneze cand e JS dezactivat.
    Daca JS-ul era activ, atunci as fi ascuns inputurile, as fi modificat probabil label-urile (sau le-as fi inlocuit cu tag-uri <a /> sa multumesc si puritanii care navigheaza pe site-uri doar cu tastatura :P ) si as fi postat formularul cu AJAX, fara reincarcarea paginii.

Show trackbacks
  1. […] la sistemul de votare spuneam că avem un markup simplu, am cam mințit. Sunt deja două taguri, e stil inline, ce mai? E prea […]

Ți-a plăcut articolul? Lasă un comentariu!

You can insert code snippets using BBcode:
[js].[/js] [html].[/html] [php].[/php] [css].[/css]
You can also use some HTML tags:
<blockquote>.</blockquote> <code>.</code> <a href="">.</a> <strong>.</strong> <em>.</em>

windows apple dropbox facebook twitter