Hacer algo cuando inicia o termina el evento AJAX con Prototype

Introducción.

De manera análoga a como hace poco había mostrado como manejar el evento de inicio y terminación de AJAX con jQuery para realizar algún tipo de acción específica como el mostrar un indicador de carga, ahora experimentaremos como hacerlo con el framework de Prototype el cual nuevamente estaré utilizando en el proyecto de los próximos meses.

Procedimiento.

Ajax.Responders.register({
    onCreate: function()
    {
        // An AJAX request has been initialized!
    },

    onComplete: function()
    {
        // An AJAX request has been completed!
    }
});

Adicionalmente hay otros eventos que pueden manejarse de igual manera onUninitialized, onLoading, onLoaded, onInteractive y onException, además de los ya mencionados onCreate y onComplete.

Enlaces.

Ejemplo rápido y simple de AJAX con PHP y PrototypeJS

Introducción.

Intentando recuperar mis neuronas que saben de Prototype para continuar por fin con uno de los proyectos que se encontraba en pausa permanente, el día de hoy me día a la breve tarea de recordar un poco la invocación asíncrona y la manipulación del DOM utilizando esta librería.  Para hacer una pequeña práctica decidí modificar el ejemplo de la calculadora que se basaba en jQuery y PHP para migrar su código de acuerdo con la especificación de Prototype.

Las modificaciones necesarias se centraron en la inclusión de la librería javascript en la página web (frontend) y en reescribir la invocación asíncrona de la aplicación web en PHP (backend).

Procedimiento.

Reemplazar la inclusión de la librería de jQuery por la de Prototype.  Para este caso se continúo utilizando el API de Google AJAX.

<script src="http://www.google.com/jsapi"></script>
<script>google.load("prototype", "1.6");</script>

Posteriormente se asoció el manejo del evento de presión del botón igual a la invocación de la función procesar, esto se realiza tan pronto como la estructura de la página (código HTML) se encuentra cargada completamente por el navegador.

/* Código a ejecutarse tan pronto como la
   página ha sido cargada por el navegador */

document.observe('dom:loaded', function()
{
    /* Asociar el evento de clic del botón 'igual'
       con la lógica del negocio de la aplicación */

    Event.observe('igual', 'click', procesar);
});

Finalmente se implementa la función procesar que realizará la invocación asíncrona del cálculo matemático.  Esta función consta de las siguientes partes.

  1. Información básica del requerimiento.
  2. Que hacer en caso de éxito.
  3. Que hacer en caso de fracaso.

El requerimiento incluye la siguiente información básica de conexión.

  • El URL de la aplicación remota a invocar (backend).
  • El método HTTP a utilizar.
  • Los parámetros de la página web a enviarse.
function procesar()
{
    new Ajax.Request('calcular.php',                                         /* URL a invocar asíncronamente */
    {
        method:       'post',                                                /* Método utilizado para el requerimiento */
        parameters:   $('formulario').serialize(true),                       /* Información local a enviarse con el requerimiento */

En caso de que la invocación asíncrona tenga un resultado exitoso se deberán realizar los siguientes pasos.

  • Mostrar un mensaje de éxito en color verde.
  • Desplegar el valor del resultado obtenido en el campo definido para tal fin.
        /* Que hacer en caso de ser exitoso el requerimiento */

        onSuccess: function(transport)
        {
            /* Cambiar el color del texto a verde */

            $('mensaje').setStyle('color: #0ab53a');

            /* Mostrar un mensaje informando el éxito sucedido */

            $('mensaje').update("Operación realizada exitosamente");

            /* Mostrar el resultado obtenido del cálculo solicitado */

            $('resultado').update(transport.responseText);
        },

En caso de que fracase el proceso de invocación asíncrona se deberán realizar los siguientes pasos análogos.

  • Mostrar el mensaje de error proveniente del servidor, en color rojo.
  • Limpiar cualquier resultado previo para evitar confusiones con la operación.
        /* Que hacer en caso de que sea fallido el requerimiento */

        onFailure: function(transport)
        {
            /* Cambiar el color del texto a rojo */

            $('mensaje').setStyle('color: #ff0e0e');

            /* Mostrar el mensaje de error */

            $('mensaje').update('Error: ' + transport.responseText);

            /* Limpiar cualquier resultado anterior */

            $('resultado').update('Error');
        }
    });
}

Enlaces.

Resumen de AJAX con Prototype

Introducción.

Para finalizar la serie de artículos que había escrito acerca del uso de AJAX con el framework Prototype voy a realizar un muy breve resúmen de la sintaxis de las tres formas de realizar la invocación que me serán útiles para futuras referencias rápidas.

Utilizando el Updater.

El Ajax.Updater es una facilidad que toma el contenido del resultado del llamado asíncrono y inserta en el interior del componente especificado.

new Ajax.Updater(ID_COMPONENTE,
                 URL,
{
    parameters: $('FORMULARIO').serialize(true),
    method: 'post'
});

Utilizando el Request.

Esta opción es mas flexible que la anterior y permite manipular el contenido de la respuesta del llamado asíncrono.

new Ajax.Request(URL,
{
    parameters: $('FORMULARIO').serialize(true),
    method: 'post',
    onSuccess: function(transport)
    {
        // Hacer algo en éxito.
    },
    onFailure: function(transport)
    {
        // Hacer algo en fracaso.
    },
    onComplete: function(transport)
    {
        // Hacer algo al terminar.
    }
});

Utilizando JSON para el transporte.

El procedimiento es similar al anterior.  La diferencia es que la respuesta del llamado asíncrono viene empaquetada en un objeto JSON, diferente a la invocación anterior en la que se recibe como una cadena de texto.

new Ajax.Request(URL,
{
    parameters: $('FORMULARIO').serialize(true),
    method: 'post',
    requestHeaders:
    {
        Accept: 'application/json'
    },
    onSuccess: function(transport)
    {
        // Hacer algo en éxito.
        var json = transport.responseText.evalJSON(true);
        // var valorX = json.x;
    },
    onFailure: function(transport)
    {
        // Hacer algo en fracaso.
    },
    onComplete: function(transport)
    {
        // Hacer algo al terminar.
    }
});

Del lado del servidor, en PHP, el resultado final se debe encapsular en un objeto JSON antes de enviarlo al cliente.

echo "/*-secure-n";
echo json_encode($contacto -> toArray());
echo "n*/";
header('Content-type: application/json');
header("Status: 200 OK", false, 200);

En caso de error se debe retornar, al igual que en los demás casos, un mensaje cuyo tipo sea != 200.

header("Status: 400 Bad request", false, 400);

Obtener el valor de la selección de un grupo de radiobuttons con Prototype

Suponendo que se tiene el siguiente formulario se requiere determinar cual es el valor seleccionado en el grupo de radiobuttons utilizando las facilidades que ofrece Prototype.

<form id='formulario'>
    <b>Código</b> <input type='radio' id='opc1' name='opciones' value='vCodigo' />
    <b>Nombre</b> <input type='radio' id='opc2' name='opciones' value='vNombre' />
    <b>Documento</b> <input type='radio' id='opc3' name='opciones' value='vDocumento' />
</form>

Desafortunadamente no es posible realizar lo siguiente ya que el radiobuttongroup no es una entidad como tal sino un agrupamiento de las mismas, mas aún, no se referencia por su id sino por su name, motivo por el cual no funcionará con el getElementById.

resultado = $('opciones').value;

Por suerte Prototype es muy flexible y encontré dos soluciones diferentes para este problema que me parecieron muy interesantes, ambas en una sola instrucción compuesta.

La primera utiliza la búsqueda por selector para obtener los radiobuttons del documento que se encuentren seleccionados y que pertenezcan al radiobuttongroup elegido para posteriormente utilizar el método pluck para extraerle su atributo value.

resultado = $$('input:checked[type="radio"][name="opciones"]').pluck('value');

La segunda optiene los radiobuttons de un radiobuttongroup específico accediendo directamente al formulario que los contiene para posteriormente utilizar el método find que retornará al primer elemento encontrado y que se encuentre seleccionado.

resultado = $('formulario').getInputs('radio','opciones').find(function(radio) { return radio.checked; }).value;

Enlaces.

Ejemplo 2 de Ajax con Prototype y PHP

Mi interés en esta miniserie de artículos es la enseñar de manera fácil y didáctica las bases prácticas del desarrollo de aplicaciones web basadas en Javascript Asíncrono (o AJAX).  Para esto se utilizará la librería Prototype que facilitará la implementación de Javascript en el lado del cliente y PHP como lenguaje dinámico en el  lado del servidor, accediendo a una base de datos SQLite que se utilizará como capa de persistencia.

La serie de artículos se divide según cada una de las etapas del desarrollo de la aplicación de ejemplo, la cual consiste en un administrador de contactos muy simple.  Los capitulos mencionados a continuación comprenden la implementación del código XHTML, Javascript general, la creación de la base de datos, el código PHP para acceder a la base de datos y el acceso a la información mediante AJAX.

  1. La interfaz del usuario.
  2. Preparando el escenario con JavaScript.
  3. Estableciendo la persistencia.
  4. Creando el modelo de datos.
  5. Implementando las acciones con AJAX (I).
  6. Implementando las acciones con AJAX (II).

Cada uno de los artículos divide el código de la implementación del subtema que le compete para ser comentado paso a paso.  En el caso en que se prefiera dar un vistazo al código consolidado del capítulo se puede consultar al final de los artículos el producto final de la implementación allí realizada, así como descargar el código fuente de la aplicación implementada hasta el momento.

Espero que esta miniserie les sea de interés y utilidad, y que les permita conocer el desarrollo de aplicaciones web asíncronas mediante el uso de las herramientas elegidas.

Enlaces.

Ejemplo 2 de Ajax con Prototype: implementando las acciones con AJAX (II)

Introducción.

En este capítulo final se va a realizar la implementación de las acciones que permanecen pendientes.

  • Editar a un contacto.
  • Remover a un contacto.

Estas acciones requieren que se haya realizado con anterioridad la implementación de la lista y la carga de contactos para que el usuario tenga la posibilidad de ver los contactos existentes en la base de datos y de seleccionar uno específico sobre el cual se va a ejecutar la acción elegida.

Estas acciones estan basadas en Ajax.Request motivo por el cual su implementación es muy similar a la acción de agregar contactos y carecen de aspectos particulares para destacar.

Editando contactos.

En el lado del cliente.

Se actualiza la implementación de la función JavaScript enEditarRegistro en la cual se realizan las siguientes actividades.

  • Verificar que el contenido del campo oculto que almacena el ID del contacto que se va a editar no se encuentre vacío.
    if($('tId').value.strip().length == 0)
    {
        alert('Para editar un registro primero debe seleccionarlo.');

        return false;
    }
  • Realizar la invocación del llamado asíncrono con las siguientes características.
  • Como parámetros se envían los campos del formulario.
  • Si la invocación asíncrona termina exitosamente se muestra un mensaje y se actualiza el listado de contactos registrados para que se reflejen los cambios.
  • Si la invocación termina de manera fallida se muestra un mensaje indicando el error.
    new Ajax.Request('editar.php',
    {
        method:     'post',

        parameters: $('formulario').serialize(true),

        onSuccess: function(transport)
        {
            ponMensajeBien('<b>' + transport.responseText + '</b>');

            enActualizarBusqueda(null);
        },

        onFailure: function(transport)
        {
            ponMensajeMal('<b>' + transport.responseText + '</b>');
        }
    });

    return true;

En el lado del servidor.

La implementación se realiza en el archivo editar.php que se ubica en el directorio raíz de la aplicación web en el cual se desarrollan las siguientes actividades.

  • Establecer la conexión con la base de datos.
include('config.php');
include_once('basededatos.php');
include_once('contacto.php');

$bd = new BaseDeDatos(BaseDeDatos::crearDSN($bdInfo));
  • Obtener la nueva información del contacto enviada por el cliente.
$tId          = filter_var($_POST['tId'],          FILTER_SANITIZE_STRING);
$tNombres     = filter_var($_POST['tNombres'],     FILTER_SANITIZE_STRING);
$tApellidos   = filter_var($_POST['tApellidos'],   FILTER_SANITIZE_STRING);
$tCorreo      = filter_var($_POST['tCorreo'],      FILTER_SANITIZE_EMAIL);
$tFNacimiento = filter_var($_POST['tFNacimiento'], FILTER_SANITIZE_STRING);
  • Crear una instancia de la clase Contacto con la información recién recibida y realizar la actualización del contacto a través de ella.
$contacto = new Contacto();

$contacto -> ponId($tId);
$contacto -> ponNombres($tNombres);
$contacto -> ponApellidos($tApellidos);
$contacto -> ponCorreo($tCorreo);
$contacto -> ponFechaDeNacimiento($tFNacimiento);

$control = $contacto -> editar($bd);

$bd -> desconectar();
  • Enviar al cliente el mensaje informativo y el código HTTP apropiado según el tipo de terminación del proceso.
if($control > 0)
{
    echo utf8_encode("Registro editado");

    header("Status: 200 OK", false, 200);
}
else
{
    echo utf8_encode("El registro no pudo ser editado, inténtelo nuevamente");

    header("Status: 400 Bad request", false, 400);
}

Removiendo contactos.

Nuevamente el procedimiento es similar al anterior, se utiliza Ajax.Request.

En el lado del cliente.

  • Verificar que el contenido del campo oculto que almacena el ID del contacto que se va a remover no se encuentre vacío.
    if($('tId').value.strip().length == 0)
    {
        alert('Para remover un registro primero debe seleccionarlo.');

        return false;
    }
  • Realizar la invocación asíncrona de la acción consultando al archivo remover.php.
    new Ajax.Request('remover.php',
    {
        method:     'post',

        parameters: $('formulario').serialize(true),

        onSuccess:  function(transport)
        {
            ponMensajeBien('<b>' + transport.responseText + '</b>');

            enActualizarBusqueda(null);
        },

        onFailure:  function(transport)
        {
            ponMensajeMal('<b>' + transport.responseText + '</b>');
        }
    });

    return true;

En el lado del servidor.

  • Establecer la conexión con la base de datos.
include('config.php');
include_once('basededatos.php');
include_once('contacto.php');

$bd = new BaseDeDatos(BaseDeDatos::crearDSN($bdInfo));
  • Obtener la información del contacto enviada por el cliente, es de particular interés la información del campo tId.
$tId = filter_var($_POST['tId'], FILTER_SANITIZE_STRING);
  • Crear una instancia de la clase Contacto con la información recién recibida y realizar la remoción del contacto a través de ella.
$contacto = new Contacto();

$contacto -> ponId($tId);

$control = $contacto -> remover($bd);

$bd -> desconectar();
  • Enviar al cliente el mensaje informativo y el código HTTP apropiado según el tipo de terminación del proceso.
if($control > 0)
{
    echo utf8_encode("Registro removido");

    header("Status: 200 OK", false, 200);
}
else
{
    echo utf8_encode("El registro no pudo ser removido, inténtelo nuevamente");

    header("Status: 400 Bad request", false, 400);
}

Conclusiones.

En los últimos dos capítulos se realiza la implementación de los llamados asíncronos desde la interfaz del usuario (navegador web) utilizando JavaScript que son respondidos por las acciones implementadas en PHP.

Las implementaciones de Ajax hace uso de sus tres presentaciones:

  1. Ajax.Request: útil para realizar el llamado asíncrono, recibir la información de respuesta y realizar cierto grado de procesamiento sobre ella.  Utilizado para agregar, editar y remover contactos.
  2. Ajax.Updater: es una facilidad basada en el tipo anterior.  Su utilidad radica en que el mismo framework se encarga de desplegar la información recibida como respuesta del servidor en el componente especificado de manera automática.  Utilizado para mostrar el listado de los contactos registrados en el sistema.
  3. Ajax.Request con JSON: el involucrar JSON como formato para la respuesta recibida del servidor le permite al cliente realizar fácilmente cualquier procesamiento o transformación de esta información ya que es inmediatamente convertida a un objeto JavaScript con todas las ventajas que esto proporciona.  Utilizado para mostrar la información (cargar) del contacto seleccionado por el usuario.

Enlaces.

Ejemplo 2 de Ajax con Prototype: implementando las acciones con AJAX (I)

Introducción.

Para terminar este mini-tutorial se deben implementar las acciones que corresponden con los requerimientos pendientes de los capítulos anteriores.

La implementación de estas acciones se va a realizar del lado del servidor utilizando AJAX mediante Prototype y PHP y la infraestraestructura recién creada del lado del servidor.  Respecto a AJAX se van a implementar las tres modalidades que permite Prototype.

  1. Ajax.Request.  Realiza la solicitud asíncrona y recibe la respuesta del servidor permitendo manipularla y procesarla según se requiera.  Es posible determinar el éxito o fracaso de la comunicación con el servidor.
  2. Ajax.Updater.  Es un subcaso del método anterior.  Realiza el llamado asíncrono y actualiza automáticamente el contenido de un componente XHTML con la respuesta obtenida del servidor.
  3. Ajax.Request con JSON.  Realiza la solicitud asíncrona y recibe la respuesta del servidor en formato JSON facilitando su manipulación.

Si se reucerda las acciones que quedaron pendientes de implementación fueron las siguientes.

  • Agregar un registro.
  • Editar un registro.
  • Eliminar un registro.
  • Actualizar el listado de contactos.
  • Cargar un contacto específico.

La primera de las acciones que se va a implementar es la de agregar registros ya que le permitirá al usuario empezar a poblar la base de datos.  La implementación de cada acción incluirá modificaciones a los archivos del lado del cliente (JavaScript) y del lado del servidor (PHP).

Agregando registros.

En el lado del cliente.

Se debe actualizar el manejo del evento que sucede ante la solicitud del usuario de agregar un nuevo registro de un Contacto, para esto editamos el archivo jsfunciones.js y modificamos el contenido de la función enAgregarRegistro.

La función debe realizar las siguientes actividades.

  • Realizar las validaciones necesarias para garantizar que los datos se encuentran dispuestos para ejecutarse la acción solicitada.
    • Verificar que todos los campos tengan contenido, es decir, el contenido de ninguno de los campos puede ser vacío.
    var camposVacios = new Array();

    $('formulario').select('.CampoEstilo').each(function (elemento)
    {
        if(elemento.value.strip().length == 0)
        {
            camposVacios.push(elemento.title);
        }
    });

    if(camposVacios.length > 0)
    {
        alert('Los siguientes campos se encuentran vacíos,n' +
              'por favor complemente su información: nn' +
              camposVacios.toString());

        return false;
    }
  • Realizar el llamado asíncrono a la acción agregar.php para adicionar a la base de datos la información contenida en el formulario.
    • En caso de ser exitosa la ejecución de la acción se deberá mostrar en color verde (.MensajeBien) la respuesta obtenida del servidor y actualizar el listado de los clientes registrados donde se deberá reflejar la adición del nuevo registro.
    • En caso de ser fallida la ejecución, se deberá mostrar en color rojo (.MensajeMal).
    new Ajax.Request('agregar.php',
    {
        method:     'post',

        parameters: $('formulario').serialize(true),

        onSuccess: function(transport)
        {
            ponMensajeBien('<b>' + transport.responseText + '</b>');

            enActualizarBusqueda(null);
        },

        onFailure: function(transport)
        {
            ponMensajeMal('<b>' + transport.responseText + '</b>');
        }
    });

    return true;

En el lado del servidor.

Se define la implementación en el archivo agregar.php en el directorio raíz de la aplicación web.

Las actividades realizadas por esta acción se relacionan a continuación.

  • Establecer la conexión con la base de datos.
include('config.php');
include_once('basededatos.php');
include_once('contacto.php');

$bd = new BaseDeDatos(BaseDeDatos::crearDSN($bdInfo));
  • Obtener la información enviada por el cliente.  Esta información viene a través del método POST y los nombres de las variables suministradas corresponden con los nombres de los campos del formulario.
$tNombres     = filter_var($_POST['tNombres'],     FILTER_SANITIZE_STRING);
$tApellidos   = filter_var($_POST['tApellidos'],   FILTER_SANITIZE_STRING);
$tCorreo      = filter_var($_POST['tCorreo'],      FILTER_SANITIZE_EMAIL);
$tFNacimiento = filter_var($_POST['tFNacimiento'], FILTER_SANITIZE_STRING);
  • A partir de la información recién obtenida se crea una instancia del objecto Contacto y almacena su información utilizando su método agregar.
$contacto = new Contacto();

$contacto -> ponNombres($tNombres);
$contacto -> ponApellidos($tApellidos);
$contacto -> ponCorreo($tCorreo);
$contacto -> ponFechaDeNacimiento($tFNacimiento);

$control = $contacto -> agregar($bd);

$bd -> desconectar();
  • Según el resultado de la operación (valor de $control) se define si la ejecución fue exitosa o fallida y se envía al cliente el mensaje y código HTTP apropiado.
if($control > 0)
{
    echo utf8_encode("Registro agregado");

    header("Status: 200 OK", false, 200);
}
else
{
    echo utf8_encode("El registro no pudo ser agregado");

    header("Status: 400 Bad request", false, 400);
}

Listando contactos registrados.

Esta acción permitirá que se verifique si efectivamente la adición de registros anterior se encuentra funcionando correctamente o no al desplegar en la interfaz (6) el listado de contactos existente en la base de datos de acuerdo con el filtro de búsqueda seleccionado.

En el lado del cliente.

La misión de esta acción es la de actualizar al div Resultados con la información de la base de datos de acuerdo con los criterios contenidos en los campos sLetra y sCampo.  Se utiliza el Ajax.Updater para este fin.

    new Ajax.Updater('Resultados',
             'listar.php',
             {
                parameters: $('sLetra').serialize(true) + "&" + $('sCampo').serialize(true),

                method: 'post'
             });

En el lado del servidor.

Se realiza la implementación del archivo listar.php en el cual desarrollan las siguientes actividades.

  • Establecer la conexión con la base de datos.
include('config.php');
include_once('basededatos.php');
include_once('contacto.php');

$bd = new BaseDeDatos(BaseDeDatos::crearDSN($bdInfo));
  • Obtener el valor del campo sCampo y verificar que sea válido, es decir, sea nom o ape.
$campos = array('nom' => 'nombres',
                'ape' => 'apellidos');

$sCampo = filter_var($_POST['sCampo'], FILTER_SANITIZE_STRING);

if(!isset($campos[$sCampo]))
{
    echo utf8_encode("<span class='MensajeMal'>Los parámetros de búsqueda especificados son inválidos.</span>");

    header("Status: 400 Bad request", false, 400);

    exit;
}
  • Obtener el valor del campo sLetra.
$campo = $campos[$sCampo];

$sLetra = filter_var($_POST['sLetra'], FILTER_SANITIZE_STRING);
  • Crear la condición de filtro de búsqueda y obtener el listado de los Contactos que cumplen con dicho criterio.
$letra1 = (($sLetra == 'todos' ) ? "" : strtoupper($sLetra[0])) . "%";
$letra2 = (($sLetra == 'todos' ) ? "" : strtolower($sLetra[0])) . "%";

$where = $campo . " LIKE '{$letra1}' OR " . $campo . " LIKE '{$letra2}'";

$listado = Contacto::listar($bd, $where);
  • Generar la presentación del listado (XHTML) para ser enviado hacia el cliente para que sea ubicado en el contenedor apropiado de la página web.
echo "<table><tbody>";

echo "<tr><td class='RegistroTitulo'>Apellidos</td>" .
     "<td class='RegistroTitulo'>Nombres</td>" .
     "<td class='RegistroTitulo'>Correo</td>" .
     "<td class='RegistroTitulo'>FNacimiento</td></tr>";

foreach($listado as $registro)
{
    $id          = $registro['id'];
    $nombres     = urldecode($registro['nombres']);
    $apellidos   = urldecode($registro['apellidos']);
    $correo      = urldecode($registro['correo']);
    $fnacimiento = urldecode($registro['fnacimiento']);

    $e1 = "<a href='#' onClick='enCargarRegistro({$id}); return false;'>";
    $e2 = "</a>";

    echo "<tr><td class='RegistroListado'>{$e1}{$apellidos}{$e2}</td>" .
         "<td class='RegistroListado'>{$e1}{$nombres}{$e2}</td>" .
         "<td class='RegistroListado'>{$e1}{$correo}{$e2}</td>" .
         "<td class='RegistroListado'>{$e1}{$fnacimiento}{$e2}</td></tr>";
}

echo "</tbody></table>";

$bd -> desconectar();

Cargando registros.

El usuario puede seleccionar a uno de los Contactos registrados haciendo clic sobre sus datos en el componente (6), esta acción invoca a la función enCargarRegistro que conociendo el ID del Contacto debe obtener toda su información para ser desplegada en el formulario apropiado.

Esta acción requiere poder manipular de manera discreta e individual a la información retornada por el servidor ya que cada valor corresponderá con un campo diferente del Contacto seleccionado, lo cual es diferente a por ejemplo la acción anterior, la obtención del listado de Contactos, en la cual todo lo obtenido del servidor (XHTML) es transferido directamente y sin procesamiento a un div específico; por este motivo se involucrará el uso de JSON en la respuesta del llamado asíncrono.

En el lado del cliente.

  • La función enCargarRegistro recibe el ID del Contacto a obtener el cual se convierte en parámetro para la acción recuperar.php.
    new Ajax.Request('recuperar.php',
    {
        parameters: 'id=' + id,

        method: 'post',
  • Se especifica que el resultado de esta acción deberá ser del tipo Application/JSON.
        requestHeaders:
        {
            Accept: 'application/json'
        },
  • En caso de fracasar el llamado asíncrono se mostrará un mensaje indicándolo.
        onFailure: function(transport)
        {
            ponMensajeMal('<b>No fue posible recuperar el registro ' + id + '</b>: ' + transport.responseText);
        }
  • En caso de tener éxito el llamado asíncrono se ejecutarán las siguientes actividades.
  • Se evalúa la respuesta del servidor como un objeto JSON convirtiéndo la respuesta en un objeto JavaScript.
            var json = transport.responseText.evalJSON(true);
  • Se llenan los camps del formulario con la información recibida del servidor.
            $('tId').value          = json.id;
            $('tNombres').value     = json.nombres;
            $('tApellidos').value   = json.apellidos;
            $('tCorreo').value      = json.correo;
            $('tFNacimiento').value = json.fechaNacimiento;
  • Se modifica la acción del formulario a Editar ya que se cuenta con un registro seleccionado.
            $('bAccion').value = 'Editar';
  • Se muestra un mensaje de éxito.
            ponMensajeBien('<b>Registro recuperado: ' + json.id + '</b>');

En el lado del servidor.

La lógica de la acción se implementa en el archivo recuperar.php ubicado en la raíz de la aplicación web y en ella se desarrollan las siguientes actividades.

  • Establecer la conexión con la base de datos.
include('config.php');
include_once('basededatos.php');
include_once('contacto.php');

$bd = new BaseDeDatos(BaseDeDatos::crearDSN($bdInfo));
  • Obtener el identificador del Contacto enviado desde el cliente.
$tId = filter_var($_POST['id'], FILTER_SANITIZE_STRING);
  • Crear una instancia de la clase Contacto y a través de ella recuperar la información del contacto especificado por el usuario.
$contacto = new Contacto();

$control = $contacto -> recuperar($bd, $tId);

$bd -> desconectar();
  • A partir de la respuesta obtenida ($control) determinar si la acción fue realizada exitosa o fallidamente y realizar los procedimientos apropiados para informárselo al cliente.
  • En caso de éxito:
    • Enviar al cliente el objeto resultante en formato JSON.
    • Informar al cliente que el tipo de contenido enviado es Application/JSON.
    • Enviar el código HTTP de éxito.
if($control === true)
{
    echo "/*-secure-n";

    echo json_encode($contacto -> toArray());

    echo "n*/";

    header('Content-type: application/json');

    header("Status: 200 OK", false, 200);
}
  • En caso de fracaso:
    • Enviar al usuario el motivo del error con un mensaje informativo.
    • Enviar el código HTTP de fracaso.
else
{
    echo utf8_encode("El registro no pudo ser agregado");

    header("Status: 400 Bad request", false, 400);
}