Een dynamische peiling maken met jQuery en PHP

Wanneer je een aantal handige functies combineert met PHP met de slimheid van jQuery, kun je een aantal behoorlijk coole resultaten produceren. In deze tutorial maken we een peiling met PHP en XHTML, maken dan gebruik van sommige jQuery Ajax-effecten om de noodzaak voor een paginavernieuwing te elimineren, en om het een leuk beetje animatie te geven.

  1. HTML
  2. PHP
    1. Invoering
    2. poll_default ()
    3. poll_submit ()
    4. poll_return_results ()
    5. poll_ajax ()
  3. CSS
  4. Javascript
    1. Invoering
    2. formProcess ()
    3. loadResults ()
    4. animateResults ()

HTML

Laten we onze halen opgericht:

   
  • style.css houdt de CSS-markup vast.
  • jquery.js is de base jQuery-bibliotheek.
  • jquery.cookie.js is een plug-in van Klaus Hartl om cookiemanipulatie toe te voegen aan jQuery.
  • poll.js zal het Javascript hebben dat de poll dynamisch maakt.

Vervolgens maken we een eenvoudig pollformulier:

poll

Kies uw favoriete Javascript-framework:








Dit formulier wordt nu door de PHP verwerkt en wanneer JavaScript wordt uitgevoerd, door jQuery. De PHP en Javascript zijn ontworpen om de optie-ID uit het waardetag te trekken. is gewoon een gecodeerde HTML-entiteit, en is een pijl: →.


PHP

Invoering

Als Javascript is uitgeschakeld, zal de PHP:

  1. Neem GET / POST-verzoeken van het formulier
  2. Een cookie instellen / controleren
  3. Zorg ervoor dat het verzoek afkomstig is van een uniek IP-adres
  4. Sla de stemming op in een platte DB
  5. Lever de resultaten in een HTML-bestand in

Als Javascript is ingeschakeld, zal de PHP:

  1. Neem GET / POST-verzoeken van het Javascript
  2. Zorg ervoor dat het verzoek afkomstig is van een uniek IP-adres
  3. Sla de stemming op in een platte DB
  4. Retourneer de resultaten als JSON

Voor de platte file DB gebruiken we een pakket geschreven door Luke Plant.

Ten eerste hebben we een array nodig met de namen en ID's van de poll-opties:

 

Het flatfile-pakket gebruikt nummers voor de kolom-ID's, dus laten we enkele constanten instellen om die naar namen te converteren:

define ('OPT_ID', 0); define ('OPT_TITLE', 1); define ('OPT_VOTES', 2);

Wanneer het formulier wordt ingediend, moet PHP weten in welk bestand de resultaten moeten worden ingevoegd en moeten worden geretourneerd, dus we stellen een andere constante in:

define ('HTML_FILE', 'index.html');

We moeten opnemen flatfile.php en initialiseer een databaseobject:

require_once (flatfile.php); $ db = nieuw Flatbestand ();

De platte bestanden zijn alleen tekstbestanden die zijn opgeslagen in de gegevensdirectory:

$ db-> datadir = 'data /'; define ('VOTE_DB', 'votes.txt'); define ('IP_DB', 'ips.txt');

Als we een verzoek krijgen met de poll-parameter, is dit de statische vorm, dus verwerken we deze. Als het verzoek een stemparameter bevat, is dit een verzoek van Ajax. Anders geven we alleen het HTML_FILE.

if ($ _GET ['poll'] || $ _POST ['poll']) poll_submit ();  else if ($ _GET ['vote'] || $ _POST ['vote']) poll_ajax ();  else poll_default (); 

poll_default ()

functie poll_default () global $ db; $ ip_result = $ db-> selectUnique (IP_DB, 0, $ _SERVER ['REMOTE_ADDR']); if (! isset ($ _ COOKIE ['vote_id']) && empty ($ ip_result)) print file_get_contents (HTML_FILE);  else poll_return_results ($ _ COOKIE ['vote_id']); 

poll_default () verwerkt aanvragen rechtstreeks in het script zonder geldige GET / POST-aanvragen.

De globaal lijn maakt het $ db object beschikbaar in het bereik van de functie.

Het script traceert unieke IP's om ervoor te zorgen dat u maar één keer kunt stemmen, dus we doen een vraag om te controleren of het in de database zit:

$ ip_result = $ db-> selectUnique (IP_DB, 0, $ _SERVER ['REMOTE_ADDR']);

Als we geen cookie hebben en de IP-vraag leeg verschijnt, heeft de klant nog niet gestemd, dus we kunnen gewoon het HTML-bestand verzenden dat het formulier bevat. Anders sturen we alleen de resultaten:

if (! isset ($ _ COOKIE ['vote_id']) && empty ($ ip_result)) print file_get_contents (HTML_FILE);  else poll_return_results ($ _ COOKIE ['vote_id']); 

poll_submit ()

function poll_submit () global $ db; globale $ opties; $ id = $ _GET ['poll'] || $ _POST [ 'poll']; $ id = str_replace ("opt", ", $ id); $ ip_result = $ db-> selectUnique (IP_DB, 0, $ _SERVER ['REMOTE_ADDR']); if (! isset ($ _ COOKIE ['vote_id']) && empty ($ ip_result)) $ row = $ db-> selectUnique (VOTE_DB, OPT_ID, $ id); if (! empty ($ row)) $ ip [0] = $ _SERVER ['REMOTE_ADDR']; $ db-> insert (IP_DB, $ ip); setcookie ("vote_id", $ id, time () + 31556926); $ new_votes = $ row [OPT_VOTES] +1; $ db-> updateSetWhere (VOTE_DB, array (OPT_VOTES = > $ new_votes), nieuwe SimpleWhereClause (OPT_ID, '=', $ id)); poll_return_results ($ id); else if ($ options [$ id]) $ ip [0] = $ _SERVER ['REMOTE_ADDR'] ; $ db-> insert (IP_DB, $ ip); setcookie ("vote_id", $ id, time () + 31556926); $ new_row [OPT_ID] = $ id; $ new_row [OPT_TITLE] = $ opties [$ id] ; $ new_row [OPT_VOTES] = 1; $ db-> insert (VOTE_DB, $ new_row); poll_return_results ($ id); else poll_return_results ($ id);

poll_submit () neemt de formulierinzending aan, controleert of de klant al heeft gestemd en werkt de database vervolgens bij met de stemming.

Deze regels krijgen de ID van de geselecteerde optie en worden ingesteld $ id ernaar toe:

$ id = $ _GET ['poll'] || $ _POST [ 'poll']; $ id = str_replace ("opt", ", $ id);

We moeten controleren of de optie al in de DB zit:

$ row = $ db-> selectUnique (VOTE_DB, OPT_ID, $ id);

Als dit in de DB staat (resultaat niet leeg), moeten we een updateSetWhere (). Als dat niet het geval is, moeten we een voegen ():

if (! empty ($ row)) $ new_votes = $ row [OPT_VOTES] +1; $ db-> updateSetWhere (VOTE_DB, array (OPT_VOTES => $ new_votes), nieuwe SimpleWhereClause (OPT_ID, '=', $ id)); poll_return_results ($ id);  else if ($ options [$ id]) $ new_row [OPT_ID] = $ id; $ new_row [OPT_TITLE] = $ opties [$ id]; $ new_row [OPT_VOTES] = 1; $ db-> insert (VOTE_DB, $ new_row); poll_return_results ($ id); 

Hoe dan ook, we moeten het IP in de database plaatsen en een cookie instellen (verloopt over één jaar):

$ ip [0] = $ _SERVER ['REMOTE_ADDR']; $ db-> insert (IP_DB, $ ip); setcookie ("vote_id", $ id, time () + 31556926);

poll_return_results ()

functie poll_return_results ($ id = NULL) global $ db; $ html = file_get_contents (HTML_FILE); $ results_html = "

Resultaten enquêteren

\ n
\ n "; $ rijen = $ db-> selectWaar (VOTE_DB, nieuwe SimpleWhereClause (OPT_ID,"! = ", 0), -1, nieuwe OrderBy (OPT_VOTES, DESCENDING, INTEGER_COMPARISON)) foreach ($ rijen als $ rij) $ total_votes = $ rij [OPT_VOTES] + $ total_votes; foreach ($ rijen als $ rij) $ percent = round (($ rij [OPT_VOTES] / $ total_votes) * 100); if (! $ rij [OPT_ID] == $ id) $ results_html. = "
". $ rij [OPT_TITLE]."
$ Procent%\ n "; else $ results_html. ="
". $ rij [OPT_TITLE]."
$ Procent%\ n "; $ results_html. ="

Totaal aantal stemmen: ". $ Total_votes."

\ n "; $ results_regex = '/
(. *?)<\/div>/ S; $ return_html = preg_replace ($ results_regex, $ results_html, $ html); print $ return_html;

poll_return_results () genereert de resultaten van de peiling, neemt het HTML-bestand aan, vervangt het formulier door de resultaten en retourneert het bestand naar de client.

Laten we eerst het HTML-bestand pakken en instellen $ html ernaar toe:

$ html = file_get_contents (HTML_FILE);

Vervolgens starten we de HTML-structuur met resultaten:

$ results_html = "

Resultaten enquêteren

\ n
\ N ";

Om de resultaten-HTML te maken, moeten we alle rijen (opties) uit de DB sorteren op aantal stemmen:

$ rows = $ db-> selectWaar (VOTE_DB, nieuwe SimpleWhereClause (OPT_ID, "! =", 0), -1, nieuwe OrderBy (OPT_VOTES, DESCENDING, INTEGER_COMPARISON));

We hebben ook de totale stemmen nodig om de percentages te berekenen:

foreach ($ rijen als $ rij) $ total_votes = $ rij [OPT_VOTES] + $ total_votes; 

Vervolgens berekenen we het percentage stemmen dat de huidige optie heeft:

foreach ($ rijen als $ rij) $ procent = round (($ rij [OPT_VOTES] / $ total_votes) * 100);

De HTML voor de resultaten zal een definitielijst zijn (

) gestileerd met CSS om staafdiagrammen te maken:

$ results_html. = "
". $ rij [OPT_TITLE]."
$ Procent%\ N ";

We moeten ook controleren of de huidige optie degene is waarvoor de klant heeft gestemd en de kleur wijzigen:

if (! $ row [OPT_ID] == $ id)  ​​else $ results_html. = "
". $ rij [OPT_TITLE]."
$ Procent%\ n ";

Hier voegen we een totaal aantal stemmen toe en sluiten we de html-tags af:

$ results_html. = "

Totaal aantal stemmen: ". $ Total_votes."

\ N ";

Dit is een regex die de poll-container

:

$ results_regex = '/
(. *?)<\/div>/ S;

De laatste stap in deze functie is het poll-formulier vervangen door de resultaten met behulp van de regex en het resultaat retourneren:

$ return_html = preg_replace ($ results_regex, $ results_html, $ html); print $ return_html;

poll_ajax ()

function poll_ajax () global $ db; globale $ opties; $ id = $ _GET ['vote'] || $ _POST [ 'stem']; $ ip_result = $ db-> selectUnique (IP_DB, 0, $ _SERVER ['REMOTE_ADDR']); if (empty ($ ip_result)) $ ip [0] = $ _SERVER ['REMOTE_ADDR']; $ db-> insert (IP_DB, $ ip); if ($ id! = 'none') $ row = $ db-> selectUnique (VOTE_DB, OPT_ID, $ id); if (! empty ($ row)) $ new_votes = $ row [OPT_VOTES] +1; $ db-> updateSetWhere (VOTE_DB, array (OPT_VOTES => $ new_votes), nieuwe SimpleWhereClause (OPT_ID, '=', $ id));  else if ($ options [$ id]) $ new_row [OPT_ID] = $ id; $ new_row [OPT_TITLE] = $ opties [$ id]; $ new_row [OPT_VOTES] = 1; $ db-> insert (VOTE_DB, $ new_row);  $ rows = $ db-> selectWaar (VOTE_DB, nieuwe SimpleWhereClause (OPT_ID, "! =", 0), -1, nieuwe OrderBy (OPT_VOTES, DESCENDING, INTEGER_COMPARISON)); print json_encode ($ rijen); 

poll_ajax () neemt een verzoek van Javascript aan, voegt de stem toe aan de database en retourneert de resultaten als JSON.

Er zijn een paar coderegels die verschillen van poll_submit (). De eerste controleert of Javascript alleen de resultaten wil en er mag geen stem worden geteld:

if ($ id! = 'none')

De andere twee regels selecteren de hele database en retourneren deze als JSON:

$ rows = $ db-> selectWaar (VOTE_DB, nieuwe SimpleWhereClause (OPT_ID, "! =", 0), -1, nieuwe OrderBy (OPT_VOTES, DESCENDING, INTEGER_COMPARISON)); print json_encode ($ rijen);

CSS

.grafiek width: 250px; positie: relatief; rechts: 30px;  .bar-titel positie: relatief; zweven: links; breedte: 104 px; regelhoogte: 20px; margin-right: 17px; lettertype: vet; text-align: right;  .bar-container positie: relatief; zweven: links; breedte: 110 px; hoogte: 10 px; marge: 0px 0px 15px;  .bar-container div background-colour: # cc4400; hoogte: 20 px;  .bar-container sterk positie: absoluut; rechts: -32px; top: 0px; overloop verborgen;  # poll-resultaten p text-align: center; 

Deze CSS stijlen de resultaten geretourneerd door de PHP of Javascript.


Javascript

Invoering

De JavaScript-code onderschept de knop Verzenden, stuurt de stem met Ajax en animeert de resultaten.

Eerst enkele globale variabelen. Je zou de eerste drie van de PHP moeten herkennen. votedID slaat de ID op van de optie waarvoor de klant heeft gestemd.

var OPT_ID = 0; var OPT_TITLE = 1; var OPT_VOTES = 2; var gestemdID;

Nu hebben we een jQuery-ready-functie nodig die wordt uitgevoerd wanneer de pagina wordt geladen:

$ (Document) .ready (function () 

Binnen die functie registreren we de handler voor de stemknop die zal worden uitgevoerd formProcess wanneer het wordt geactiveerd:

. $ ( "# Poll") in te dienen (formProcess);

We moeten ook controleren of de resultaten

bestaat en animeert de resultaten als dit het geval is:

if ($ ("# poll-resultaten"). length> 0) animateResults (); 

Als we een cookie hebben, moeten we direct naar de resultaten springen omdat de gebruiker al heeft gestemd. Om dat te doen moeten we het poll-formulier verwijderen, de id uit de cookie halen, de resultaten van de PHP halen en doorgeven aan loadResults ().

if ($ .cookie ('vote_id')) $ ("# poll-container"). empty (); voteID = $ .cookie ('vote_id'); $ .GetJSON ( "poll.php stemming = none?", LoadResults); 

formProcess ()

function formProcess (event) event.preventDefault (); var id = $ ("input [@ name = 'poll']: checked"). attr ("value"); id = id.replace ("opt", "); $ (" # poll-container "). fadeOut (" slow ", function () $ (this) .empty (); votedID = id; $ .getJSON ( "poll.php? vote =" + id, loadResults); $ .cookie ('vote_id', id, expires: 365););

formProcess () wordt aangeroepen door de gebeurtenis submit die een gebeurtenisobject doorgeeft. Het voorkomt dat het formulier een normale inzending doet, controleert / stelt de cookies in, voert in plaats daarvan een Ajax-submit uit en belt vervolgens loadResults () om de resultaten naar HTML te converteren.

Ten eerste moeten we de standaardactie voorkomen (het formulier verzenden):

event.preventDefault ();

Vervolgens krijgen we de ID van de momenteel geselecteerde optie:

var id = $ ("input [@ name = 'poll']: checked"). attr ("value"); id = id.replace ("opt", ");

input [@ te pollen name =]: aangevinkt is een jQuery-selector die een a selecteert met een attribuut van naam = 'poll' dat is gecontroleerd. attr ( "value") krijgt de waarde van het object dat in ons geval is opterenn waar n is de ID van de optie.

Nu we het ID hebben, kunnen we het verwerken. Om te beginnen vervagen we het pollformulier en stellen we een anonieme functie in als een callback die wordt uitgevoerd wanneer de fade is voltooid. Animaties pauzeren het script niet, dus er gebeuren rare dingen als je het niet op deze manier doet.

$ ( "# Poll-container"). Fade-out ( "langzaam", function () 

Nadat het is vervaagd, kunnen we het formulier uit de DOM verwijderen leeg():

$ (This) .empty ();

In dit geval, $ (This) is jQuery-afkorting voor het DOM-element waarop de vervaging is toegepast.

jQuery heeft een aantal andere snelkoppelingsfuncties, waaronder $ .GetJSON () die een GET-aanvraag voor een JSON-object doet. Als we het object hebben, bellen we loadResults () ermee:

$ .GetJSON ( "? Poll.php stemmen =" + id, loadResults);

Het laatste wat je moet doen is de cookie instellen:

$ .cookie ('vote_id', id, expires: 365);

loadResults ()

functie loadResults (gegevens) var total_votes = 0; var procent; for (id in data) total_votes = total_votes + parseInt (data [id] [OPT_VOTES]);  var results_html = "

Resultaten enquêteren

\ n
\ n "; for (id in data) percent = Math.round ((parseInt (data [id] [OPT_VOTES]) / parseInt (total_votes)) * 100); if (data [id] [OPT_ID]! == voteID) results_html = results_html + "
"+ Data [id] [OPT_TITLE] +"
"+ Procent +" %\ n "; else results_html = results_html +"
"+ Data [id] [OPT_TITLE] +"
"+ Procent +" %\ n "; results_html = results_html +"

Totaal aantal stemmen: "+ total_votes +"

\ n "; $ (" # poll-container "). add (results_html) .fadeIn (" slow ", function () animateResults (););

loadResults () wordt aangeroepen door $ .GetJSON () en wordt een JSON-object doorgegeven dat de resultaten-DB bevat. Het is ongeveer hetzelfde als zijn PHP-tegenhanger poll_return_results () met een paar uitzonderingen. Het eerste verschil is dat we de breedte op alle balken op 0% omdat we ze zullen animeren. Het andere verschil is dat we een jQuery gebruiken toevoegen () in plaats van regex om de resultaten te tonen. Nadat de resultaten vervagen, roept de functie animateResults ().

animateResults ()

functie animateResults () $ ("# poll-resultaten div"). each (function () var percentage = $ (this) .next (). text (); $ (this) .css (width: "0 % "). animeren (width: percentage, 'slow');); 

animateResults () itereert door elk van de balken en animeert het breedte eigendom op basis van het percentage.

elk() is een jQuery-functie die door elk element dat wordt geselecteerd, itereert:

$ ("# poll-resultaten div"). each (function () 

Eerst stellen we het percentage in op de tekst van het element naast de balk die de met het percentage.

var percentage = $ (this) .next (). text ();

Dan zorgen we ervoor dat de breedte is ingesteld op 0% en animeert het:

$ (this) .css (width: "0%"). animeren (width: percentage, 'slow');
Code