Bygg et 5 Star Rating System Med jQuery, AJAX og PHP

I denne opplæringen lærer du hvordan du bygger et rating system med AJAX, PHP og jQuery. Stemmer blir registrert og oppdatert i sanntid med magien til AJAX, og vi vil også utnytte kraften til PHP, slik at du ikke engang trenger en database!


Trinn 1. Bygg HTML

Vi skal lage en enkel side som viser to filmer, og lar deg rangere dem. Dette betyr at vi trenger stjernene til å vise nåværende vurdering, og for å tillate avstemning. Vi vil også ha et område for å vise totalt antall stemmer, og nåværende vurdering ned til en desimal.

La oss ta en titt på HTML / CSS

 
Vurder: Raiders of the Lost Ark
stemme data
Rate: The Hunt for Red October
stemme data

Legg merke til hvordan det ikke er grafikk i denne HTML-en? De vil bli lagt til med CSS. Vi bruker bare HTML til å lage rammen som widgeten fungerer fra. Nå er det på tide å begynne å legge til CSS.

 .rate_widget border: 1px solid #CCC; overløp: synlig; polstring: 10px; stilling: relativ; bredde: 180px; høyde: 32px;  .ratings_stars bakgrunn: url ('star_empty.png') no-repeat; flyte: venstre; høyde: 28px; polstring: 2px; bredde: 32px;  .ratings_vote bakgrunn: url ('star_full.png') no-repeat;  .ratings_over bakgrunn: url ('star_highlight.png') no-repeat; 

Denne første delen av CSS oppnår noen få ting:

  • Gir standard 'tom' start til hver stjerneplassering
  • Setter opp klasser for fylt i stjerner og uthevede stjerner
  • Definerer og stiler stjernens container.

Du kan enten bruke grafikken som tilbys i nedlastingen, eller lage din egen. Det må være grafikk for hver av de tre statene: tom, full og uthevet.

Deretter legger vi til litt mer CSS for å plassere totalt antall stemmer, og senter widgetene slik at siden stemmer overens med grafikken i begynnelsen av denne delen.

 .total_votes background: #eaeaea; topp: 58px; venstre: 0; polstring: 5px; posisjon: absolutt;  .movie_choice font: 10px verdana, sans-serif; margin: 0 auto 40px auto; bredde: 180px; 

Trinn 2. Legge til grensesnittinteraktiviteten

På dette tidspunktet har vi en veldig vanlig utseende gjeng med tomme stjerner, men de gjør det ikke gjøre mye på dette punktet. Det er her hvor jQuery kommer til redning.

Vårt første skritt er å legge til mouseover og mouseout handlers for stjernene. Vi må markere stjernen musen er over, og alle de foregående stjernene.

 $ ('. ratings_stars'). hover (// Håndterer mouseover-funksjonen () $ (dette) .prevAll () .Self (). addClass ('ratings_over'); $ (dette) .nesteAll () 'ratings_vote');; // Håndterer mouseout-funksjonen () $ (dette) .prevAll () .Self (). removeClass ('ratings_over'); set_votes ($ (this) .parent ());) ;

Vi drar nytte av jQuery's kraftige .prevAll () og .nextAll () metoder for å få stjernene før og etter den nåværende moused over star.

Koden ovenfor legger til og fjerner klassene for å lage stjernene under musen og før 'uthevet', og stjernene etter 'ikke uthevet'.

Hva med set_votes () ?

Dette er en funksjon som kontrollerer hvilke stjerner som skal være i "full" tilstand, og knytter seg tett sammen med neste trinn, hvor vi tar fjerndata fra serveren.


Trinn 3. Henter data fra serveren

Våre stjerner markerer når du beveger musen over dem, og det er en god start. Men hva med de røde stjernene som viser nåværende stemme? For å nå dette trinnet må vi både få informasjonen fra serveren og skrive litt JavaScript for å håndtere dataene.

 $ ('. rate_widget'). hver (funksjon (i) var widget = dette; var out_data = widget_id: $ (widget) .attr ('id'), henting: 1; $ .post php ', out_data, funksjon (INFO) $ (widget) .data (' fsr ', INFO); set_votes (widget);;' json '););

Denne koden blokk - faktisk alle JavaScript - går i en document.ready blokk. Denne bestemte koden kjøres straks. Det spørre serveren og får litt informasjon om hver stemme-widget på siden.

Først oppretter vi et objekt, out_data, for å inneholde informasjonen vi sender til serveren. Vår PHP skript forventer å se "hente" når du bare tar data, så vi inkluderer den her. Vi inkluderer også IDen til widgeten, som lar server-side skriptet vite hvilke data vi er ute etter. Når tilbakeringingsfunksjonen brenner, inneholder den et JavaScript-objekt som ser slik ut:

 "widget_id": "r1", "number_votes": 129, "totalpoeng": 344, "dec_avg": 2,7, "whole_avg": 3

Metoden .data () er litt av jQuery magi som lar deg knytte vilkårlig data til en DOM
gjenstand.

Hvis du ser nøye på koden, ser du at vi tar det objektet (lagret i variabelen INFO) og
gjør noe med det via metoden .data ().

Metoden .data () er litt av jQuery magi som lar deg knytte vilkårlig data til en DOM
gjenstand. I dette tilfellet lagrer vi dataene i widget-diven. Det kan nås senere som dette:

 $ ( '# One_of_your_widgets) .data (' FSR ') WIDGET_ID.;

set_votes (), Finally.

Etter at dataene er returnert fra serveren, avgis den indirekte til set_votes ().

 funksjon set_votes (widget) var avg = $ (widget) .data ('fsr'). whole_avg; var stemmer = $ (widget) .data ('fsr'). number_votes; var eksakt = $ (widget) .data ('fsr'). dec_avg; $ (widget) .find ('. star_' + avg) .prevAll (). ogSelf (). addClass ('ratings_vote'); $ (widget) .find ('. star_' + avg) .nextAll (). removeClass ('ratings_vote'); $ (widget) .find ('. total_votes'). tekst (stemmer + 'stemmer innspilt (' + eksakt + 'vurdering)'); 

De tre første linjene er for lesbarhet, da de variable navnene er ganske lange. Så la oss ta en titt på hva som skjer her.

Linje 7: 'avg' er et helt tall, som representerer det avrundede stemme gjennomsnittet for denne widgeten. Fordi det er
et tall 1-5, kan vi bruke det til å finne den riktige stjernen i widgeten, og slå den, og
foregående til vår "fylte" grafikk. Legg merke til bruken av .andSelf () for å inkludere stjernen som
vi har valgt.

Linje 8: Dette er ganske lik linje 7, men vi fjerner den fylte grafikken fra senere stjerner. Dette
er nødvendig hvis gjennomsnittet for denne widgeten har gått ned siden siste stemme.

Linje 9: Her oppdaterer vi den grå boksen under widgeten, som viser en mer presis vurdering,
og lar en besøkende få vite hvor mange stemmer har blitt kastet.


Trinn 4. La stemmeangivelsen

Det siste trinnet for brukergrensesnittet er å muliggjøre avstemning. Vi skal legge til en klikkbehandler til hver av stjernene. Denne klikkbehandleren vil være ansvarlig for å sende stemmeinformasjonen til serveren.

Her er klikkbehandleren:

 $ ('. ratings_stars'). bind ('klikk', funksjon () var stjerne = dette; var-widget = $ (dette) .parent (); var clicked_data = klikked_on: $ (stjerne) .attr '), widget_id: widget.attr (' id '); $ post (' ratings.php ', clicked_data, funksjon (INFO) widget.data (' fsr ', INFO); set_votes (widget); 'json'););

I denne kodeblokken begynner vi ved å skape noen variabler, ikke bare for klarhet, men i dette tilfellet, slik at de kan brukes i .post-tilbakeringingen. Husk at klikkbehandleren er tildelt stjernene, så vi trenger også den andre variabelen, widget, for å få objektet som inneholder dataene.

Først oppretter vi våre utgående data, som vi plasserer i objektet clicked_data. Vi tar tak i klassen som inneholder et klassenavn i formatet star_ # forteller oss hvilken stemme som blir gitt, og forbereder seg på å sende det til serveren, sammen med widgetens ID.

Widget-IDen er hjørnestenen som dette stemmegivningssystemet bygger på. Det lar oss se opp våre lagrede data, og for å enkelt vise dataene til den besøkende.

Til slutt, på linjelinje, sender vi denne informasjonen til serveren. Serveren vil legge til stemme til dagens totals, og sende informasjon tilbake til nettleseren som inneholder de oppdaterte dataene. Verdiene som vises av widgeten oppdateres deretter med set_votes ().


Trinn 5. PHP: Opprette klassen

Nå når brukergrensesnittet er ferdig, må vi opprette et server side script for å lagre og hente stemmedata.

Vi skal lage en veldig enkel klasse i PHP, kalt "Ratings," og bruke den til å håndtere serverforespørsler for vårt klassesystem. Det kommer bare to metoder, pluss innkallingen. Bruken av vår klasse vil se slik ut:

 # Nytt objekt $ rating = nye karakterer ($ _ POST ['widget_id']); # enten returnere karakterer eller behandle en stemmeutgave ($ _ POST ['hent'])? $ rating-> get_ratings (): $ rating-> vote ();

Hvis du går tilbake til seksjonen fire, ser vi at vi laster opp dataene med variabelen 'hent' sett - det er det vi leter etter her på linje fem. Hvis det ikke er satt, behandler vi en stemme.

Det første vi skal se på er begynnelsen av klassen, og nærmere bestemt konstruktøren.

 klassevurdering private $ data_file = './ratings.data.txt'; privat $ widget_id; privat $ data = array (); funksjon __construct ($ wid) $ this-> widget_id = $ wid; $ all = file_get_contents ($ this-> data_file); hvis ($ alle) $ this-> data = unserialize ($ all); 

serialize () og unserialize er en fin måte å enkelt lagre
PHP datastrukturer på disk.

Det skjer mye her i svært få linjer, så jeg skal dekke de viktige biter.

Linje 3: Dette må settes til en tekstfil du vil bruke til å lagre dataene dine. Vi bruker ikke en database for dette prosjektet, selv om du enkelt kunne. En enkel fil vil være tilstrekkelig for våre behov.

Linje 7: Konstruktøren. Dette kalles når vi lager vårt objekt, og lagrer umiddelbart IDen til widgeten.

Linje 11: Vi prøver å laste inn tekstfilen. Hvis filen ikke eksisterer, bra, men på enkelte systemer må du opprette den på forhånd og gi den riktig tillatelse til PHP for å kunne lese og skrive til det.

Linje 14: Denne linjen er viktig. Det tar dataene fra tekstfilen - hvis det er en - og unserializes () det. Filen inneholder et komplekst PHP-array som er konvertert til en ren tekstrepresentasjon, via serialize (), slik at vi kan lagre den og lese den tilbake som en matrise senere.


Trinn 6. Get_ratings () Metoden.

Denne metoden kalles enten alene eller fra stemme () -metoden. Den finner dataene for en bestemt widget-ID og returnerer den til forespørselssiden, i JSON-format.

 offentlig funksjon get_ratings () if ($ this-> data [$ this-> widget_id]) echo json_encode ($ this-> data [$ this-> widget_id]);  ellers $ data ['widget_id'] = $ this-> widget_id; $ data ['number_votes'] = 0; $ data ['total_points'] = 0; $ data ['dec_avg'] = 0; $ data ['whole_avg'] = 0; ekko json_encode ($ data); 

Dette ser bare ut komplisert - det er faktisk ganske enkelt. Det første vi gjør er å se om arrayet som er lagret i $ this-> data har en nøkkel som samsvarer med widget-IDen vår. Hvis det gjør det, returnerer vi bare den informasjonen, fordi det er widgetdataene siden ble bedt om.

Vi trenger ikke å gjøre noe for at dataene, fordi det allerede er i matriseform. $ this-> data er bare en rekke arrays. Vi koder for arrayet vi vil ha med json_encode () og send det tilbake til nettleseren.

Hvis det ikke er data for widget-IDen vi har bedt om, lager vi en plate med alle nullverdier, og sender den tilbake til nettleseren.

Trinn 7. Stemmen () Metode

Deretter må vi lage en metode for å håndtere innkommende stemmer. Når metoden er ferdig, må den ringe get_ratings () for å sende oppdatert informasjon tilbake til nettleseren.

Metoden Start

 offentlig funksjonstemme () # Hent verdien av avstemningen preg_match ('/ star _ ([1-5] 1) /', $ _POST ['clicked_on'], $ match); $ vote = $ match [1];

Det første vi gjør er å få verdien av avstemningen. Husk at et sted i 'clicked_on' er et klassenavn i formatet star_ #. "star_4", for eksempel. For å få den verdien bruker vi et vanlig uttrykk og fanger verdien av nummeret til $ match [1].

Metoden Middle

 $ ID = $ this-> widget_id; # Oppdater posten hvis den eksisterer hvis ($ this-> data [$ ID]) $ this-> data [$ ID] ['number_votes'] + = 1; $ this-> data [$ ID] ['total_points'] + = $ vote;  # Opprett en ny hvis den ikke annet $ this-> data [$ ID] ['number_votes'] = 1; $ this-> data [$ ID] ['total_points'] = $ vote; 

Her lagrer vi $ this-> widget_id til $ ID for klarhet - den følgende koden blir litt grov på øynene uten den.

Vi kontrollerer om informasjon for denne IDen finnes, og i så fall legger vi til en stemme på totalt antall stemmer, og legger til poengene fra mottatt stemme. Dette er en løpende sum av alle stemmer; så hvis en person gir fem stjerner, og en annen, tre, det er åtte poeng totalt.

Hvis posten ikke eksisterer, oppretter vi en, med en stemme, og bare poengene fra innkommende stemme.

Etterbehandling

 $ this-> data [$ ID] ['dec_avg'] = runde ($ this-> data [$ ID] ['total_points'] / $ this-> data [$ ID] ['number_votes'], 1); $ this-> data [$ ID] ['whole_avg'] = runde ($ this-> data [$ ID] ['dec_avg']); file_put_contents ($ this-> data_file, serialize ($ this-> data)); $ Dette-> get_ratings (); 

Når vi har oppdatert avstemningen og poengtallene, må vi beregne både gjennomsnittet uttrykt som et helt tall og til ett desimalpunkt. For å unngå å gjøre matematikken to ganger, beregner vi først gjennomsnittet til ett desimaltall på linje ett og deretter rund det av til et helt tall på linje to.

På linje fire lagrer vi den endrede informasjonen tilbake på disken etter å ha behandlet den med serialize (). Når dataene er lagret trygt, kalder vi $ this-> get_ratings () for å sende den nye, oppdaterte informasjonen til nettleseren.


Konklusjon

For enkelhets skyld er dette ikke en 100% komplett løsning. For å utvide dette prosjektet, bør vi lagre en informasjonskapsel for å sikre at folk bare stemmer en gang, eller til og med registrerer IP-adressen. Det er også mulig at to førstestemmede par skje samtidig, og bare en kan bli registrert. Det er imidlertid en god start, og er mer enn egnet for å holde oversikt over stemmer på noen få håndfuller elementer på nettstedet ditt. Tanker? Takk for at du leste!

For øvrig, hvis du trenger ekstra hjelp, kan du prøve å kontakte en av PHP-tjenesteleverandørene på Envato Studio. Du kan få feilene løst, nye funksjoner lagt til, eller hele applikasjoner utviklet fra grunnen av!