Problema creazione sondaggio dinamico

fradamma

Utente Attivo
28 Set 2012
93
0
0
Salve ragazzi.
Arrivo subito al dunque: per il mio sito dovrei creare un modulo che permetta all'utente di rispondere ad un sondaggio. Per esempio ho una domanda, ci sono tre risposte possibili e al click su "vota" di una delle tre possibili risposte una barra corrispondente deve aumentare percentualmente. Vi posto quello che sono riuscito a fare un po smanettando su internet e un po da solo:

Codice:
<div id="container">
    <span class="domanda">Qual è il tuo calciatore preferito?</span>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Baggio</div>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Ronaldo</div>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Messi</div>
</div>
<script>
$("#container div a").click(function() {
        $(this).parent().animate({
           width: '+=20px'
        }, 500);
 
        $(this).prev().html(parseInt($(this).prev().html()) + 1);
        return false;
});
</script>
css:

Codice:
#container {
        margin-top: 20px;
        color: #fff;
    }
    #container .domanda {
        display: block;
        padding: 20px;
        font-weight: bold;
        letter-spacing: -3px;
        margin-bottom: 20px;
        padding: 10px;
        font-size: 40px;
    }
    #container div {
        font-weight: bold;
        letter-spacing: -3px;
        background: #F90;
        margin-bottom: 15px;
        padding: 10px;
        font-size: 34px;
        color: #ffffff;
        border-left: 20px solid #333;
        width: 400px;
        -webkit-border-radius: 0 10px 10px 0;
        -moz-border-radius: 0 10px 10px 0;
        border-radius: 0 10px 10px 0;
    }
    #container div a {
        border-radius: 10px;
        text-decoration: none;
        color: #f90;
        padding: 5px 15px;
        background: #333;
        margin: 0 20px;
    }
    #container div a:hover {
        color: #fff;
    }
Ora non essendo una cima in queste cose ho due problemi:
1) rendere la cosa in maniera di percentuale (%) e non aumentando di una unità la barra al click;
2) salvare i valori immessi e inviarli ad un database.

come posso fare? grazie a tutti e buona giornata!
 

flameseeker

Utente Attivo
27 Nov 2013
699
0
0
Ciao, ti manca tutta la progettazione lato server.
Dovresti prima di tutto definire le tabelle necessarie nel database (se non ti occorre una forte logica relazionale si può gestire il tutto anche con un paio di tabelle), successivamente i dati che archivi ti andranno a definire il topic del sondaggio e i valori che è possibile votare.

Quando apri la pagina, grazie a PHP vai a generare le varie opzioni per il sondaggio e una preview dell'andamento fino ad ora (le famose barre percentuale).

Nel momento in cui voti un opzione spedisci una richiesta a PHP che incrementa il numero di voti nel database.


Grossomodo, la logica è questa.
 

fradamma

Utente Attivo
28 Set 2012
93
0
0
Grazie tante per la risposta :)
Diciamo che però io non mi devo occupare del "lato server"....mi interessa solamente sapere come implementare l effetto jquery/javascript che mi fa accrescere una barra e decrescere un altra percentualmente al submit su "vota". Inoltre vorrei sapere come, avendo un <form method="post" action="..."> con dei campi <input type="hidden"... /> al suo interno, inviare i dati....
 

flameseeker

Utente Attivo
27 Nov 2013
699
0
0
Ti ho scritto al volo un mini plugin jquery per gestire la questione, salvalo in un file tipo poll.js e poi includilo nella pagina
Codice:
(function($) {
    var settings = {
        ratings: 0,
        optRatings: {},
        maxBarWidth: null,
        callback: null
    };
    
    $.fn.extend({
        
        poll: function(s) {
            settings = $.extend(settings, s);
            
            if (settings.maxBarWidth == null)
                settings.maxBarWidth = $(this).find("div").width();
            
            return this.each(function() {
                $(this).poll_click_event();
            });
        },
        
        poll_click_event: function() {
            var Poll = $(this);
            
            $(this).find("div a").click(function(e) {
                e.preventDefault();
                var span = $(this).parent().find("span");
                
                settings.ratings += 1;
                $(span).html(parseInt($(span).html())+1);
                
                var toVote = $(this)
                    .parent()
                    .poll_utils_getOnlyText();
                
                if (typeof settings.optRatings[toVote] == 'undefined')
                    settings.optRatings[toVote] = 1;
                else
                    settings.optRatings[toVote] += 1;
                
                $(Poll).poll_bar_adjust();
                $(Poll).poll_make_hiddenInput();
                
                if (settings.callback != null)
                    settings.callback(settings.optRatings);
            });
        },
        
        poll_utils_getOnlyText: function() {
            return $(this)
                .clone()
                .children()
                .remove()
                .end()
                .text();
        },
        
        poll_bar_adjust: function() {
            var bars = $(this).find("div");

            for (var i = 0; i < bars.length; ++i) {
                var thisVote = $(bars[i]).poll_utils_getOnlyText();
                if (typeof settings.optRatings[thisVote] !== 'undefined') {
                    var rating = settings.optRatings[thisVote]/settings.ratings;
                }else {
                    var rating = 0;
                }                
                
                $(bars[i]).animate({
                   width: parseInt(settings.maxBarWidth*rating) + 'px'
                }, 500);
            }
        },
        
        poll_make_hiddenInput: function() {
            var bars = $(this).find("div");
            
            for (var i = 0; i < bars.length; ++i) {
                if ($('#votes_'+i).length > 0) {
                    $('#votes_'+i).val($(bars[i]).find("span").text());
                }else {
                    $('<input>').attr({
                        type: 'hidden',
                        id: 'votes_'+i,
                        name: 'votes['+i+']',
                        rel: 'poll_votes',
                        value: $(bars[i]).find("span").text()
                    }).appendTo(this);
                }
            }
        }
    
    });
    
})(jQuery);

Il codice lo puoi usare in questa maniera:
HTML:
<form id="poll1">
    <div id="container">
        <span class="domanda">Qual è il tuo calciatore preferito?</span>
        <div><span>0</span><a href="javascript:void(0)">Vota</a>Baggio</div>
        <div><span>0</span><a href="javascript:void(0)">Vota</a>Ronaldo</div>
        <div><span>0</span><a href="javascript:void(0)">Vota</a>Messi</div>
    </div>
</form>
<script>
$(document).ready(function() {

    $('#container').poll();

});
</script>
A questo punto le barre dovrebbero funzionare in percentuale come volevi tu.
Occhio che le barre variano tra 0px e la dimensione massima che assegni ai div da css.

Per mandare i dati al server ho messo la possibilità di definire una callback che viene richiamata ogni qual volta clicchi su di un "Vota", ti basta modificare l'istruzione $('#container').poll(); in questa maniera:
Codice:
    $('#container').poll({
        callback: function() {
            $.post('salvadati.php', $('#poll1').serialize())
                .done(function() {
                    // successo! i dati sono stati spediti al server..
                });
        }
    });
. salvadati.php dovrebbe essere la tua pagina, lato server, che si occupa di prelevare i dati ed eseguire tutte quelle operazioni di cui hai detto che non ti devi occupare.

. $('#poll1').serialize() è importante, perchè serve a raccogliere i valori degli input hidden che il plugin crea automaticamente dentro il div container (considera che se al tuo form dai un id diverso devi aggiornarlo ovviamente al posto di poll1 anche qui).

. Il name che viene assegnato agli input hidden invece è votes[], i dati vengono passati al server come array rispettando l'ordinamento con cui scrivi le varie opzioni di voto sull'html.


Fammi sapere se, fin qui, è quello che cercavi.
Ho messo un esempio funzionante su JSFiddle, così per avere un anteprima di funzionamento al volo ;)
 
Ultima modifica:

fradamma

Utente Attivo
28 Set 2012
93
0
0
Grazie!!! semplicemente grandioso! :D
Per quanto riguarda le percentuali tutto ok. Io però avrò come pagina di "arrivo" una action. Ora vorrei solo capire una cosa. Mettiamo il caso io abbia un form del genere, nel quale inserisco "a mano" gli input hidden:

Codice:
<form name="votazioneForm" id="vota" method="post" action="sondaggio.action">
			<ul>
				<li>
					<span class="risposta">Lorem ipsum ecc</span>
					<input type="submit" name="opzione1" value="1" />
					<span class="percentuale-risultato">100%</span>
				</li>
				<li>
					<span class="risposta">Lorem ipsum ecc</span>
					<input type="submit" name="opzione1" value="1" />
					<span class="percentuale-risultato">100%</span>
				</li>
				<li>
					<span class="risposta">Lorem ipsum ecc</span>
					<input type="submit" name="opzione1" value="1" />
					<span class="percentuale-risultato">100%</span>
				</li>
			</ul>
	                        <input type="hidden" name="tipologia1" value="1" id="tipologia1">
				<input type="hidden" name="tipologia2" value="1" id="tipologia2">
				<input type="hidden" name="tipologia3" value="1" id="tipologia3">	

</form>
Posso fare una cosa del genere oppure è sbagliata?

Codice:
$("#vota").submit( function() {
                  $.post('sondaggio.action', $(this).serialize() )
                       .done(function() {
                    // successo! i dati sono stati spediti al server..
                      });
               });
Tu faresti in modo differente, e in parole povere, a cosa serve il serialize()?
 

flameseeker

Utente Attivo
27 Nov 2013
699
0
0
A patto che rispetti la struttura html che hai postato ad inizio topic:
HTML:
<div id="container">
    <span class="domanda">Qual è il tuo calciatore preferito?</span>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Baggio</div>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Ronaldo</div>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Messi</div>
</div>
Puoi decidere di fare il submit del form anche in altri modi, quello da te esposto può esserne una variante.
Considera solo che se cambi uno qualsiasi dei tag html usati per creare visivamente il sondaggio và aggiornato il codice del plugin.

Gli input vengono generati automaticamente dallo script, ma ho lasciato molta libertà in proposito e puoi ridefinirli così
HTML:
<div id="container">
    <span class="domanda">Qual è il tuo calciatore preferito?</span>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Baggio</div>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Ronaldo</div>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Messi</div>
	<input id="votes_0" type="hidden" name="tipologia1" value="1" id="tipologia1">
	<input id="votes_1" type="hidden" name="tipologia2" value="1" id="tipologia2">
	<input id="votes_2" type="hidden" name="tipologia3" value="1" id="tipologia3">
</div>
Devono essere dentro il div container e devono avere obbligatoriamente come id "votes_[numero]", dove [numero] è un conteggio che parte da 0 e incrementa di 1 per ogni opzione e la posizione degli input identifica le tue scelte; nell'esempio che ti ho scritto votes_0 identifica Baggio, votes_1 Ronaldo e votes_2 Messi.
Per cui occhio che se sposti "Ronaldo" sotto messi, tipo così:
HTML:
<div id="container">
    <span class="domanda">Qual è il tuo calciatore preferito?</span>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Baggio</div>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Messi</div>
    <div><span>0</span><a href="javascript:void(0)">Vota</a>Ronaldo</div>
	<input id="votes_0" type="hidden" name="tipologia1" value="1" id="tipologia1">
	<input id="votes_1" type="hidden" name="tipologia2" value="1" id="tipologia2">
	<input id="votes_2" type="hidden" name="tipologia3" value="1" id="tipologia3">
</div>
votes_2 si riferirà a Ronaldo.

Tu faresti in modo differente, e in parole povere, a cosa serve il serialize()?
Il serialize prende tutti gli input e i valori del form indicato e li trasforma direttamente in una query string.
I tuoi input verrebbero serializzati così, per dirti:
Codice:
tipologia1=1&tipologia2=1&tipologia3=1
Questo formato serve a facilitare il passaggio dei dati al server che lo interpreta già per conto suo.


Per quanto riguarda il come farei, nella mia precedente risposta ti ho messo un esempio funzionante dove ad ogni click sul vota corrisponde un invio dati al server.
 

fradamma

Utente Attivo
28 Set 2012
93
0
0
Grazie mille flameseeker!
sei stato davvero illuminante! :) Ci lavoro su e vediamo che succede. Purtroppo (o per fortuna) interagisco con altre persone nel fare questa cosa e non posso decidere tutto per conto mio... vedo un po come va, altrimenti tornerò a darti fastidio! :D:D:D
grazie ancora!