-
byjovany
Nuevo
|
12-10-2012, 05:32 (UTC) Título del mensaje: COMO poner votos |
|
|
Crear un sistema de votación basado en estrellas
Vamos a crear un sistema de votación basado en seleccionar el número de estrellas.
Uploaded with ImageShack.us
Lo primero será construir el HTML de la página. En nuestro ejemplo tendremos la posibilidad de hacer la votación de dos películas, por lo que tendremos que crear para cada una de ellas la estructura de estrellas para poder votar. También mostraremos el número de votos recibidos y la media de estos votos.
El código html quedará de la siguiente manera.
<div class='movie_choice'>
Rate: Raiders of the Lost Ark
<div id="r1" class="rate_widget">
<div class="star_1 ratings_stars"></div>
<div class="star_2 ratings_stars"></div>
<div class="star_3 ratings_stars"></div>
<div class="star_4 ratings_stars"></div>
<div class="star_5 ratings_stars"></div>
<div class="total_votes">vote data</div>
</div>
</div>
<div class='movie_choice'>
Rate: The Hunt for Red October
<div id="r2" class="rate_widget">
<div class="star_1 ratings_stars"></div>
<div class="star_2 ratings_stars"></div>
<div class="star_3 ratings_stars"></div>
<div class="star_4 ratings_stars"></div>
<div class="star_5 ratings_stars"></div>
<div class="total_votes">vote data</div>
</div>
</div>
En el código html no se incluyen las imágenes, ya que estas se añadirán desde la hoja de estilos, como veremos en el código de abajo.
.rate_widget {
border: 1px solid #CCC;
overflow: visible;
padding: 10px;
position: relative;
width: 180px;
height: 32px;
}
.ratings_stars {
background: url('star_empty.png') no-repeat;
float: left;
height: 28px;
padding: 2px;
width: 32px;
}
.ratings_vote {
background: url('star_full.png') no-repeat;
}
.ratings_over {
background: url('star_highlight.png') no-repeat;
}
Esta primera parte del CSS hace varias cosas:
Pone por defecto la estrella vacía a cada localización de las estrellas.
Establece las clase de estrellas rellenas y de las estrellas doradas.
Define el estilo para el contenedor de las estrellas.
A continuación añadimos los estilos correspondientes a la zona de votos totales.
.total_votes {
background: #eaeaea;
top: 58px;
left: 0;
padding: 5px;
position: absolute;
}
.movie_choice {
font: 10px verdana, sans-serif;
margin: 0 auto 40px auto;
width: 180px;
}
Con el código que hemos utilizado hasta ahora, hemos conseguido crear la estructura de las votaciones, pero nos aparecerán las estrellas vacias.
Uploaded with ImageShack.us
Ahora vamos a añadir la interactividad a nuestro sistema de votación.
Lo primero que haremos será añadir los manejadores para las acciones mouseover y mouseout. Cuando el ratón pase por encima de las estrellas, se deben de poner las doradas. Para esto ya vamos a utiliza jQuery.
$('.ratings_stars').hover(
// Handles the mouseover
function() {
$(this).prevAll().andSelf().addClass('ratings_over');
$(this).nextAll().removeClass('ratings_vote');
},
// Handles the mouseout
function() {
$(this).prevAll().andSelf().removeClass('ratings_over');
set_votes($(this).parent());
}
);
Hemos utilizado los métodos “preAll()” y “nextAll()” de jQuery para seleccionar las estrellas que nos hemos dejado atrás y adelante de la posición del ratón para darle el estilo correspondiente a cada una de ellas. Las que se quedan atrás deberán de estar con la estrella dorada, mientras que las de delante, no deben de tener nada en el fondo.
Lo siguiente que hacemos es recuperar los datos del servidor. Cuando se ha realizado la votación o se entra en la página, en la zona de las estrellas deben de aparecer las estrellas que indican la media de votos, que tiene un color al resto. Para ello debemos de obtener los datos del servidor.
$('.rate_widget').each(function(i) {
var widget = this;
var out_data = {
widget_id : $(widget).attr('id'),
fetch: 1
};
$.post(
'ratings.php',
out_data,
function(INFO) {
$(widget).data( 'fsr', INFO );
set_votes(widget);
},
'json'
);
});
Con el código de arriba, obtenemos los datos correspondientes a las votaciones que tenemos almacenadas en el servidor.
Lo primero que hacemos es crear el objeto “out_data” que contiene la información que nosotros queremos enviar al servidor. También incluye el id, para identificar los datos que queremos recuperar. Cuando nuestra función php devuelve los datos, tendremos algo parecido a esto:
{
"widget_id" : "r1",
"number_votes" : 129,
"total_points" : 344,
"dec_avg" : 2.7,
"whole_avg" : 3
}
El método “data()” de jQuery, permite asociar datos con objetos del DOM.
$('#one_of_your_widgets).data('fsr').widget_id;
Después de que los datos hayan sido devueltos desde el servidor, estos pasan al método set_votes().
function set_votes(widget) {
var avg = $(widget).data('fsr').whole_avg;
var votes = $(widget).data('fsr').number_votes;
var exact = $(widget).data('fsr').dec_avg;
$(widget).find('.star_' + avg).prevAll().andSelf().addClass('ratings_vote');
$(widget).find('.star_' + avg).nextAll().removeClass('ratings_vote');
$(widget).find('.total_votes').text( votes + ' votes recorded (' + exact + ' rating)' );
}
Las primeras líneas de la función, son para obtener los datos, y almacenarlas en variables para su mejor manejo.
En la línea 7, avg representa un número entero, representando el redondeo de las votaciones. Con este número sabremos el número de estrellas que hay que marcar y que representan a la media de votos recibidos. Se utiliza el método “andSelf()”, para indicar también la estrella que hemos seleccionado.
La línea 8 es similar a la anterior, pero marcando como vacías las últimas estrellas.
En la línea 9 lo que hacemos es actualizar el número total de votos que ha recibido y la media de todos los votos.
Ya que tenemos programado el código para recibir los datos del servidor, vamos a realizar ahora el código correspondiente a las votaciones de los usuarios.
Para ello hay que controlar el manejador cuando se haga click en la estrella que se ha seleccionado.
$('.ratings_stars').bind('click', function() {
var star = this;
var widget = $(this).parent();
var clicked_data = {
clicked_on : $(star).attr('class'),
widget_id : widget.attr('id')
};
$.post(
'ratings.php',
clicked_data,
function(INFO) {
widget.data( 'fsr', INFO );
set_votes(widget);
},
'json'
);
});
En primer lugar, hemos creado nuestros datos de salida, que ponemos en el clicked_data objeto. Nos aferramos a la clase que incluye un nombre de clase en el formato de star_ # nos dice lo que la votación se está dando, y que se preparan para enviar al servidor, junto con la identificación del widget.
Al final se envía los datos al servidor para que se queden almacenados.
Para finalizar, vamos a crear la clase que almacena los datos en el servidor para luego poder consultarlos.
Vamos a crear una clase en PHP llamada “Ratings” que será la encargada de hacer estas operaciones. Veamos un pequeño ejemplo de como la utilizaremos:
# New Object
$rating = new ratings($_POST['widget_id']);
# either return ratings, or process a vote
isset($_POST['fetch']) ? $rating->get_ratings() : $rating->vote();
Empecemos a construir la clase.
class ratings {
private $data_file = './ratings.data.txt';
private $widget_id;
private $data = array();
function __construct($wid) {
$this->widget_id = $wid;
$all = file_get_contents($this->data_file);
if($all) {
$this->data = unserialize($all);
}
}
En el código anterior nosotros le indicamos la ruta al fichero donde estarán almacenados los datos.
Al constructor se le pasa el id para poder obtener y actualizar los datos correspondientes a ese id que le hemos indicado.
En la línea 11 cargamos todos los datos del fichero. En la línea 14, al contenido le aplicamos la función unserializable(), para pasar los datos a un array y poder así trabajar de una forma más sencilla con ellos.
Veamos ahora el método get_ratings(). Este método nos devolverá los datos correspondientes a un id de un elemento. Los datos serán devueltos en formato JSON.
public function get_ratings() {
if($this->data[$this->widget_id]) {
echo json_encode($this->data[$this->widget_id]);
}
else {
$data['widget_id'] = $this->widget_id;
$data['number_votes'] = 0;
$data['total_points'] = 0;
$data['dec_avg'] = 0;
$data['whole_avg'] = 0;
echo json_encode($data);
}
}
Lo que hacemos en el código anterior es comprobar si en el array de datas obtenidos en el constructor están los datos correspondientes al id que le pasamos. Si es así, se devuelven esos datos. Si no se encuentran, entonces es la primera vez que se vota y se inicializa los datos de ese elemento, que serán los que se devuelvan.
El método vote(). Tenemos que crear un método para controlar los votos entrantes. Al finalizar el método, se tiene que llamar get_ratings () para enviar la información actualizada en el navegador web. Vamos a ver este método dividido en secciones.
Lo primero que hacemos es recuperar el valor del voto que se ha enviado.
public function vote() {
# Get the value of the vote
preg_match('/star_([1-5]{1})/', $_POST['clicked_on'], $match);
$vote = $match[1];
A continuación veremos el código correspondiente a aumentar las votaciones. Lo que hace es comprobar con el id del elemento si está en el array de datos. Si es así, se aumenta en uno el número de votos y se suma las estrellas seleccionadas. Si no existe, entonces se crea de nuevo inicializandolo con los valores que se han votado.
$ID = $this->widget_id;
# Update the record if it exists
if($this->data[$ID]) {
$this->data[$ID]['number_votes'] += 1;
$this->data[$ID]['total_points'] += $vote;
}
# Create a new one if it does not
else {
$this->data[$ID]['number_votes'] = 1;
$this->data[$ID]['total_points'] = $vote;
}
Por último, solo falta almacenar los datos en el fichero, calculando antes la media de votos que se lleva para ese elemento. Al final de todo, se llama a la función “get_rating()”, para que se muestren las votaciones actualizadas.
$this->data[$ID]['dec_avg'] = round( $this->data[$ID]['total_points'] / $this->data[$ID]['number_votes'], 1 );
$this->data[$ID]['whole_avg'] = round( $this->data[$ID]['dec_avg'] );
file_put_contents($this->data_file, serialize($this->data));
$this->get_ratings();
}
Al igual que hemos utilizado un fichero para los datos, se podría haber realizado con bases de datos.______________ Apoyo ala jente a saber lo que yose sobre PWG y ala bes aprender sobre ellos para haci tener unas mejores webs:D |
|