¿ Qué es pecado ?

Personal July 31st, 2007

  1. Respetarás a todos por igual.
  2. Evitarás la arrogancia y la soberbia.
  3. No mentirás.
  4. No matarás.
  5. No harás nada que atente en contra de localhost o de cualquier otro (leyes).
  6. No dejarás que el tiempo de trabajo consuma tu tiempo de descanso ni permitirás que el descanso interfiera con tu trabajo.
  7. Destinarás el tiempo que sea necesario para aprender lo que sea de tu responsabilidad o interés.
  8. Tendrás cuidado con root sobre todas las cosas.
  9. Creerás en sigterm como en sigkill.
  10. No violarás el diseño. En caso de necesitarlo deberás complementarlo y tomar medidas correctivas para que tal sacrilegio no vuelva a suceder.
  11. Documentarás todo lo que haces.
  12. No mezclarás la presentación con el modelo.
  13. No aceptarás ni argumentarás un no por respuesta si existe al menos una posibilidad de realizarlo. Tampoco aceptarás el argumento "porque aquí siempre se ha hecho así".
  14. No dividirás por cero ni ejecutarás acción ninguna sobre objetos cuyo contenido sea null.
  15. Harás que todo sea de la manera mas simple posible, no un poco mas ni un poco menos (principio KISS).
  16. Declararás del tipo apropiado cualquier cosa que utilices, en su defecto le asignarás siempre un valor inicial.
  17. No intentarás ejecutar métodos sobre otros objetos que no quieres que sean ejecutados en los tuyos, menos aún si el ámbito de estos es privado o protegido.
  18. Todo deberá ser fielmente validado, tanto en el lado del servidor como en el cliente. Ante la incertidumbre no confiarás en nadie, ni siquiera en la existencia de tí mismo.
  19. Nunca perderás la esperanza, siempre habrá un día+1 hasta el último return, después de eso encontrarás la paz en /dev/null.
  20. Nunca retrodocerás, jamás te rendirás.

Ejemplo simple con Ajax - parte final

Desarrollo de software, Web July 30th, 2007

La aplicación de ejemplo fue producto de mi primer par de horas de contacto con Ajax y Prototype así que tal vez no sea la mejor de las soluciones, sin embargo como todo es suceptible de ser mejorado. Se reciben comentarios al respecto.

La aplicación de ejemplo y los archivos fuente pueden ser descargados del siguiente URL: http://demo.jorgeivanmeza.com/Prototype/ajax1/.

Tags: , , ,

Humor de ingenieros

Humor July 29th, 2007

-Qué le dijo un vector a otro vector?: Tienes un momentum?

-En una fiesta de funciones está bailando "seno de x" con "coseno de x".
"seno de x" se da cuenta de que "e a la x" está sentado solo a un costado
de la pista. Entonces se le acerca amigablemente y le dice:
¡Intégrate!" Y él le responde: "¿para qué? ! Si da igual!

-¿Qué es un niño complejo? Un niño con la madre real y el padre imaginario.

-Dios es real, a menos que sea declarado entero.

-Jesús a sus discípulos: "En verdad os digo: y=x2 +3x+4"
Los discípulos empiezan a hablar entre sí, hasta que Pedro se dirige a
Jesús y muy apesadumbrado le dice: "Maestro no entendemos". "Tranquilos,
es una parábola!"

- Comprendiendo a los Ingenieros - Parte 1 Dos estudiantes de ingeniería estaban caminando por el campus cuando uno de ellos dijo: "¿De dónde sacaste esa magnifica bicicleta?" El segundo contestó: "Bueno, Yo estaba caminando por ahí ayer, pensando en mis trabajos, cuando una hermosa mujer apareció sobre esta bicicleta. Tiró la bicicleta al suelo, se quitó toda su ropa y dijo: "Toma lo que quieras". El segundo ingeniero cabeceó afirmativamente: "¡Buena elección! ¡La ropa probablemente no te hubiera quedado bien!

-Comprendiendo a los Ingenieros - Parte 2 Un arquitecto, un artista y un
ingeniero estaban discutiendo acerca de si era mejor pasar el rato con la
esposa o con la amante. El arquitecto dijo que disfrutaba pasar el tiempo
con su mujer, construyendo una base sólida, para una relación duradera. El
artista dijo que disfrutaba pasar el tiempo con su amante, porque con ella
encontraba pasión y misterio. El ingeniero dijo: "A mi me gustan las dos"
"¿Las dos?" le preguntaron. "Sí. Si tienes una mujer y una amante, cada una
de ellas asumirá que estás con la otra, y puedes ir a la fábrica y dejar el
trabajo terminado."

-Comprendiendo a los Ingenieros - Parte 3 Para el optimista, el vaso está
medio lleno. Para el pesimista, el vaso está medio vacío. Para el ingeniero,
el vaso es el doble de grande de lo que debería ser.

-Comprendiendo a los Ingenieros - Parte 4 Un ingeniero estaba cruzando un camino un día, cuando un sapo lo llamó y le dijo: "Si me besas, me volveré
una hermosa princesa". El ingeniero se inclinó, tomó el sapo y se lo metió
en el bolsillo. El sapo volvió a hablar, y dijo: " Si me besas para que me
vuelva una hermosa princesa, me quedaré contigo durante una semana". El
ingeniero sacó el sapo del bolsillo, le sonrió y lo volvió a meter en el
bolsillo. Entonces el sapo gritó: "Si me besas y me vuelvo una hermosa
princesa, me quedaré contigo y haré cualquier cosa que quieras". Otra vez
el ingeniero sacó el sapo, le sonrió y lo devolvió al bolsillo. Finalmente,
el sapo preguntó: "¿Qué pasa? Te dije que soy una hermosa princesa, que me
quedaré contigo por una semana y haré lo que quieras. ¿Por qué no me
besas?" El ingeniero dijo: "Mira, soy un ingeniero. No tengo tiempo para
chicas, pero un sapo que hable, ¡eso si que es interesante!
"

- Un hombre que vuela en globo, se percata de que está perdido, por lo que
maniobra y desciende hasta que divisa a alguien en la calle y grita:
"¡Disculpe!, ¿Podría usted ayudarme?, he quedado de reunirme a las dos con
un amigo, llevo media hora de retraso y no sé donde me encuentro. "Claro que sí, le contesta, se encuentra Ud. en un globo de aire a unos 30m de altura,
entre los 40 y 42º de latitud norte y los 58 y 60º de longitud oeste. "Es
Ud. ingeniero, ¿verdad?", dice el del globo. "Si señor. Lo soy. ¿Cómo lo
adivinó?" "Es simple. Porque todo lo que me ha dicho es "técnicamente
correcto", pero "prácticamente inútil". "Continúo perdido, llegaré tarde y
no sé que hacer con su información..
. Es usted gerente, ¿verdad?", preguntó
el de la calle. "Si señor, ¿Cómo lo ha sabido?" "Es simple. No sabe donde
está ni a donde va. Ha hecho una promesa que no puede cumplir y espera que
otro le resuelva el problema. De hecho, se halla exactamente en la misma
situación en que estaba antes de encontrarnos, salvo que ahora, por alguna
extraña razón,..... ¡La culpa es mía!"

- Un tipo iba caminando por la calle cuando, de
repente, lo para un ladrón enmascarado, arma en mano y le dice: "Anda
pronto. Este es un asalto ¡Dame tu reloj!" El tipo le da su reloj (una
imitación Rolex ).... El ladrón se molesta y le dice: "¿Qué es esto? Una
imitación? ¡Dame tu billetera!" El hombre le da su billetera de plástico,
imitación de Pierre Cardin, con una tarjeta de Transmilenio y 12.000 pesos.
El ladrón se enoja y le increpa: "¿Qué carajos es esto? ... tu traje está
todo desgastado, tu celular es pirata, tu reloj que aparenta ser bueno es
úna imitación... estás más jodido que yo. ¿A que te dedicas? El tipo,
avergonzado, contesta casi llorando: "¡Soy ingeniero de sistemas!" El ladrón,
Quitándose la máscara, emocionado le pregunta: "¿De verdad ?¿ De qué
promoción?"

Problemas con el idioma de los documentos

Linux/Unix/FreeBSD, Windows July 27th, 2007

El día de ayer tuve que invertir un buen par de horas en investigar acerca de unos presuntos problemas con la selección del idioma de los documentos de OpenOffice.

Instalé el diccionario en Español (Colombia) con el macro. Configuré correctamente en Herramientas > Opciones > Configuración de Idioma > Idiomas > Idioma Predeterminado (Occidental). La corrección automática funcionaba bien en los documentos nuevos, sin embargo algunos documentos traídos por los usuarios no eran verificados por el corrector.

Descubrí que, aparentemente, los carácteres (parrafos ?) también pueden tener secciones con diccionarios por separado.

El problema se solucionó seleccionando todo el documento afectado y eligiendo Formato > Carácter > Idioma = Español (Colombia).

Tags:

Un poco de humor para un día caluroso

Humor July 24th, 2007

Humor1

Humor2

Ejemplo simple con Ajax - Cuarta parte

Desarrollo de software, Web July 19th, 2007

La parte final del ejemplo corresponde al código PHP que realiza en realidad las tareas de inserción, búsqueda y listado de los registros en la base de datos.

El archivo config.php define la información requerida para la ejecución de la aplicación, en este ejemplo concreto determina la información de conexión a la base de datos.

$config["bd"]["tipo"] = "sqlite";
$config["bd"]["servidor"] = "localhost";
$config["bd"]["nombre"] = "data/database.db";
$config["bd"]["usuario"] = "nobody";
$config["bd"]["contrasena"] = "nothing";

Incluye una función de apoyo para generar rápidamente el DSN de conexión.

function construirDSN()
{
global $config;

$dsn = $config["bd"]["tipo"]."://".$config["bd"]["usuario"].":".
$config["bd"]["contrasena"]."@".$config["bd"]["servidor"]."/".
$config["bd"]["nombre"];

return $dsn;
}

Incluye también una ampliación en ejecución del include_path de PHP para acceder sin problemas de rutas a las clases de Creole.

ini_set("include_path", ini_get("include_path") . PATH_SEPARATOR . 'lib/creole');

El archivo buscar.php realiza la búsqueda del registro cuyo documento corresponda con el especificado por el usuario. Incluye los archivos de configuración y de Creole para el acceso a la base de datos.

require_once('config.php');
require_once('creole/Creole.php');

Se requiere de la variable doc obtenida a través de los parámetros GET la cual representa el documento a buscarse. Se verifica que la variable exista, en caso contrario se termina la ejecución con un error 500.

if (!isset($_GET['doc']))
header("HTTP/1.0 500 El documento no fue correctamente especificado.");

$documento = htmlspecialchars($_GET['doc'], ENT_QUOTES);

Se realiza la conexión a la base de datos, en caso de error se termina la ejecución con un error 500.

$dsn = construirDSN();

$conn = Creole::getConnection($dsn, Creole::COMPAT_ASSOC_LOWER |
Creole::COMPAT_RTRIM_STRING);

if ($conn == null)
header("HTTP/1.0 500 Tuve problemas abriendo la base de datos.");

Se realiza la consulta a la base de datos basada en el documento especificado por el usuario. Nuevamente, en caso de fallar la consulta, se termina la ejecución con un error 500.

$sql = "SELECT documento, nombres, apellidos, email
FROM usuario
WHERE documento='{$documento}'";

try
{
$rs = $conn->executeQuery($sql);
$rs->next();
}
catch (SQLException $e)
{
header("HTTP/1.0 500 Tuve problemas ejecutando la consulta.");
}

Se verifica que la consulta haya retornado una registro como respuesta, en caso contrario se le indica al usuario.

$count = $rs->getRecordCount();

if ($count == 0)
header("HTTP/1.0 500 El documento consultado no existe en la base de datos.");

En caso de éxito, se obtiene la información del registro encontrada en la base de datos y se construye el mensaje en formato JSON para ser remitida a la función en JavaScript que la mostrará en el formulario.

$document = htmlspecialchars_decode ($rs->get('documento'), ENT_QUOTES);
$name = htmlspecialchars_decode ($rs->get('nombres'), ENT_QUOTES);
$lastname = htmlspecialchars_decode ($rs->get('apellidos'), ENT_QUOTES);
$email = htmlspecialchars_decode ($rs->get('email'), ENT_QUOTES);

$mensaje = "{
'documento': '{$document}',
'nombres': '{$name}',
'apellidos': '{$lastname}',
'email': '{$email}'
}";

Se finaliza la información de conexión a la base de datos, se notifica del éxito del procedimiento y se envía la información de vuelta al solicitante.

$rs->close();

$conn->close();

header("HTTP/1.0 200 Documento encontrado exitosamente.");

echo $mensaje;

El archivo agregar.php inserta la información determinada por el usuario en la forma como un registro en la base de datos. Incluye los mismos archivos de soporte del archivo anterior.

Requiere que se especifiquen la información del documento, nombres, apellidos y dirección de correo electrónico del registro que se va a agregar. Verifica la existencia de esta información y termina la ejecución en caso de faltar cualquiera de las variables. En caso de éxito obtiene la información que va a ser agregada.

if (!isset($_POST['doc']) || !isset($_POST['nom']) ||
!isset($_POST['apl']) || !isset($_POST['ema']))
header("HTTP/1.0 500 El registro no fue correctamente especificado.");

$documento = htmlspecialchars($_POST['doc'], ENT_QUOTES);
$nombres = htmlspecialchars($_POST['nom'], ENT_QUOTES);
$apellidos = htmlspecialchars($_POST['apl'], ENT_QUOTES);
$email = htmlspecialchars($_POST['ema'], ENT_QUOTES);

Se realiza la conexión a la base de datos, en caso de error se termina la ejecución con un error 500.

$dsn = construirDSN();

$conn = Creole::getConnection($dsn, Creole::COMPAT_ASSOC_LOWER |
Creole::COMPAT_RTRIM_STRING);

if ($conn == null)
header("HTTP/1.0 500 Tuve problemas abriendo la base de datos.");

Se prepara la sentencia INSERT de SQL para agregar la información especificada a la base de datos.

$sql = "INSERT INTO usuario (documento, nombres, apellidos, email)
VALUES (?, ?, ?, ?)";

$stmt = $conn->prepareStatement($sql);

$stmt->setString(1, $documento);
$stmt->setString(2, $nombres);
$stmt->setString(3, $apellidos);
$stmt->setString(4, $email);

Se realiza la ejecución de la misma.

$count = 0;

try
{
$count = $stmt->executeUpdate();
}
catch (SQLException $e)
{
header("HTTP/1.0 500 Tuve problemas insertando el nuevo registro.");
}

if ($count == 0)
header("HTTP/1.0 500 No fue posible agregar el registro en la base de datos.");

En caso de éxito, finaliza la información de conexión a la base de datos y notifica del éxito del procedimiento.

$stmt->close();

$conn->close();

header("HTTP/1.0 200 El registro fue agregado exitosamente.");

El último archivo que conforma el ejemplo es listar.php que despliega la lista de registro almacenados en la base de datos al presionar el botón Registros. Se incluyen los mismos archivos de los códigos anteriores y se realiza la conexión a la base de datos de igual manera.

Se consultan los registros almacenados en la base de datos.

$sql = "SELECT documento, nombres, apellidos, email
FROM usuario
ORDER BY apellidos, nombres";

try
{
$rs = $conn->executeQuery($sql);
$rs->next();
}
catch (SQLException $e)
{
header("HTTP/1.0 500 Tuve problemas ejecutando la consulta.");
}

Se verifica que la consulta retorne información, en caso contrario se notifica al solicitante.

$count = $rs->getRecordCount();

if ($count == 0)
header("HTTP/1.0 500 No se encuentran registros en la base de datos.");

En caso de éxito se prepara la información tal y como se va a presentar en la forma, en este caso dentro de una tabla HTML.

$mensaje = "<table cellspacing='3' cellpadding='2' border='1'>";

$mensaje .= "<tr bgcolor='yellow' align='center'><td><b>Documento</b></td>" .
"<td><b>Nombres</b></td><td><b>Apellidos</b></td>" .
"<td><b>Email</b></td></tr>\n";

do
{
$mensaje .= "<tr>";
$mensaje .= "<td>{$rs->get('documento')}</td>";
$mensaje .= "<td>{$rs->get('nombres')}</td>";
$mensaje .= "<td>{$rs->get('apellidos')}</td>";
$mensaje .= "<td>{$rs->get('email')}</td>";
$mensaje .= "</tr>\n";
} while($rs->next());

$mensaje .= "</table>";

Se finaliza la información de conexión a la base de datos, se notifica del éxito del procedimiento y se envía la información de vuelta al solicitante.

$rs->close();

$conn->close();

header("HTTP/1.0 200 Listado de registros generado exitosamente.");

echo $mensaje;

Tags: , , ,

Mario Bros. 2 bamba!

Videojuegos July 9th, 2007

Hoy, sin querer, descubrí el motivo por el cual Mario Bros. 2 no se parece en nada al 1, 3 y demás. Resulta que después del éxito de la versión 1, Nintendo desarrolló una versión 2 que era básicamente un reencauche del 1 con nuevos niveles y mayor complejidad. Sin embargo cuando la versión final estuvo lista dijeron que el juego era demasiado difícil para el público americano y decidieron tomar un juego japonés (Doki Doki Panic), adaptarlo modificando las gráficas y presentarlo como Mario Bros. 2. Por eso es que no tienen nada que ver el uno con los otros.

El verdadero Mario Bros. 2 es el que conocimos como The Lost Levels incluido en la versión de Super Nintendo que recopilaba todas las versiones de Mario Bros.

Para mas información de este interesante hecho consultar los siguientes enlaces.

Ejemplo simple con Ajax - Tercera parte

Desarrollo de software, Web July 7th, 2007

Modelo de llamados a procedimientos JavaScript y PHP para la ejecución de código con AJAX

La secuencia de llamados es la siguiente.

[1] Un botón en una página HTML ejecuta a una función JavaScript según la especificación del manejo de su evento OnClick.

[2] La función (Manejador de Acción en el diagrama) especifica el URL del PHP a ejecutarse, el método de envío de parámetros (POST o GET), prepara los parámetros necesarios (mensaje en formato GET) y determina cuales funciones JavaScript deberán ejecutarse en el caso en que la ejecución del programa PHP envíe la señal de que ha terminado exitosamente o que ha fracasado.

[3] El programa PHP (Implementación) es ejecutado previo envío de los parámetros con la información necesaria para su ejecución. La aplicación ejecutada puede tomar ventaja de todas las facilidades que el lenguaje nativo ofrece, incluyendo el acceso a bases de datos.

El programa PHP envía a la salida estándar la información que requiere enviar como respuesta al procedimiento AJAX que inicio su ejecución. Además puede indicar su estado de éxito o de fracaso manipulando los códigos HTTP de respuesta (2xx es éxito, cualquier otro es fracaso). En PHP esto se realiza utilizando la función header con la información apropiada. Su llamado debe ser previo a cualquier envío de información (echo, printf, etc.) por parte de código PHP. Si nose especifica ninguna respuesta, se asume la 200 (éxito).

[4] Según la respuesta obtenida por la aplicación PHP se ejecuta la función JavaScript Manejador de Éxito o Manejador de Fracaso según se especificó en la definición del Manejador de Acción.

Estas funciones tienen acceso a la información producida por la aplicación PHP y por el código de respuesta de la misma a través de las siguientes funciones.

  • xmlHttpRequest.responseText: Información suministrada por la aplicación PHP.
  • xmlHttpRequest.responseXML: Igual que responseText representando la respuesta en una estructura XML.
  • xmlHttpRequest.statusText: Código de respuesta de la aplicación PHP.
  • xmlHttpRequest.statusText: Información del código de respuesta de la aplicación PHP.

La ejecución de las funciones mencionadas determina la actualización de la interfaz de usuario (HTML) según la respuesta obtenida.

A continuación se describen los procedimientos y código fuente requerido para realizar las funciones de búsqueda, inserción y listado de registros.

* Búsqueda de registros.

[1] El botón b_buscar del formulario myForm ejecuta la función buscar cuando su evento OnClick es lanzado. La función mencionada recibe como parámetro el documento del registro a buscar.

[2] La función JavaScript buscar(doc) procesa la solicitud de la siguiente manera.

Crea una cadena con los datos requeridos para procesar correctamente la información (params).
Establece la ubicación (url) de la aplicación PHP a ejecutarse.
Establece el método (method) para transmitir esta información.

var params = "doc=" + doc;
var url = "buscar.php";
var method = "get";

Ejecuta el llamado a la aplicación utilizando los valores definidos anteriormente y definiendo las funciones doExitoBusqueda y doFracasoBusqueda para procesar los casos de éxito y fracaso respectivamente.

var ajax = new Ajax.Request (url,
{
method: method,
parameters: params,
onSuccess: doExitoBusqueda,
onFailure: doFracasoBusqueda
}
);

[3] En este momento la aplicación PHP, que será discutida posteriormente, es ejecutada.

En caso de que suceda algún tipo de error es enviado el mensaje 500 junto con un texto alusivo al error. En caso de éxito es enviado un mensaje 200, de igual manera se envía la información respuesta imprimiendo a esta a partir de echo.

[4] En caso de error se ejecuta la función doFracasoBusqueda que obtiene el mensaje asociado al error (xmlHttpRequest.statusText) y lo muestra en el campo dispuesto para tal fin, valiéndose de la función mostrarMensajeError.

Como el registro no pudo ser encontrado, la función limpia el valor de los campos nombres, apellidos e email el puede contener en ese momento valores imprecisos.

function doFracasoBusqueda(xmlHttpRequest, responseHeader)
{
mensaje = xmlHttpRequest.statusText;

mostrarMensajeError(mensaje, "error");

document.getElementById("t_nombres").value = "";
document.getElementById("t_apellidos").value = "";
document.getElementById("t_email").value = "";
}

En caso de éxito se ejecuta la función doExitoBusqueda que muestra un mensaje de estado informando al usuario del éxito de la búsqueda, convierte la información recibida de la ejecución de la aplicación PHP (xmlHttpRequest.responseText) que viene en formato JSON y la convierte utilizando el parser de Prototype (evalJSON) para convertirlo en una clase cuyos campos son ubicados en sus atributos. Esta información recibida es transmitida a los campos de texto correspondientes para ser presentados al usuario.

function doExitoBusqueda(xmlHttpRequest, responseHeader)
{
var response = xmlHttpRequest.responseText;
var mensaje = xmlHttpRequest.statusText;

mostrarMensajeError(mensaje, "exito");

var data = response.evalJSON();

document.getElementById("t_documento").value = data.documento;
document.getElementById("t_nombres").value = data.nombres;
document.getElementById("t_apellidos").value = data.apellidos;
document.getElementById("t_email").value = data.email;
}

* Inserción de registros.

[1] El botón b_agregar del formulario myForm ejecuta la función agregar cuando su evento OnClick es lanzado. La función mencionada recibe como parámetro la forma donde se encuentran ubicados los campos que contienen la información relativa al registro a insertar.

[2] La función JavaScript agregar(forma) procesa la solicitud de la siguiente manera.

Crea una cadena con los datos requeridos para procesar correctamente la información (params).
Establece la ubicación (url) de la aplicación PHP a ejecutarse.
Establece el método (method) para transmitir esta información.

var params = "doc=" + forma.t_documento.value +
"&nom=" + forma.t_nombres.value +
"&apl=" + forma.t_apellidos.value +
"&ema=" + forma.t_email.value;
var url = "agregar.php";
var method = "post";

Ejecuta el llamado a la aplicación utilizando los valores definidos anteriormente y definiendo las funciones doExitoAgregar y doFracasoAgregar para procesar los casos de éxito y fracaso respectivamente.

var ajax = new Ajax.Request (url,
{
method: method,
postBody: params,
onSuccess: doExitoAgregar,
onFailure: doFracasoAgregar
}
);

[3] En este momento la aplicación PHP, que será discutida posteriormente, es ejecutada.

[4] En caso de error se ejecuta la función doFracasoAgregar que obtiene el mensaje asociado al error y lo muestra en el campo dispuesto para tal fin, valiéndose de la función mostrarMensajeError.

function doFracasoAgregar(xmlHttpRequest, responseHeader)
{
mensaje = xmlHttpRequest.statusText;

mostrarMensajeError(mensaje, "error");
}

En caso de éxito se ejecuta la función doExitoAgregar que muestra un mensaje de estado informando al usuario del éxito del proceso de inserción.

function doExitoAgregar(xmlHttpRequest, responseHeader)
{
mensaje = xmlHttpRequest.statusText;

mostrarMensajeError(mensaje, "exito");
}

* Generar un listado de registros.

[1] El botón b_listar del formulario myForm ejecuta la función listar cuando su evento OnClick es lanzado.

[2] La función JavaScript listar() procesa la solicitud de la siguiente manera.

Determina a partir del estado de la variable global (mostrandoListado) si el listado se encuentra actualmente en pantalla (true) y en cuyo caso debe ocultarse o si por el contrario, el listado se encuentra oculto (false) y deberá presentarse al usuario.

En caso de requerirse que se oculte, el contenido del DIV con el identificador listado_registros es vaciado.

if (mostrandoListado)
{
mostrandoListado = false;

document.getElementById("listado_registros").innerHTML = "";

return;
}

En el caso contrario, cuando es necesario desplegar la lista de registro en la página, se realizan los siguientes pasos.

Establece la ubicación (url) de la aplicación PHP a ejecutarse.
Establece el método (method) para transmitir esta información.

mostrandoListado = true;

var url = "listar.php";
var method = "get";

Ejecuta el llamado a la aplicación especificando el DIV donde se mostrará la tabla (listado_registros), los valores definidos anteriormente y definiendo las funciones doExitoListar y doFracasoListar para procesar los casos de éxito y fracaso respectivamente.

var ajax = new Ajax.Updater ("listado_registros",
url,
{
method: method,
onSuccess: doExitoListar,
onFailure: doFracasoListar
}
);

En ambos casos se modifica el valor de la variable mostrandoListado a su negación para mantener sincronizado el sistema.

Nótese por favor que en este último caso se utilizo Ajax.Request en lugar de Ajax.Updater. La diferencia entre los dos radica en que el primero permite especificar que funciones JavaScript se deberán ejecutar según el éxito o el fracaso de la aplicación ejecutada, mientras que el segundo permite además especificar el id de un DIV al cual se redireccionará automáticamente la información recibida de parte de la aplicación PHP.

[3] En este momento la aplicación PHP, que será discutida posteriormente, es ejecutada.

[4] En caso de error se ejecuta la función doFracasoListar que obtiene el mensaje asociado al error y lo muestra en el campo dispuesto para tal fin, valiéndose de la función mostrarMensajeError.

function doFracasoListar(xmlHttpRequest, responseHeader)
{
mensaje = xmlHttpRequest.statusText;

mostrarMensajeError(mensaje, "error");
}

En caso de éxito se ejecuta la función doExitoListar que muestra un mensaje de estado informando al usuario del éxito de la presentación de la información.

function doExitoListar(xmlHttpRequest, responseHeader)
{
mensaje = xmlHttpRequest.statusText;

mostrarMensajeError(mensaje, "exito");
}

Como última etapa del desarrollo de la aplicación, se deberá continuar con la especificación de las aplicaciones PHP (buscar.php, agregar.php y listar.php) las cuales son las responsables realmente de procesar la información por solicitud del usuario y de recuperarla o en la base de datos según se requiera.

Tags: , , ,

Ejemplo simple con Ajax - Segunda parte

Desarrollo de software, Web July 6th, 2007

Diagrama Ajax1

Estructura:

[1] El formulario tiene 4 campos: Documento de identidad, nombres, apellidos y dirección de correo electrónico que corresponden 1:1 con los campos de la tabla usuario de la base de datos.

[2] En la parte superior hay un espacio para los mensajes de error.

[3] En la parte inferior hay un espacio para mostrar la tabla de registros.

[4] A continuación del campo: documento de identidad, hay un botón Buscar que permite indagar sobre la existencia de un registro con dicho documento.

[5] En la parte inferior está el botón Agregar que permite insertar la información del usuario ubicada en el formulario a la base de datos.

[6] También se encuentra un botón Registros que permite mostrar u ocultar la tabla de registros con la información almacenada hasta el momento en la base de datos.

Flujo:

Si se presiona [4] se consulta la base de datos en busca del documento especificado. En caso de encontrarse una coincidencia, su información se muestra en [1], en caso contrario se muestra el mensaje de error en [2].

Si se presiona [5] se intenta realizar la inserción de la información en la tabla usuario de la base de datos. En caso de tener éxito o fracaso durante la transacción, se muestra un mensaje adecuado en [2].

Si se presiona [6] se muestran los registros contenidos en la base de datos en [3]. En caso de no existir registros se muestra un mensaje de error apropiado en [2].

Implementación:

Teniendo esto claro se procedió con la implementación del formulario en HTML en el archivo form.html.

Se contó con 4 áreas. Una para la inclusión de los archivos JavaScript: prototype.js requerido por el framework de Prototype y form.js que contiene las funciones a definirse próximamente.

<script language="javascript" src="lib/prototype/prototype.js"></script>
<script language="javascript" src="form.js"></script>

La segunda sección representa el espacio reservado para los mensajes de error.

<div id="mensaje_error"></div>

La tercer sección define el formulario (myForm) como tal. Las longitudes de los campos de texto (maxlength) deberán coincidir con los tamaños de los campos definidos en la base de datos.

<form name="myForm">
<table>
<tr>
<td>
<b>Documento</b>
</td>
<td>
<input type="text" id="t_documento" value="" size="30"
maxlength="10" />
</td>
<td>
<input type="button" id="b_buscar" value="Buscar"
onClick="buscar(document.myForm.t_documento.value)" />
</td>
</tr>
<tr>
<td>
<b>Nombres</b>
</td>
<td colspan="2">
<input type="text" id="t_nombres" value="" size="30"
maxlength="60" />
</td>
</tr>
<tr>
<td>
<b>Apellidos</b>
</td>
<td colspan="2">
<input type="text" id="t_apellidos" value="" size="30"
maxlength="60" />
</td>
</tr>
<tr>
<td>
<b>Dirección de Correo</b>
</td>
<td colspan="2">
<input type="text" id="t_email" value="" size="30"
maxlength="128" />
</td>
</tr>
</table>

<input type="button" id="b_agregar" value="Agregar"
onClick="agregar(document.myForm) "/>

<input type="button" id="b_listar" value="Registros"
onClick="listar() "/>
</form>

Nótese que el evento onClick de los botones Buscar, Agregar y Registros es manejado por las funciones JavaScript buscar(documento), agregar(forma) y listar() respectivamente, las cuales se definirán próximamente.

La cuarta y última sección de la interfaz de usuario representa el espacio reservado para desplegar la tabla de registros.

<div id="listado_registros"></div>

El siguiente paso corresponde al implementar las funciones JavaScript almacenadas en el archivo form.js que produzcan los resultados esperados en la presión de los botones de la forma. La implementación de estas funciones estará basada en la librería de Prototype.

Tags: , , ,

Ejemplo simple con Ajax - Primera parte

Desarrollo de software, Web July 6th, 2007

[...]

Me quedé pensando ... qué tan difícil puede ser implementar el formulario solicitado utilizando AJAX para implementarlo como una mejor experiencia para el usuario que tiene que digitar la información ? Así fue como el jueves me dí a la tarea de crear mi primera aplicación (de prueba) en AJAX que describo a continuación.

Para el desarrollo de la aplicación tuve las siguientes consideraciones.

  • En lugar del autocompletar propuesto incialmente continué con la propuesta del botón de Buscar, sin embargo utilizando AJAX para la comunicación de las consultas.
  • El lenguaje del lado del servidor será PHP.
  • Utilizar Prototype (http://www.prototypejs.org/) como framework facilitador para la implementación de los llamados AJAX.
  • Utilizar SQLite (http://www.sqlite.org/) como medio de almacenamiento.
  • Utilizar Creole (http://creole.phpdb.org/) como abstracción del acceso a bases de datos desde PHP.

Creé la siguiente estructura de directorios para mi proyecto.

/ Archivos HTML, PHP y JS.

/data Archivo de almacenamiento de la base de datos.

/lib Almacenamiento librerías de terceros descritas a continuación.

/lib/creole

/lib/prototype

/lib/sqlite

El primer paso fue la creación de la base de datos a partir de la siguiente especificación de tabla.

CREATE TABLE usuario (
documento CHAR(10) NOT NULL,
nombres CHAR(60) NOT NULL,
apellidos CHAR(60) NOT NULL,
email CHAR(128) NOT NULL,
PRIMARY KEY (documento)
);

Con los siguientes registros incluidos como ejemplo.

INSERT INTO usuario VALUES ('123', 'PEPE', 'PIMENTON', 'pepe@pimenton.com');
INSERT INTO usuario VALUES ('231', 'LAURA', 'LLANO', 'laura@llano.com');
INSERT INTO usuario VALUES ('321', 'MIGUEL', 'ARBELAEZ', 'miguel@arbelaez.com');
INSERT INTO usuario VALUES ('213', 'PATRICIA', 'PEREZ', 'patricia@perez.com');

Esto se realizó de la siguiente manera.

dos> cd RUTA\ajax1\data

dos> ..\lib\sqlite\sqlite.exe database.db < script.sql

Los comandos anteriores crean el archivo 'database.db' a patir de la ejecución del 'script.sql' el cual contiene lo mencionado anteriormente. Es de notar que el archivo de base de datos se crea en el directorio actual.

A continuación escribí la interfaz de usuario en HTML.

Tags: , , ,