18 - Encuenta con AJAX


Confeccionaremos un nuevo problema donde podemos utilizar AJAX. Vamos a desarrollar una pequeña aplicación para hacer una encuesta.

La característica principal es que cuando el operador haga su selección procederemos a enviar la selección al servidor y generaremos un gráfico en forma dinámica en el servidor y procederemos a actualizar en forma asincrónica solo una parte de la página.

pagina1.php

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Problema</title>
  <script src="funciones.js"></script>
</head>
<body>
  <h1>Implementación de una encuesta empleando AJAX.</h1>
  <form action="pagina1.php" method="post" id="formulario">
    <fieldset>
    <h2>Que lenguaje utiliza para la implementación de páginas dinámicas?</h2>
    <div id="encuesta">
    <input type="radio" id="radio1" name="radio">PHP<br>
    <input type="radio" id="radio2" name="radio">ASP<br>
    <input type="radio" id="radio3" name="radio">JSP<br>
    <input type="submit" value="Enviar" id="enviar">
    </div>    
    </fieldset>
  </form>
</body>
</html>

funciones.js

addEventListener('load',inicializarEventos,false);

function inicializarEventos()
{
  var ref=document.getElementById('formulario');
  ref.addEventListener('submit',enviarDatos,false);
}

function enviarDatos(e)
{
  e.preventDefault();
  if (document.getElementById('radio1').checked)
    enviarSeleccion(1);
  else
    if (document.getElementById('radio2').checked)
      enviarSeleccion(2);
    else
      if (document.getElementById('radio3').checked)
        enviarSeleccion(3);
}


var conexion1;
function enviarSeleccion(cod) 
{
  conexion1=new XMLHttpRequest();
  conexion1.onreadystatechange = procesarEventos;
  var aleatorio=Math.random();
  conexion1.open('GET','pagina1.php?codigo='+cod+"&aleatorio="+aleatorio, true);
  conexion1.send(null);  
}

function procesarEventos()
{
  var encuesta = document.getElementById("encuesta");
  if(conexion1.readyState == 4)
  {
    encuesta.innerHTML = '<img src="encuesta.png">';
  } 
  else 
  {
    encuesta.innerHTML = '<img src="../cargando.gif">';
  }
}

Procedemos a capturar el evento submit para enviar los datos en forma asincrónica:

function inicializarEventos()
{
  var ref=document.getElementById('formulario');
  ref.addEventListener('submit',enviarDatos,false);
}

Cuando se presiona el botón submit procedemos a llamar a la función enviarSeleccion con el número de opción seleccionada:

function enviarDatos(e)
{
  e.preventDefault();
  if (document.getElementById('radio1').checked)
    enviarSeleccion(1);
  else
    if (document.getElementById('radio2').checked)
      enviarSeleccion(2);
    else
      if (document.getElementById('radio3').checked)
        enviarSeleccion(3);
}

La función enviarSeleccion procede a crear un objeto de la clase XMLHttpRequest y envía el número de opción seleccionada de la encuesta y un valor aleatorio para que no rescate el navegador una página que se encuentre en la cache de la computadora:

var conexion1;
function enviarSeleccion(cod) 
{
  conexion1=new XMLHttpRequest();
  conexion1.onreadystatechange = procesarEventos;
  var aleatorio=Math.random();
  conexion1.open('GET','pagina1.php?codigo='+cod+"&aleatorio="+aleatorio, true);
  conexion1.send(null);  
}

La función procesarEventos carga la imagen generada dinámicamente en el servidor. Esto se hace cuando el objeto XMLHttpRequest nos informa que los datos fueron generados completamente:

function procesarEventos()
{
  var encuesta = document.getElementById("encuesta");
  if(conexion1.readyState == 4)
  {
    encuesta.innerHTML = '<img src="encuesta.png">';
  } 
  else 
  {
    encuesta.innerHTML = '<img src="../cargando.gif">';
  }
}

Por último el archivo pagina1.php

fijarprofundidad(20);
$barra->sumar($reg['pregunta1'],"PHP");
$barra->sumar($reg['pregunta2'],"ASP");
$barra->sumar($reg['pregunta3'],"JSP");
$barra->graficar();

class Barra {
    var $ancho;
    var $alto;
    var $imagen;
    var $profundidad;

    var $colorfondo;
    var $vectorcolorfondo;
    var $colorbarra;
    var $vectorcolorbarra;
    var $colorvalores;
    //almacena los valores y los titulos de cada barra
    var $datos;

    function sumar($valor,$titulo)
    {
    	$indice=count($this->datos);
    	$this->datos[$indice]['valor']=$valor;
        $this->datos[$indice]['titulo']=$titulo;
    }

    function fijarcolorfondo($rojo,$verde,$azul)
    {
        $this->vectorcolorfondo[0]=$rojo;
        $this->vectorcolorfondo[1]=$verde;
        $this->vectorcolorfondo[2]=$azul;
	$this->colorfondo=ImageColorAllocate($this->imagen,$this->vectorcolorfondo[0],$this->vectorcolorfondo[1],$this->vectorcolorfondo[2]);
   	ImageFill($this->imagen,0,0,$this->colorfondo);
    }

    function fijarcolorbarra($rojo,$verde,$azul)
    {
        $this->vectorcolorbarra[0]=$rojo;
        $this->vectorcolorbarra[1]=$verde;
        $this->vectorcolorbarra[2]=$azul;
        $this->colorbarra=ImageColorAllocate($this->imagen,$this->vectorcolorbarra[0],		   $this->vectorcolorbarra[1],$this->vectorcolorbarra[2]);
    }

    function fijarprofundidad($profundidad)
    {
    	$this->profundidad=$profundidad;
    }


    //Metodo privado
    function mayor()
    {
	$primera=true;
	$may=0;
	foreach ($this->datos as $val)
	{
	    if ($primera)
	    {
		$primera=false;
	        $may=$val['valor'];
	    }
	    if ($val['valor']>$may)
  	        $may=$val['valor'];
	}
        return $may;
    }

    function graficarsombraizquierda($columna,$y1,$y2)
    {
       $rojo=$this->vectorcolorbarra[0]-90;
       if ($rojo<0)
       	  $rojo=0;
       $verde=$this->vectorcolorbarra[1]-90;
       if ($verde<0)
       	  $verde=0;
       $azul=$this->vectorcolorbarra[2]-90;
       if ($azul<0)
       	  $azul=0;

       $colorsombra=imageColorAllocate($this->imagen,$rojo,$verde,$azul);
       $puntos[]=$columna;
       $puntos[]=$y1;
       $puntos[]=$columna;
       $puntos[]=$y2;
       $puntos[]=$columna+$this->profundidad;
       $puntos[]=$y2-$this->profundidad;
       $puntos[]=$columna+$this->profundidad;
       $puntos[]=$y1-$this->profundidad;

       imagefilledpolygon($this->imagen,$puntos,4,$colorsombra);
       $colorbordebarra=imageColorAllocate($this->imagen,0,0,0);
       imagepolygon($this->imagen,$puntos,4,$colorbordebarra);
    }


    function graficarsombrasuperior($columna,$y1,$anchobarra)
    {
       $rojo=$this->vectorcolorbarra[0]-40;
       if ($rojo<0)
       	  $rojo=0;
       $verde=$this->vectorcolorbarra[1]-40;
       if ($verde<0)
       	  $verde=0;
       $azul=$this->vectorcolorbarra[2]-40;
       if ($azul<0)
       	  $azul=0;

       $colorsombra=imageColorAllocate($this->imagen,$rojo,$verde,$azul);
       $puntos[]=$columna;
       $puntos[]=$y1;
       $puntos[]=$columna+$anchobarra;
       $puntos[]=$y1;
       $puntos[]=$columna+$anchobarra+$this->profundidad;
       $puntos[]=$y1-$this->profundidad;
       $puntos[]=$columna+$this->profundidad;
       $puntos[]=$y1-$this->profundidad;

       imagefilledpolygon($this->imagen,$puntos,4,$colorsombra);
       $colorbordebarra=imageColorAllocate($this->imagen,0,0,0);
       imagepolygon($this->imagen,$puntos,4,$colorbordebarra);
    }

    function Barra($ancho,$alto)
    {
    	$this->ancho=$ancho;
        $this->alto=$alto;
		$this->imagen=imageCreate($this->ancho,$this->alto);
        $this->vectorcolorfondo[0]=0;
        $this->vectorcolorfondo[1]=0;
        $this->vectorcolorfondo[2]=255;
	$this->colorfondo=ImageColorAllocate($this->imagen,$this->vectorcolorfondo[0],$this->vectorcolorfondo[1],$this->vectorcolorfondo[2]);
	ImageFill($this->imagen,0,0,$this->colorfondo);
        $this->vectorcolorbarra[0]=255;
        $this->vectorcolorbarra[1]=255;
        $this->vectorcolorbarra[2]=0;
        $this->colorbarra=ImageColorAllocate($this->imagen,$this->vectorcolorbarra[0],
$this->vectorcolorbarra[1],$this->vectorcolorbarra[2]);
	$this->profundidad=10;
	$this->colorvalores=ImageColorAllocate($this->imagen,0,0,0);
   }

   function graficar()
   {

    	$may=$this->mayor();
        $anchobarra=($this->ancho-110)/count($this->datos);
	$x1=10;
	$y1=$this->alto-50;
        $colorbordebarra=imageColorAllocate($this->imagen,0,0,0);
	foreach($this->datos as $reg)
	{
	   $altura=($reg['valor']/$may)*($this->alto-80);
	   imagefilledrectangle($this->imagen,$x1,$y1-$altura,$x1+$anchobarra,$y1,$this->colorbarra);
	   imagerectangle($this->imagen,$x1,$y1-$altura,$x1+$anchobarra,$y1,$colorbordebarra);
	   ImageString($this->imagen,2,$x1+3,$y1,$reg['titulo'],$this->colorbarra);
           $this->graficarsombraizquierda($x1+$anchobarra,$y1-$altura,$y1);
           $this->graficarsombrasuperior($x1,$y1-$altura,$anchobarra);
	   ImageString($this->imagen,2,$x1+3,$y1-$altura+5,$reg['valor'],$this->colorvalores);
	       $x1=$x1+$anchobarra+(100/count($this->datos));
	 }
	 Header ("Content-type: image/png");
	 ImagePNG ($this->imagen,"encuesta.png");
	 ImageDestroy($this->imagen);
 }
}
?>

No analizaremos mucho este archivo ya que no es objetivo del curso el aprendizaje de PHP.

Básicamente la clase Barra nos permite crear un gráfico de barra creando un objeto de dicha clase y pasando los datos respectivos:

$barra=new Barra(500,300);
$barra->fijarprofundidad(20);
$barra->sumar($reg['pregunta1'],"PHP");
$barra->sumar($reg['pregunta2'],"ASP");
$barra->sumar($reg['pregunta3'],"JSP");
$barra->graficar();


Problema resuelto.


Confeccionar una encuesta utilizando AJAX.


pagina1.html



Ejecutar ejemplo



funciones.js




pagina1.php


Retornar