Inicio AJAX Sistema de encuesta con AJAX

Sistema de encuesta con AJAX

19 6563

Veremos ahora un sistema de encuesta haciendo uso, como siempre de herramientas libres, de PHP + MySQL y AJAX. Las características de este sistema de encuesta son simples en realidad. Contendrá las siguientes partes: un administrador, para agregar una nueva encuesta o actulizarla; visualizador de opciones, la lista de alternativas con un boton de opción a su lado; visualizador de resultados, es decir las opciones con sus respectivos resultados; y el número de votantes.

Definamos la tabla y especificaremos, el porque de los campos y su tipo.

CREATE TABLE `encuesta` (
 `idenc` int(7) NOT NULL auto_increment,
 `pregunta` varchar(255) NOT NULL default '',
 `nrovotos` int(7) default '0',
 `opciones` text NOT NULL,
 `respuestas` text NOT NULL,
 KEY `id` (`idenc`)
 ) ENGINE=MyISAM;

Tenemos el campo idenc de tipo int autoincrement, es útil para identificar el registro de la encuesta; el campo pregunta tipo varchar, escribiremos allí la pregunta de la encuesta; nrovotos de tipo int, el numero de los votantes; opciones tipo text, las alternativas que puede elegir el votante; y finalmente el campo respuestas de tipo text también, almacena las respuestas a las alternativas seleccionadas.

Sobre los campos opciones y respuestas queremos aclarar un punto, vamos a trabajar de la siguiente manera: Las opciones que el usuario ingrese para su encuesta serán separadas por comas y se concatenarán para formar una sola expresión que se guardará en el campo opciones de tipo text. Lo mismo sucede para el campo respuestas, allí se guardará las cantidades de cada alternativa y luego se concatenarán para forma una sola expresión que se almacenará en el campo respuestas.

Pongamos un ejemplo, tenemos la siguiente encuesta:

¿Qué te parece el tutorial de Sistema de Encuesta?

  • Muy bueno
  • Bueno
  • Regular
  • Malo

Siguiendo el ejemplo, nuestro sistema de encuesta tiene que almacenar las alternativas: “Muy bueno, Bueno, Regular, Malo” en el campo opciones, y automaticamente tiene que crear las respuestas iniciales, en este caso: “1,1,1,1”, o sea una unidad por cada opción. De manera que cuando un usuario eliga una alternativa se sumará una unidad a cada opción elegida. Ej. Si el usuario elige “Muy bueno”, entonces las respuestas tienen que quedar así: “2,1,1,1”. Espero que de momento este algo claro, pero a medida que explicare el código se podrá entender mejor.

Entonces vamos al código

conexion.php >> Datos de la conexión a la base de datos.

<?php
   //Configuracion de la conexion a base de datos
   $bd_host = "localhost"; 
   $bd_usuario = "root"; 
   $bd_password = ""; 
   $bd_base = "wordpress"; 
   $con = mysql_connect($bd_host, $bd_usuario, $bd_password); 
   mysql_select_db($bd_base, $con); 
?>

admin.php >> Vamos a trabajar con un solo registro; es decir, creamos un encuesta y si deseamos cambiar la pregunta y las opciones simplemente actualizamos los datos. Desde está pagina podremos hacer esto, agregaremos una encuesta si no existe o actualizaremos la actual.

La página contiene un formulario con dos campos, uno para agregar la pregunta y otro para las opciones las cuales debemos separar por coma (,). El código PHP trabaja de la siguiente manera: capturamos las variables pregunta y opciones mediante el método POST, luego aplicamos explode a las opciones para separar los elementos por coma, así automaticamente creamos un array, luego contamos los elementos del array y mediante un while especificamos una cadena de texto de este tipo “1,1,1,1”. Luego verificamos si existe encuestas en la base de datos, dependiendo de si existe o no, actualizará o agregará una.

Nota: No creamos cadena de respuestas de este tipo “0,0,0,0,0”, porque cuando trabajamos con cero genera un error al pasar de texto a número y viceversa, así que cuando iniciamos una encuesta la hacemos con “1,1,1,1”. Por supuesto, la cantidad de unos dependerá de las opciones.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Mini-Administrador de encuesta</title>
</head>
<body>
<?php
  require('conexion.php');
  $continuar=false;
   
  if(isset($_POST['pregunta'])) $continuar=true;
  if(isset($_POST['opciones'])) $continuar=true;

  if($continuar==true){
    $pre=$_POST['pregunta'];
    $opc=$_POST['opciones'];
    $opciones = explode(",",$opc);
 
    //contamos cantidad de elementos
    //separados por coma
    $tot_elems=count($opciones);
 
    //iniciamos variables que usaremos
    $coma="";
    $i=0;
    $unidad="1";
    $respuesta="";
 
    //escribimos cadena del tipo "0,1,0,0,0"
    while($i<=$tot_elems-1){
       $respuesta=$respuesta.$coma.$unidad;
       $coma=",";
       $i++;
    } 
    //verificar si existe encuesta la actualizamos
    //sino la registramos
    $cons_cant=mysql_query("SELECT COUNT(*) AS nroenc FROM encuesta",$con);
    $cant=mysql_fetch_array($cons_cant);
    if($cant['nroenc']==0){
       $insenc="INSERT INTO encuesta(pregunta, opciones, respuestas) VALUES ('$pre','$opc','$respuesta')";
       $insencresult = mysql_query($insenc, $con);
       echo "<div style=\"background-color:#888888;width:200px;color:red;\">Agregado <a href=\"./\">Ver encuesta</a></div>";
    }else{
       $cons_id=mysql_query("SELECT idenc FROM encuesta",$con);
       $idenc=mysql_fetch_array($cons_id);
       $id=trim($idenc['idenc']);
       $updenc="UPDATE encuesta SET pregunta='$pre', opciones='$opc', respuestas='$respuesta', nrovotos=0 WHERE idenc=$id";
       $updencresult = mysql_query($updenc, $con);
       echo "<div style=\"background-color:#888888;width:200px;color:red;\">Modificado <a href=\"./\">Ver encuesta</a></div>";
    }
  }
?>
<h3>Mini-Administrador de encuesta</h3>
<form name="frmEncuesta" method="post" action="admin.php">
<p>Escriba la pregunta</p>
<p>
  <input name="pregunta" type="text" id="pregunta" />
</p>
<p>Escriba las opciones separandolas por comas. Ej. Ubuntu, Red Hat, Suse, Debian</p>
<p>
  <input name="opciones" type="text" id="opciones" />
</p>
<p>
  <input type="submit" name="Submit" value="Crear Encuesta" />
</p>
</form>
</body>
</html>

index.php >> Ahora la página inicial de la encuesta. Esta página muestra la pregunta de la encuesta y las opciones que podemos elegir con un botón en la parte final para votar.

El script funciona así: Verificamos en primer lugar si existe la encuesta, en caso de no existir mostramos un vinculo que nos lleva a la página admin.php, en caso de existir realizamos otra consulta para capturar los datos de la tabla encuesta en varibles. Pasamos a definir un formulario en cuyo evento onsubmit espeficiamos la función cargarResultados(), esta función se encuentra en el archivo funciones_javascript.js. Usamos explode para separar las las opciones por coma para luego contar cuantos son y mediante un while creamos los botones radio necesarios. Recordemos que al usar explode convertimos una variable en array, así que para ver lo que contiene este elemento usamos un contador en este caso $i. También especificamos input de tipo hidden con el cantidad de opciones, este dato lo usaremos en la función cargarResultados(). Finalmente al formulario le colocamos un botón con el texto Votar.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Sistema de encuesta</title>
<script language="javascript" type="text/javascript" src="funciones_javascript.js"></script>
</head>
<body>
<?php
  require('conexion.php');
  //consultamos si hay datos en la tabla
  $cons_cant=mysql_query("SELECT COUNT(*) AS nroenc FROM encuesta",$con);
  $cant=mysql_fetch_array($cons_cant);
  if($cant['nroenc']==0){
    echo "<p>No hay encuesta</p>";
    echo "<p><a href=\"admin.php\">Agregar encuesta</p>";
  }else{
    //consultamos la encuesta actual
    $cons_enc_act=mysql_query("SELECT * FROM encuesta",$con);
    $datos=mysql_fetch_array($cons_enc_act);
    //obtenemos los datos de la tabla
    $id=$datos['idenc'];
    $preg=$datos['pregunta'];
    $opc=$datos['opciones'];
    //empezamos a crear la estructura html
    echo "
    <p style=\"padding-bottom:10px;\"><strong>".$preg."</strong></p>
    <div id=\"resultados\"> \n";
    //especificamos un formulario
    echo "
    <form onsubmit=\"cargarResultados(); return false\" name=\"frmencuesta\" action=\"\">
    <input type=\"hidden\" name=\"cod\" value=\"".$id."\" /> \n";
    //especificamos opciones
    //NOTA, usamos explode para separar cada item por las comas
    $opciones = explode(",",$opc);
    $i=0;
    //contamos cuantas partes tiene opciones
    $tot_elems=count($opciones);
    while($i<=$tot_elems-1){
      $j=$i+1;
      //note que $opciones es un array y visualizamos sus elementos 
      //mediante esta forma: elemento=$opciones[ubicacion_integer]
      echo "
      <p>
      <input type=\"radio\" name=\"opcion\" value=\"".$j."\" id=\"opcion".$j."\" /> ".trim($opciones[$i])."</p> \n";
      $i++;
    }
    echo "
    <input type=\"hidden\" name=\"nroopciones\" value=\"".$i."\" />";

    echo "
    <p style=\"text-align:center;\">
      <input class=\"boton\" type=\"submit\" value=\"Votar\" />
    </p>
    </form>
    </div> \n";
}
?>
</body>
</html>

funciones_javascript.js >> Definimos aquí las funciones: nuevoAjax() para crear el objeto XMLHttpRequest, y cargarResultados() la cual se encarga de verificar mediante un while si algun boton radio está seleccionado (checked), si es así capturamos en la variable alt el numero. Luego especificamos el archivo que realizará el proceso resultados.php, y le enviamos dos variables el id de la encuesta y la alternativa seleccionada.

function nuevoAjax(){
   var xmlhttp=false;
   try{
     xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");
   }catch(e){
     try{
       xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
     }catch(E){
       xmlhttp=false;
     }
 }
 if(!xmlhttp && typeof XMLHttpRequest!='undefined'){
   xmlhttp = new XMLHttpRequest();
 }
 return xmlhttp;
}

function cargarResultados(){
   divResultado = document.getElementById('resultados');
   //obtengo el codigo de la encuesta
   codenc=document.frmencuesta.cod.value;
   //obtengo el numero de opciones
   nroopc=document.frmencuesta.nroopciones.value;
   //creo un bucle para ver si alguna opcion esta checked
   //si esta checked ese valor lo envio por post
   i=1;
   while(i<=nroopc){
      opcion=document.getElementById('opcion'+i).checked;
      if (opcion==true){
         alt=i;
      }
      i++;
   }
   ajax=nuevoAjax();
   ajax.open("POST", "resultados.php",true);
   ajax.onreadystatechange=function() {
      if (ajax.readyState==4) {
         divResultado.innerHTML = ajax.responseText
      }
   }
   ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
   //envio dos valores el id de la encuesta y la opcion elegida de la encuesta
   ajax.send("idenc="+codenc+"&alternativa="+alt)
}

resultados.php >> Este el archivo principal del proceso de la encuesta. Su función es actualizar las opciones elegidas y mostrar los totales hasta el momento.

¿Como funciona? Obtengo las variables que me envio la función javascript cargarResultados(), el id de la encuesta y la alternativa seleccionada, luego realizamos una consulta por su id para trabajar con los valores obtenidos. Mediante explode separamos por coma los elementos tanto de las opciones como de las respuestas, contamos cuantos elementos son y mediante un while vamos concatenar la nueva respuesta. Esto lo haremos así: por ejemplo supongamos que se envio la alternativa 3, dentro del while mediante un if compararemos si son iguales, en caso afirmativo le sumaremos una unidad. Al final concatenaremos todas las respuestas. Después realizamos un update para actualizar tanto las respuestas como el número de votos.

Ahora listar los resultados. Para ello consultamos los nuevos datos, capturamos las variables con las cuales trabajaremos y separamos por coma las opciones y respuestas. Usamos un while para listar las opciones con su respectiva respuesta. Vamos a mostrar la alternativa con su porcentaje. Hay que tener en cuenta que para sacar el porcentaje a la respuesta le restamos una unidad, esto porque cuando guardamos la primera vez lo hicimos con 1,1,1… Finalmente mostramos el total de votos.

<?php
   require('conexion.php');
   //obtengo posicion de la opcion elegida
   $id=$_POST['idenc'];
   $vot=$_POST['alternativa'];
   //consulto la encuesta enviada
   $consulta=mysql_query("SELECT * FROM encuesta WHERE idenc=$id",$con);
   $datos=mysql_fetch_array($consulta);
   $opc=$datos['opciones'];
   $resp=$datos['respuestas'];
   //opciones aqui
   //explode separa c/item por las comas
   //aqui creamos automaticamente un array
   //con los elementos separados por coma
   $opciones = explode(",",$opc);
   $rptas = explode(",",$resp);
   $i=0;
   //iniciamos variables de cadenas vacias
   $respuesta_nueva="";
   $alternativas="";
   $coma="";
   //contamos la cantidad de respuestas
   $tot_elems=count($rptas);
   while($i<=$tot_elems-1){
      $j=$i+1;
      //si la opcion elegida coincide con el elemento
      //sumamos 1 a la opcion
      if($j==$vot){
         $valor_respuesta=$rptas[$i]+1; 
      }else{
         $valor_respuesta=$rptas[$i];
      }
      //escribimos cadena del tipo "0 1 0 0"
      $respuesta_nueva=$respuesta_nueva.$coma.$valor_respuesta;
      $alternativas=$alternativas.$rptas[$i];
      $coma=",";
      $i++;
   }
   //actualizamos a nuevos valores de respuestas, y sumamos en una unidad el numero de votos
   $updenc="UPDATE encuesta SET respuestas='$respuesta_nueva', nrovotos=nrovotos+1 WHERE idenc=$id";
   $updencresult = mysql_query($updenc, $con);

   //ahora listamos resultados
   $consulta2=mysql_query("SELECT * FROM encuesta WHERE idenc=$id",$con);
   $listado=mysql_fetch_array($consulta2);
   $preg=$listado['pregunta'];
   $opc=$listado['opciones'];
   $resp=$listado['respuestas'];
   $nrovot=$listado['nrovotos'];
   $opciones = explode(",",$opc);
   $rptas = explode(",",$resp);
   $i=0;
   $tot_elems=count($opciones);
   while($i<=$tot_elems-1){
      echo "<p>";
      echo $opciones[$i];
      $ResulOpc = $rptas[$i]-1;
      //-1 por que empieza con 1 en los resultados 
      //esto por que si coloco 0 (ceros) no acepta
      //total de votos por cada opcion por el 100% y sobre el numero total de votos
      $ResulPorc=( $ResulOpc * 100 ) / $nrovot;
      echo "&nbsp;<strong>".round($ResulPorc,2)."%</strong>";
      echo "</p> \n";
      $i++;
   }
   echo "<p style=\"text-align:center;\">Total de votos: ".$nrovot."</p> \n";
?>

He incluido lineas //comentadas en el código con el fin de explicar mejor cada bloque de código y que pueda ser entendido. Pueden ver una muestra en acción y como también descargar el código.

El sistema de encuesta se puede mejorar a criterio de cada uno. Por ejemplo para no realizar votos a cada instante se puede trabajar con cookies o guardar las IPs.

Programador y Desarrollador Web. Administrador de RibosoMatic y Proyecto Yupy. Blogger y entusiasta de la tecnología, internet, software y tutoriales para desarrollo de aplicaciones para la web ....