miércoles, 8 de junio de 2011

Menú desplegable con AJAX

Vamos a mostrar un interesante menú desplegable hecho con la técnica AJAX, y como construirlo paso a paso. Debo advertir que quizás se requiere de conocimientos básicos de programación y en especial, algo de programación en ambiente Web.
Necesitaremos los siguientes elementos:
  1. Base de datos: Usaremos MySQL como SMBD y, para este ejemplo tendremos una tabla cargada con un listado de ciudades
  2. Un script PHP que capture los datos de la base de datos según el parámetro enviado.
  3. Una Página Receptora de los resultados, en la que colocaremos la zona para mostrarlos. Además esta misma enviará la solicitud de los datos que necesita mostrar.
Veamos como será el resultado esperado. Solo comience a escribir un nombre en el campo de texto indicado. Al escribir las 3 primeras letras aparecerá un listado de los nombre en los que se encuentren estas. Por favor, intente escribir "mar..."

Nombre

Id
Documento


Paso 1. Empezamos construyendo la página donde se desencadenan todos los eventos. En nuestro ejemplo usaremos lo siguiente:
<html>
  <head>
    <title>Menu desplegable con AJAX</title>
  </head>
  <body>
    <div style="float:left;width:80px;">Nombre</div>
      <div style="float:left; width:220px;">
        <input type="text" style="width:200px;" name="nom" id="nom" value="" />
      </div>
      <div style="float:left; width:130px;">
        Id <input type="text" style="width:90px;" name="id" id="id" value="" />
      </div>
      <div style="float:left; width:190px;">
         Documento <input type="text" style="width:90px;" name="cid" id="cid" value="" />
      </div>
  </body>
</html>

Paso 2. Desarrollamos los elementos básicos para que AJAX funcione. Primero la función para crear instancias del objeto XMLHTTPRequest. En el post AJAX para principiantes - 2 encontraremos mas detalles acerca de este tema.
function nuevoAjax(){
var ajax;
  if (window.XMLHttpRequest) { // codigo para IE7+, Firefox, Chrome, Opera, Safari
    ajax=new XMLHttpRequest();
  } else { // codigo para IE6, IE5
    ajax=new ActiveXObject("Microsoft.XMLHTTP");
  }
  return ajax;
}

Paso 3. Crearemos el archivo php que se conectará a la base de datos para sacar de ella lo que necesitamos. A este archivo lo llamaremos array_listado.php, luego lo veremos mencionado en el proceso de captura de datos con Ajax en el paso 4.
<?php
$hostname = "localhost";
$database = "my_database";
$username = "my_username";
$password = "my_password";
$conexion = mysql_pconnect($hostname, $username, $password) or trigger_error(mysql_error(), E_USER_ERROR);

mysql_select_db($database, $conexion);
$sql_query = "SELECT * FROM clientes";
$cliData = mysql_query($sql_query, $conexion) or die(mysql_error());
$cliCount = mysql_num_rows($cliData);
  if ($cliCount>0) {
      $cli = mysql_fetch_assoc($cliData);
      $k = 0;
      do {
          echo $cli['id']."~".$cli['cli_nombre']."~".$cli['cli_cid']."--\n";
      } while ($cli = mysql_fetch_assoc($cliData));
  }
?>

Paso 4. Ahora crearemos una función con la que cargaremos en nuestra página un listado de nombre, id y documentos (para nuestro ejemplo).
var listado = new Array();
function cargar_array_listado() {
  var ajaxL = nuevoAjax();
  ajaxL.open("GET", "array_listado.php", true);
  ajaxL.onreadystatechange=function() {
    if (ajaxL.readyState==4) {
       var tabla = ajaxL.responseText;
       var registros = tabla.split("--");
       for (var u in registro) {
          datos = registro[u].split("~");
          listado[u]= new Object();
          listado[u]['id']=datos[0];
          listado[u]['nom']=datos[1];
          listado[u]['cid']=datos[2];
       }
     }
  }
  ajaxL.send(null);
}
Podemos darnos cuenta de que:

  • A través de la función open del objeto Ajax, ejecutamos en el servidor el archivo array_listado.php
  • Usando el método responseText del objeto Ajax, capturamos la respuesta del servidor como texto plano. Este contenido será una serie de registros separados por el doble guion "--", donde cada dato estará separado por el símbolo "~". Obviamente podemos usar el método responseXML, para lo cual deberíamos haber configurado nuestra respuesta del archivo array_listado.php como datos en formato XML.
  • Considerando que tenemos una respuesta en formato de texto plano, hacemos uso de la función split de JavaScript para obtener cada dato y construir la matriz de datos que necesitamos.

Paso 5. Agregaremos algunas funciones que nos ayudarán a que nuestra escritura en el campo de texto de como resultado que se despliegue un listado con los nombres que coincidan en cualquier parte con nuestra escritura.
function teclear(evt,campo){
    if (campo.value.length == 0) {
      if ((evt.keyCode == 9)||(evt.keyCode == 13)) {
      clear();
      }
    } else if ((campo.value.length > 0)&&(campo.value.length < 3)) {
       document.getElementById('selector').innerHTML = "";
       if ((evt.keyCode == 9)||(evt.keyCode == 13)) { // tab o enter
          clear();
       }
    } else {
       if ((evt.keyCode > 47)&&(evt.keyCode < 91)){ // cualquier letra o numero
          autoCompletar(campo);
       }
       if ((evt.keyCode == 37)||(evt.keyCode == 38)) { // flecha hacia arriba o hacia atras
          if (document.getElementById('sel').selectedIndex > 0) {
             document.getElementById('sel').selectedIndex = (document.getElementById('sel').selectedIndex)-1;
             campo.value =     document.getElementById('sel').options[document.getElementById('sel').selectedIndex].text
          }
       }
       if ((evt.keyCode == 39)||(evt.keyCode == 40)) { // flecha hacia abajo o hacia delante
            if (document.getElementById('sel').selectedIndex < (document.getElementById('sel').length-1)) {
                document.getElementById('sel').selectedIndex = (document.getElementById('sel').selectedIndex)+1;
                campo.value = document.getElementById('sel').options[document.getElementById('sel').selectedIndex].text
            }
        }
        if ((evt.keyCode == 9)||(evt.keyCode == 13)) { // tab o enter
            if (document.getElementById('sel').selectedIndex != -1) {
                var idsel = document.getElementById('sel').options[document.getElementById('sel').selectedIndex].value;
                document.getElementById('id').value = idsel;
                look(idsel);
                document.getElementById('selector').innerHTML = "";
                document.getElementById('cid').focus();
            } else {
                 document.getElementById('selector').innerHTML = "";
                 clear();
            }
        }
    }
    return false;
}

function autoCompletar(field) {
// crear selector
    var lista = "";
    var cuent = 0;
    var ubica = 0;
    var selecto = "";
    for (var k=0; k < listado.length; k++) {
        ubica = listado[k].name.toUpperCase().indexOf(field.value.toUpperCase());
        if ((ubica == 0)||(listado[k].name.toUpperCase().charCodeAt(ubica-1)==32)) {
           selecto += "<option value='" + listado[k].code + "' >" + listado[k].name + "</option>\n";
           cuent++;
        }
     }
     lista = "<select style=\"width:200px;\" name=\"sel\" id=\"sel\" onfocus = \"document.getElementById('nom').focus()\" onclick = \"document.getElementById('nom').value = this.options[this.selectedIndex].text\">\n" + selecto + "</select>\n";

// mostrar selector
    if (cuent == 0) {
        document.getElementById('selector').innerHTML = "";
        document.getElementById('re_id').value = 0;
    } else {
        document.getElementById('selector').innerHTML = lista;
        document.getElementById('sel').setAttribute('size',cuent+1);
        document.getElementById('sel').selectedIndex = -1;
    }
}

function clear() {
  document.getElementById('id').value = 0;
  document.getElementById('cid').value = '';
  document.getElementById('nom').value = '';
  document.getElementById('nom').focus();
}

function look(id) {
    for (var k=0; k<listado.length; k++) {
        if (listado[k].code == id){
            document.getElementById('cid').value = listado[k].cid;
            document.getElementById('nom').value = listado[k].name;
        }
    }
}

Paso 6. Finalmente, agregamos un par de detalles al campo de texto nombre, para que se desencadenen las funciones programadas para los eventos onFocus y onKeyUp

<input id="nom" name="nom" onfocus="cargar_array_listado();" onkeyup="teclear(event,this);" style="width: 200px;" type="text" value="" />

onFocus: Al recibir el enfoque, la matriz de datos se recargará con la lista actualizada de clientes, por lo que en un entorno multiusuario se podrán tener siempre los datos actualizados.
onKeyUp: Al soltar la pulsación de una tecla, se desencadenará la función que despliega el listado de nombres coincidentes. Igualmente en esta misma función se encuentran inmersos los procesos de selección de la lista y carga de datos del nombre seleccionado.

Por favor, no olviden comentar sus ideas para mejorar este artilugio.

sábado, 4 de junio de 2011

Cómo obtener datos de MySQL usando PHP

El lenguaje PHP es muy extenso, como todos. Aprender todas las posibilidades del lenguaje cuesta tiempo y perseverancia. Hoy vamos a explicar como conectarse a una base de datos en MySQL usando PHP.
Lo primero que debemos hacer es crear un archivo PHP por separado, en el cual crearemos "la conexión" a la base de datos. Este archivo será un objeto reutilizable en nuestra página.
<?php
$hostname = "localhost";
$database = "mi_base_de_datos";
$username = "mi_nombre_de_usuario";
$password = "mi_password";
$conexion = mysql_pconnect($hostname, $username, $password) or trigger_error(mysql_error(),E_USER_ERROR);
?>
De esta forma, la variable $conexion será nuestro enlace a la base de datos.
Ahora bien, ¿de dónde sacamos esos valores que le daremos a este pequeño script? Veamos nuestro phpMyAdmin para entenderlo
Clic para agrandar la imagen
En esta pantalla haremos clic en la opción "Agregar un nuevo usuario"
Colocamos nuestro nombre de usuario, elegimos servidor Local, colocamos una contraseña y la repetimos. Luego debemos asignarle a este nuevo usuario privilegios. En principio vamos a usar la opción "Marcar todos/as", luego podremos hablar con más detalles acerca de estos privilegios.
De estos datos tomaremos en cuenta:
  • El nombre de la base de datos
  • El nombre de usuario que acabamos de crear
  • El password de este usuario
Estos tres datos los escribiremos cada uno en su sitio en nuestro archivo de conexión, el cual llamaremos conexion.php.

Capturemos datos de una tabla
Ahora vamos a crear un archivo PHP que se conecte a la base de datos, lea una tabla, extraiga un registro e imprima los datos de este registro.
Lo primero que haremos es cargar el archivo de coenxión, con la orden siguiente:
<?php require_once('conexion.php'); ?>
Luego, seleccionamos la base de datos y la tabla que queremos acceder (Recuerde siempre encerrar el código PHP entre "<?php" y "?>".)
mysql_select_db($database, $conexion);
Ahora creamos una variable con la sentencia SQL con la que accederemos a los datos que deseamos.
$sql_query = "SELECT * FROM clientes";
Por supuesto que se pueden hacer consultas mas complejas, así como hacer uso variables de las cuales dependa el resultado, utilizando el punto (.) para concatenar o la función sprintf. Veamos dos ejemplos:
$sql_query = "SELECT * FROM clientes WHERE id_cliente=".$id_a_consultar." ORDER BY nombre_cliente";
O bien,
$sql_query = sprintf("SELECT * FROM clientes WHERE id_cliente=%s ORDER BY nombre_cliente", $id_a_consular);
Donde las ocurrencias de "%s" son sustituidas por las variables después de la coma, en el mismo orden en que aparezcan.
Luego crearemos una instancia de la tabla a través de la función mysql_query.
$clientes = mysql_query($sql_query, $conexion) or die(mysql_error());
Por último, obtendremos el número de registros, y si es superior a 0 (cero), entonces podremos acceder a los datos.
$num_registros = mysql_num_rows($clientes);
  if ($num_registros) {
    $columnas = mysql_fetch_assoc($ciudad);
    do {
      $id = $columnas['id_cliente'];
      $nombre = $columnas['nombre_cliente'];
      $telef = $columnas['tel_cliente'];
      echo $id . " - " . $nombre . " - " . $telef . "<br />"; // resultados
    } while ($columnas = mysql_fetch_assoc($ciudad))
  }
Existen varias otras formas de acceder a los datos, con el uso de las funciones propias de PHP para MySQL.
De esta forma habremos obtenido los resultados deseados. Tomemos en cuenta que al exponer los resultados, podemos agregar cualquier elemento HTML, es decir, podemos construir listas desplegables, tablas, cuadros de selección, etc. Nuestra propia audacia será nuestro límite!!

miércoles, 1 de junio de 2011

PHP: protegiendo el código fuente

PHP es un lenguaje de programación para crear scripts, ámpliamente usado en el desarrollo de páginas Web y sistemas bajo ambiente Web. Los scripts de PHP pueden ser colocados en archivos independientes o incrustado en el HTML de una página.

¿Qué tiene de particular el PHP?
PHP es un lenguaje de scripts que se ejecuta en el servidor. Esto quiere decir que las órdenes que coloquemos van a ser interpretadas en el servidor, traducidas en resultados que luego serán enviados al cliente, sin que se vea nada del código PHP que dio origen a ese resultado.
Veamos un ejemplo práctico. En su servidor de prueba o el servidor en donde hospeda su página, creemos un archivo PHP con apenas un par de órdenes:
<?php
echo "Hola mundo!!<br \>";
echo "Hoy es ".date("d/m/Y", time());
?>
Estas dos líneas las guardaremos como "prueba.php" en la carpeta raíz del servidor.
Luego navegaremos esta página en http://localhost/prueba.php. El resultado deberá ser algo como esto:
 Y al ver el código de la página en el navegador obtendremos:
Como podemos ver, los elementos del código PHP no aparecen en el resultado. El intérprete de PHP que trabaja en el servidor, procesa el código PHP y ofrece el resultado como HTML, para luego enviar este resultado a la PC cliente. De esta manera, PHP permite proteger la integridad del código fuente de nuestra página Web.

PHP incrustado en HTML
Ahora probemos algo un poco mas complejo para demostrar como funciona PHP incrustado en medio de HTML. Crea un archivo con este código y guárdalo en la raíz de tu servidor como prueba2.php.
<html>
<head>
<title>Prueba de PHP incrustado en HTML</title>
<?php
$nombre = "Neeos";


function fecha_en_espanol()
{
$result = ""; // variable de resultado vacia
// matriz de valores para dias de la semana
$diaArr[0] = "Domingo";
$diaArr[1] = "Lunes";
$diaArr[2] = "Martes";
$diaArr[3] = "Miercoles";
$diaArr[4] = "Jueves";
$diaArr[5] = "Viernes";
$diaArr[6] = "Sabado";
// matriz de valores para meses del ano
$mesArr[0] = "";
$mesArr[1] = "ENERO";
$mesArr[2] = "FEBRERO";
$mesArr[3] = "MARZO";
$mesArr[4] = "ABRIL";
$mesArr[5] = "MAYO";
$mesArr[6] = "JUNIO";
$mesArr[7] = "JULIO";
$mesArr[8] = "AGOSTO";
$mesArr[9] = "SEPTIEMBRE";
$mesArr[10] = "OCTUBRE";
$mesArr[11] = "NOVIEMBRE";
$mesArr[12] = "DICIEMBRE";
$result = $diaArr[(int)date('w')]." ".date('d')." de ".$mesArr[(int)date('m')]." de ".date('Y');
return $result;
}
?>
</head>
<body>
<p>Hola mundo!!<br />
Hoy es <?php echo fecha_en_espanol(); ?><br />
Les saluda cordialmente <?php echo $nombre; ?>
</p>
</body>
</html>

Quiero resaltar varias cosas en este código:

  1. El archivo lo hemos nombrado ".php" a pesar de contener código html. Esto se hace para que el intérprete PHP en el servidor "traduzca" la página a HTML antes de enviarla al cliente.
  2. El código PHP se puede incluir en la zona <head> de la página. En este área es frecuente encontrar funciones, declaraciones de variables o constantes y sus valores, conexiones al servidor  y capturas de datos de base de datos, etc.
  3. También se puede colocar código PHP en medio del diseño de la página, para hacer llamadas a funciones o valores declarados o capturados previamente.
  4. El código PHP se debe colocar entre las etiquetas "<?php" y "?>". Notemos también que cada línea debe terminar en ";".
  5. Para obtener el resultado concatenado, hemos usado la función 'date' propia de PHP, pasándole el argumento que conviene en cada caso. Vea este artículo del manual oficial del PHP.
  6. Note que el caracter de concatenacion en PHP es el punto '.'
El resultado en el navegador (cliente) será el siguiente:
Y el código fuente de este página no mostrará nada del código PHP original:
Les animo a que hagan sus propias pruebas y vean el potencial de este excelente lenguaje. Esté alerta a las próximas publicaciones, ya que seguiremos usando constantemente PHP para hacer muchas tareas comunes en el desarrollo de una página Web.