Realidad IT
21ene/1010

Una aplicacion web full ajax, debe manejar los botones de navegación y favoritos, te explico como

VN:F [1.9.17_1161]
Votos: +9

Creo que hay que saber que cuando uno decide encarar el desarrollo de un sitio, o aplicación web, implementar ajax no es simplemente tomar una API de javascript y usarla. Hay factores muy importantes a tener en cuenta, y conviene encararlos antes de iniciar el desarrollo porque una vez que la web app esté lista se va a tornar mas dificil realizar los cambios, lo positivo es que las consideraciones no son tantas:

  1. Debe funcionar el Historial (Back & Foward).
  2. Se deben poder guardar secciones en Favoritos, parece tonto lo que digo, pero cuando se actualiza una parte de una página, la URL no cambia, y si yo quiero guardar el estado actual no voy a poder.
  3. Debo tener claro que vínculos u onclicks llevaran a una recarga completa o solo la recarga de una sección.
  4. Debo tener una sola función que se dedica a hacer los envíos sincrónicos
  5. Debo tener cuidado con los plugins que voy agregando que no afecten a la navegación.
  6. Especial cuidado con el envío de formularios (submits)

La mayoría de los puntos mencionados tienen que ver con que por desgracia los navegadores no registran los cambios de una porción de una página en el historial y eso hace que que la funcionalidad básica del buscador no funcione y que los usuarios avanzados de internet se terminen frustrando al usar tu sitio, imaginate que si estoy en Facebook, estoy viendo fotos y de repente quiero volver a ver la anterior, preciono el botón Back del navegador y me lleva a Yahoo por ejemplo, no estaría bien, no?

La mayoría de los plugins que implementan ajax tienen por lo menos una extensión que maneja dicha navegación. Por ejemplo para los que usan JQuery, existe el plugin jquery.history.js

Voy a explicar como funciona dicho plugin brevemente, porque aunque parece una cosa facil, es bastante confuso cuando uno pone manos en la masa:

Para empezar, el plugin registra la página agregando un link con un anchor de seccion "#" a cada link que requiera ser registrado en el historial. Esto se logra llamando a la siguiente función en el evento onclick

     $.historyLoad(href);

Hasta acá viene fácil, de hecho, yo pensé que eso era todo, pero que pasó? A pesar de que quedan todas mis acciones registradas en el historial, cuando le daba al botón back, siempre apareciá la misma página, no me traía el contenido anterior.

El plugin registraba en el historia los anchors pero no el contenido. Por lo tanto, tuve que agregar un código que cuando uno presionaba back se recarga la sección que queremos ver, esto el plugin lo permite hacer utilizando una callback function.

$.historyInit(pageload, "index.php");

function pageload(hash) {
//la siguiente línea llama a mi funcion ajax, el hash son los parametros a enviar
     HistoryBackContentLoader(hash);
}

Acá les muestro la solución completa que armé para que puedan unir las piezas:

function pageload(hash) {
 HistoryBackContentLoader(hash);
}

$(document).ready(function(){
     $.historyInit(pageload, "index.php");
});

function HistoryBackContentLoader(parametros)
{
     $('#ajaxcontent').attr("innerHTML", "");
 $('body').css('cursor','wait');

     $.ajax({
          async:     true,
          success: resultadoDetalleOK,
          data:      parametros,
          url:   "ajax_accion.php",
          type:      "post",
          dataType:  "json"
     });
     return false;
};

function resultadoDetalleOK(responseText) {
     $('body').css('cursor','default');
     var oMensaje = $('#ajaxcontent');
     if (responseText.Ok)
     {
          mostrarMensaje(oMensaje, responseText.Datos);
          AnchorLink('#ajaxcontent a');
          AnchorLink('.historial');
     }
     else
     {
          responseText.Mensaje = 'Lo sentimos. NO se han podido obtener los datos.';
          mostrarMensaje(oMensaje, responseText.Mensaje);
     }
}

function AnchorLink(id)
{
     $(id).each(function() {
          if( $(this).attr('href') ) {
               var aHREF = $(this).attr('href').split('?');
               if(aHREF.length > 1) {
                    $(this).attr('href', $(this).attr('href') + "#" + aHREF[1]);
                    $(this).click(function(){
                         $.historyLoad(aHREF[1]);
                         return false;
                    });
               }
          }
     });
}

Si vieron el código y lograron comprenderlo, podrán ver que la función AnchorLink que escribí, aplica el $.historyLoad a aquellos objetos que me interesan que queden guardados en el historial. Estos son: '#ajaxcontent a': Todos los links cargados dinamicamente y '.historial' todos los objetos que tengan definida la clase historial, estos pueden ser "div" pero entonces para que funcione tienen que agregarle al div una propiedad href (no estandar) que indica la url destino.

Adicionalmente, para saber que información es la que se debe recargar, guardo en el "#" los mismos parámetros del pedido original, por ejemplo, si dinamicamente llamo a index.php?lang=es&photos=yes, la url con historial sería index.php?#lang=es&photos=yes

Espero que les haya servido, éxito con sus páginas!

Publicado por Santiago Cattaneo

Comentarios (10) Trackbacks (0)
  1. hola esta muy bien … pero no tendras algun ejemplo en practica?? o alguna pagina que este utilizando este scrip?

    • Gregorio,

      Hay dos partes en el historial, por un lado guardar el historial y en el otro “cachearlo” o sea almacenarlo en el equipo del usuario para no recargar la página.

      Nosotros lo implementamos en un cliente que para preservar la confidencialidad no podemos decirlo. Pero este código se empleó en una página productiva con un promedio de 1000 visitas diarias.

      Saludos.

  2. Ok Matías, muchas gracias.- Yo por mi cuenta, estoy aprovechando estos días de “vacaciones” para hacer un rato matutino de investigación, antes de ir a la playa con la familia, pero no logro avanzar nada. He probado mezclar con otros ejemplos ajax, cambiar, quitar, poner, inventar … y ahí vamos.
    De nuevo, muchas gracias. Espero colaborar también en lo que pueda.
    Un saludo desde mi paraíso vacacional en Almeria (españa).

  3. @gamez, vamos a tratar de ponerte algunos archivos para que descargues (como para que tengas el ejemplo completo), el problema es que tenemos que modificar los que hicimos para un cliente por temas de confidencialidad y no sé si Santiago anda con tiempo o tiene los fuentes de este ejemplo, pero en cuanto pueda, aunque sea yo, te los paso, es una promesa.

  4. Hola de nuevo:
    He estado trabajando en tu ejemplo y nada, no consigo que funcione. Yo tengo una web desarrollada en ajax, pero no consigo aplicarle las mejoras que tu explicas aquí. ¿Tendrías a mano algunos archivos de ejemplo para descargar y analizar?
    Gracias.-

  5. Hola, me parece que esta muy bueno…
    Voy a probar con una pequeña aplicación tu codigo..

    saludos..

  6. Hola como estas, te respondo a tus dudas, entiendo que el codigo no es simple, a mi no me resulto simple, asi que si alguien sabe de una forma mejor de resolverlo, bienvenido sea:

    1) El archivo “ajax_accion.php” devuelve el contenido que se va a refrescar en la pagina, podria devolver un HTML o un objeto lleno de informacion que despues lo metes dentro de un snippet HTML que ya tenga la pagina y lo mostras.

    2) No estoy seguro de entender esta pregunta, pero calculo que te referis a si vas a realizar una actualización completa de la pagina, no? En ese caso a tu link no le pones la “class” “historial” entonces podes realizar una carga completa.

    Saludos

  7. Hola: Felicidades por tu exposición, creo que está bien documentada, aunque tengo algunas cosas no las entiendo bien y te agracedería que me ayudases.

    He intentado crear una página sencilla para practicar con tu ejemplo, pero no acabo de entender bien las siguientes partes:
    1) ¿El archivo “ajax_accion.php” se encarga de recoger las variables url? ¿cual es su funcion exactamente?
    2) Los links para cargar las paginas externas sería: Pagina1

    De nuevo gracias por tu articulo. Un saludo.


Leave a comment

(required)

Aún no hay trackbacks.