Prototype: Ajax

Visita este artí­culo en http://www.estadobeta.com/2006/10/10/prototype-ajax/

Por Ismael en Desarrollo, artículos, destacados, javascript

Construyendo aplicaciones Ajax con la librería Prototype.js

Actualización: ahora se encuentra disponible la documentación completa y extensiva de Prototype (en inglés).

Hemos visto suficiente de la librería Javascript Prototype como para entrar de lleno en una de sus utilidades más… Estee… útiles: Ajax (si no sabes qué es Prototype lee este y este artículo).

Ajax, para los que no lo sepan, es una técnica para cargar datos o fragmentos de HTML sin refrescar la ventana del browser. Introducido por Microsoft para coordinar su browser Internet Explorer con aplicaciones de escritorio como Outlook, la tecnología es actualmente implementada por todos los browsers contemporáneos. El problema es que, mientras que IE usa un objeto ActiveX propietario de Microsoft, el resto usa la interfaz XMLHttpRequest, implementada por Mozilla en 2002 y seguida por los demás fabricantes. Esto significa que para hacer una transferencia de datos via Ajax, es necesario revisar la implementación del navegador y usar el objeto correspondiente.

Por fortuna, el objeto Ajax de Prototype hace ese trabajo por nosotros. Ajax (el de prototype) define una serie de clases y métodos que abstraen la detección de browser y nos dan una interfaz sencilla para cargar datos desde el servidor y actualizar elementos HTML en el documento.

Sigue leyendo para ver sabrosos detalles y código.

Ajax.Request

La clase Ajax.Request recibe una URL a la cual enviar datos. Opcionalmente, recibe una lista de opciones.

Code (javascript)
  1. var url = "http://www.mi-servidor.com/procesa-ajax.php";
  2. var pars = "param1=1&param2=34";
  3. var ajax = new Ajax.Request( url, {
  4.                                 parameters: pars,
  5.                                 method:"get",
  6.                                 onComplete: procesaRespuesta
  7.                                 }
  8. );

Vamos por partes.

El primer parámetro es claro: la url debe estar en el mismo dominio que el documento haciendo el request. Esto es una restricción de los browsers para evitar el Cross Site Scripting (manipular documentos de otros sitios con javascript, o robar datos como claves o tarjetas de crédito).

Veamos la lista de opciones, que debe ser un objeto de pares nombre:valor.

parameters
Una cadena de texto con los parámetros a enviar al servidor, formateados como una URL (”parametro1=valor1&parametro2=valor2″, etc)
method
El método para enviar los datos. “get” envía los datos como parámetros de la URL
(”http://www.servidor.com?param1=valo1&param2=valor2″). “post” envía los datos en el encabezado del request.
Puedes usar cualquiera, pero la regla es que si tu request modifica datos el servidor, usa “post”. Si sólo estas
solicitando una respuesta, usa “get”*1. Si no incluyes este parámetro, Ajax.Request usa “post” por
defecto.
onComplete
Referencia a una función que se ejecutará una vez que el servidor haya
respondido con éxito. La función debe recibir un argumento: el objeto XMLHTTPRequest con los datos entregados por
el servidor.

El último argumento de las opciones es donde manejamos la respuesta del servidor. Para el
ejemplo anterior invocamos una función llamada procesaRespuesta, que definimos a continuación.

Code (javascript)
  1.  
  2. function procesaRespuesta( resp ){
  3.         /* resp es un objeto XMLHTTPRequest
  4.         resp.responseText es la respuesta en formato texto (puede ser html)
  5.         resp.responseXML es la respuesta en formato XML */     
  6.         $("div-contenidos").innerHTML = resp.responseText;
  7. }

En el ejemplo usamos el atributo responseText del objeto de respuesta para actualizar los contenidos de un DIV de id “div-contenidos”.

Code (html)
  1. <body>
  2.         <div id="div-contenidos"></div>
  3. </body>
  4.  

En aplicaciones más complejas podríamos cargar datos en formato XML. En ese caso utilizaríamos el atributo responseXML de la respuesta y las diversas funciones del DOM de Javascript.

Code (javascript)
  1.  
  2. function procesaRespuesta( resp ){
  3.         var e = resp.responseXML.firstChild;//primer nodo XML de la respuesta
  4.         while(e != null){
  5.                 procesaNodo( e );//haz algo con cada nodo
  6.                 e = e.nextSibling;
  7.         }
  8. }
  9.  

Pero, normalmente, Ajax es usado simplemente para actualizar el contenido de elementos HTML (como en el primer ejemplo). Prototype tiene otra clase, Ajax.Updater que usa Ajax.Request internamente para hacer el proceso aún más sencillo.

Ajax.Updater

Además de la URL, Ajax.Updater recibe la id del elemento HTML cuyo contenido reemplazar por la respuesta del servidor.

Code (javascript)
  1.  
  2. function getHTML(){
  3.         var url = ‘http://mi-servidor.com/produceHtml.php’;
  4.         var pars = ‘unparametro=ABC’;
  5.         var myAjax = new Ajax.Updater( ‘div-contenido’, url, { method: ‘get’, parameters: pars });
  6. }
  7.  

Code (html)
  1. <input type=button value="GetHtml" onclick="getHTML()"/>
  2. <div id="div-contenido"></div>
  3.  

La función getHTML() que definí crea una instancia de Ajax.Updater que carga el HTML generado por la URL dentro del DIV “div-contenido”. En el HTML del documento definimos un botón que invoca a la función getHTML() al apretarlo. Cada vez que presionemos el botón, el DIV “div-contenido” actualizará su contenido según los datos enviados por el servidor.
Si no te importa tener tus documentos llenos de Javascript, bastaría con lo siguiente en tu página:

Code (html)
  1. <input type=button value="GetHtml"
  2. onclick="new Ajax.Updater( ‘div-contenido’, ‘/produceHtml.php’ )"/>
  3. <div id="div-contenido"></div>
  4.  

Un ejemplo: comentarios Ajax

Para la mayoría de los casos, Ajax.Updater provee todas las funcionalidades Ajax que necesitas. Imaginemos un formulario para dejar comentarios en un blog, via Ajax. Este tipo de formularios tienen las ventajas de disminuír el Spam (los spiders o programas de spam no pueden interpretar código Javascript arbitrario y por lo tanto no saben cómo enviarte comentarios por esta via) y, por sobre todo, hacen que tu sitio sea lo más cool y “Web 2.0″ del barrio ;)

Primero, el formulario (incluyo sólo el HTML imprescindible, por brevedad).

Code (html)
  1. <div id="nuevo-comentario"></div>
  2. <form action="" onSubmit="comentarioAjax()">
  3.         <input type="text" name="nombre" id="nombre" />
  4.         <input type="text" name="email" id="email" />
  5.         <textarea name="comentario" id="comentario"></textarea>
  6.         <input type="submit" value="Enviar!" />
  7. </form>

Dos cosas: al presionar el botón de envío, se ejecutará la función comentarioAjax() asociada al evento onSubmit del formulario. Esta función, que definiré en un momento, obtendrá el valor de cada campo según el id de cada uno, usando el método $F() de Prototype. Esta función también define la URL a donde enviar los comentarios *2 y un DIV donde mostrar el nuevo comentario una vez enviado.

Code (javascript)
  1.  
  2. function comentarioAjax(){
  3.         var nombre            = $F("nombre");
  4.         var email              = $F("email");
  5.         var comentario  = $F("comentario");
  6.         var url   = "/envia-comentario.php";
  7.         //
  8.         var params            = "nombre="+nombre+"&email="+email+"&comentario="+comentario;
  9.         //
  10.         var ajx = new Ajax.Updater("nuevo-comentario",
  11.                                                 url,
  12.                                                 {method:"post",
  13.                                                 parameters:params}
  14.                                         );
  15. }

Eso envía los datos al archivo /envia-comentario.php en el servidor e inyecta cualquier cosa que este responda en el DIV “nuevo-comentario”. Este es un ejemplo del archivo PHP que procesa los datos e imprime el HTML para el resultado

Code (php)
  1. < ?php
  2. /* envia-comentario.php */
  3. $nombre = $_POST[‘nombre’];
  4. $email = $_POST[‘email’];
  5. $comentario = $_POST[‘comentario’];
  6. /*
  7. // funcionPhpParaGuardarComentario( $nombre, $email, $comentario );
  8. /* Imprime resultado de vuelta al browser */
  9. ?>
  10. <p>Nuevo comentario de < ?php echo $nombre ?>:</p>
  11. <div class="comment-body">< ?php echo $comentario ?></div>
Actualización: Prototype 1.5.1 incorpora a los formularios un método request que, básicamente usa Ajax.Request pero aprovechando los atributos action y method del formulario HTML. Esto permite hacer lo mismo con menos duplicación de código. Más info en la documentación de Prototype. Ejemplo en New Bamboo.

CallBacks

Pero queremos más control sobre la secuencia de pasos entre enviar y recibir los datos. Por ejemplo mostrar un mensaje en la parte superior de la página para hacer más claro que ha ocurrido un cambio o mostrar un mensaje distinto en caso de error.

Ajax.Base (módulo usado por Ajax.Request y Ajax.Updater) permite el uso de callbacks, o funciones que se ejecutan ante determinados eventos. En la primera parte de este artículo vimos el callback onComplete, que se dispara cuando se completa la transacción con éxito. En el ejemplo de nuestro formulario ajax, usemos onComplete para mostrar un mensaje oculto cuando se agregue el nuevo comentario.

Code (html)
  1.  
Code (javascript)
  1. /* en Javascript: */
  2. function comentarioAjax(){
  3.         /*… etc, etc … */
  4.         var ajx = new Ajax.Updater("nuevo-comentario",
  5.                                                 url,
  6.                                                 {method:"post",
  7.                                                 parameters:params,
  8.                                                 onComplete:muestraMensaje}
  9.                                         );
  10. }
  11. // callback para onComplete.
  12. // Recibe objeto de respuesta que en este caso no usamos.
  13. function muestraMensaje( resp ){
  14.         $("mensaje").show();
  15. }

Por supuesto, podríamos haber pasado una función anónima como argumento.

Code (javascript)
  1.  
  2. onComplete: function( resp ){$("mensaje").show()}

Otros callbacks son

onFailure
Se ejecuta en caso de haber un error por parte del servidor (por ejemplo un error 500).
onLoaded
Se ejecuta una vez que los datos del servidor son cargados en el browser pero antes de procesar la respuesta.
onSuccess
Lo mismo que onComplete (¿correción?).
onException
Se ejecuta en caso de haber algún error de javascript en el cliente, por ejemplo si la respuesta es inválida o no se pasa el numero apropiado de argumentos a la función.

Pueden ver más detalles en la documentación no-oficial de Prototype.

Responders

Ahora supongamos que queremos hacer más antes y despues de enviar los datos al servidor. Por ejemplo mostrar el clásico gif animado mientras se efectúa el envío (esto te hará tu sitio verdaderamente in!), y apagarlo una vez que éste termine. Podríamos hacer esto utilizando callbacks: mostramos el gif al iniciar la transacción y lo apagamos al finalizar por medio del callback onComplete. Pero Prototype provee una solución mucho más elegante. Los Responders son callbacks globales que escuchan cualquier operación Ajax en tu documento. Esto permite definir una sola vez el comportamiento de nuestro gif animado para cualquier funcionalidad Ajax que queramos implementar.

Code (html)
  1. <!– HTML: gif animado escondido –>
  2. <div id="cargando" style="display:none"><img src="spinner.gif" />Cargando…</div>
  3.  

Code (javascript)
  1. /* Javascript: se define un objeto con callbacks globales */
  2. var globalCallbacks = {
  3.                 onCreate: function(){
  4.                         $(‘cargando’).show();
  5.                 },
  6.  
  7.                 onComplete: function() {
  8.                         if(Ajax.activeRequestCount == 0){
  9.                                 $(‘cargando’).hide();
  10.                         }
  11.                 }
  12.         };
  13. /* Se registran los callbacks en Ajax.Responders */
  14. Ajax.Responders.register( globalCallbacks );

El objeto de callbacks debe definir los métodos onCreate y onComplete, que se ejecutarán al iniciar y finalizar las transacciones Ajax, respectívamente. Estos métodos no reciben argumentos. ¿se fijan en la línea Ajax.activeRequestCount == 0? Esto indica que el gif animado no se apagará hasta que todas las transacciones ajax activas hayan finalizado.

Colofón

El objeto Ajax de Prototype y sus derivados es especialmente adecuado para aplicaciones que requieren un alto grado de control sobre cada transacción, debido a la claridad de su diseño y la versatilidad del sistema de callbacks y responders. Esto es más evidente en programas que utilizan además otras librerías como Script.aculo.us en combinación con Ajax para interfaces de alta interactividad.
Para simples actualizaciones de contenidos y efectos simples puede ser conveniente usar otras librerías con servicios Ajax como jQuery, especialmente liviana y fácil de usar (aunque no tanto de extender).

De acuerdo a la recepción de este artículo, publicaré ejemplos de funciones más avanzadas y las diversas aplicaciones de Ajax en el desarrollo de aplicaciones Web - y donde no usar la tecnología.

*1
Los parámetros codificados en la URL pueden ser guardados en los favoritos del browser o seguidos por los buscadores. Claramente no queremos una dirección que modifique o elimine datos importantes de tan fácil acceso.
*2
El archivo que recibe los valores del comentario debiera implementar la lógica necesaria para efectuar la operación (enviar un email al administrador, guardar el comentario en una base de datos, etc).Si no sabes cómo hacer eso propongan el tema como un nuevo post en los comentarios de este artículo.

112 comentarios para “Prototype: Ajax”

  1. Gravatarwachunei Dice:

    ay me queda tanto por aprender…

  2. GravatarIsmael Dice:

    Wachunei, este artículo por tratar de ser completo puede parecer muy complejo. Baste con saber que si quieres cargar el contenido de una página o script dentro de un elemento mediante Ajax, puedes hacer esto:

    
    <a hfer="/contenido-externo.php" onClick="new Ajax.Updater( 'contenido', '/contenido-externo.php' );return false;">Link Ajax!</a>
    
    <div id="contenido"> ... </div>
    
    
  3. Gravatarmeneame.net Dice:

    Uso de Ajax con Prototype.js

    Completo artículo en español sobre la implementación de Ajax con la librería Javascript Prototype.js, con ejemplos y código.

  4. Gravatardefmay { Primeros Pasos con AJAX } Dice:

    […] jQuery tiene un buen soporte para AJAX, pero el enfoque que le da Prototype me parece mucho mas sencillo y útil para quien está empezando y sobretodo para los que venimos de una sintaxis simple como la de PHP. Hoy me tope con un muy buen artículo de EstadoBeta que explica muy claramente como dar los primeros pasos en está tecnología. […]

  5. Gravatarvladimir prieto Dice:

    excelente! preciso y conciso. me gustó.

    un detalle/pregunta/duda.

    tengo entendido que el uso de get y post tienen otra gran diferencia además de las que mencionas. get no maeneja tanta informacion como post, de hecho me pasó en una oportunidad que al cambiar de get a post me funcionó el envío de un formulario gigante, cosa que con get no me funcionaba.

    favor corregir en caso que me equivoque.

  6. GravatarIsmael Dice:

    Vladimir: en teoría no hay límite para lo que puedes enviar por GET, pero eso puede depender tanto del browser como del servidor. Dicho esto, GET sólo debiera ser usado para obtener información del servidor (por eso el nombre “get”). Para eso usualmente no se necesita demasiada información en los parámetros (lo común es incluir un identificador del elemento que quieres obtener, por ejemplo “/index.php?id=234″).
    POST envía los datos en un header separado al servidor, y se usa para modificar datos en el servidor (actualizar, crear, eliminar). Recuerda que los parámetros enviados por GET quedan en el historial del browser y son accesibles por los robots de los buscadores. Nadie quiere una URL como “/index.php?accion=eliminar&id=234″ tan fácil de encontrar!

    En este (largo y en inglés) documento de la W3C puedes encontrar más información sobre el tema.

  7. GravatarHector Vergara R. Dice:

    Isma: en efecto, los datos por POST son enviados en el body del request, no en un header.

    Ej.

    GET /index.php?var1=bla&var2=blo&var3=bli HTTP/1.0
    Host: www.blablabla.com


    POST /index.php HTTP/1.0
    Host: www.blablabla.com
    Content-Length: (largo del texto de abajo, incluidos los newlines)


    var1=bla&var2=blo&var3=bli

  8. GravatarRodrigo Dice:

    Excelente artículo! simplemente genial.

  9. Gravataramor Dice:

    Estoy teniendo problemas para descargar la libreria prototype de http://prototype.conio.net/ ¿saben de algún otro sitio que esté actualizada?
    Un saludo a todos, gracias

  10. Gravatarfarlopex Dice:

    Magnífico artículo!

    Yo añadiría a los callbacks el evento onLoading

    La diferencia entre onSuccess y onComplete, creo que es la siguiente:
    - onSuccess, se lanza cuando la operación ha sido correcta.
    - onComplete, se lanza cuando la oparación ha terminado.

    Podemos decir que el evento onSuccess es el contrario de onFailure.

    OTROS EVENTOS:

    - on404, claro ¿no? :-)
    - onLoading, similar a onCreate. ¿diferencias?

    ES MUY INTERESANTE…

    El objeto new Ajax.PeriodicalUpdater(’micapa’, ‘datos.php’, {asynchronous:true, frequency:2}); para actualizar contenidos cada cierto tiempo de forma muy sencilla. Naturalmente, pueden utilizarse los callbacks :-)

  11. GravatarIsmael Dice:

    Farlopex: excelente aporte, muchas gracias!
    Claro, onComplete se dispara una vez terminada la transferencia (con o sin error). De hecho se puede hacer:

    
    onComplete: {success:funcExito, failure:funcError}
    
    
  12. Gravatarcarlos Dice:

    hola

  13. GravatarRodrigo Dice:

    Ismael: y qué pasa con el callback ‘onLoading’?? He probado tu forma de hacerlo con ‘Ajax.Responders.register( globalCallbacks );’ y me funciona mejor. Creo que si usas onLoading, tienes que usar onCreate y onComplete también. O no?

  14. GravatarGodskyller Dice:

    Ismael, muy buen articulo, te permite entrar rápidamente a AJAX sin mucho lio. Desafortunadamente lo encuentro despues de haber batallado un poco ….:(

    Aprovecho para preguntarte si conoces alguna forma que no sea tan talachera para llenar una tabla a partir de un Ajax.request… Por ejemplo.

    function ajax_validaRegistro()
    {
    var url = '../ajaxProcesor';
    var pars = "ID=REGISTRO";
    pars += "&IDREG=" + $F('hidRegistro');
    var myAjax = new Ajax.Request( url, { method: 'post', parameters: pars, onComplete: ajax_procesaRespuesta });
    }


    function ajax_procesaRespuesta(originalRequest)
    {
    //Recupera respuesta
    var lsRegreso = originalRequest.responseText;
    // En mi caso el resultado de la respuesta
    //son varios campos separados por "|"
    try
    {
    var laRegreso = lsRegreso.split("|");
    //Generar DHTML Tabla Dinamica
    }
    catch(e){};

    }

  15. Gravatargiovanny Dice:

    hola, estoy empezando a implementar AJAX, y pues no tengo muchos conocimientos en esto, pero tengo una pregunta/inquietud/duda/problema (de antemano disculpas si es muy tonto). La situacion es la siguiente: Tengo un formulario y tiene varios campos, pero tengo uno que es una identificacion de una persona(cedula), y necesito que al digitar en este campo un valor y perder el foco(onblur), me consulte en la BD para ver si existe registro de esta persona, en caso afirmativo mostrar los datos, pero en caso negativo, mostrar los campos vacios para que sean llenados. Al finalizar esto debe ser enviado la totalidad de los campos del formulario, y si esa persona no esta registrada en la BD entonces crearle el registro.

    espero que me alla echo entender. ¿puedo cambiar los campos dentro de un formulario con AJAX(agregar y quitar campos), y al enviarlos recibire la totalidad de los campos mostrados en pantalla?. si me entendieron y tienen una mejor forma de hacerlo, por favor diganmela, se los agradecere en el alma.

    gracias de antemano

  16. GravatarEzequiel Dice:

    Que me dicen de usar HTML_AJAX de pear conoces algo sobre el tema, o podrias guiarme sobre algun tutorial en español.

    ¿Cuales son las ventajas de prototype vs HTML_AJAX?

    Espero tus respuestas

  17. Gravatardavid Dice:

    Excelente articulo sobre ajax, estoy estudiando utilizarlo para una aplicacion tipo juego multijugador. El juego seria el tipico de los barcos, y lo que quiero es que cuando un jugador señale en su tablero una casilla, esta se marque al instante en el tablero de su contrario. Alguien sabe si esto se puede hacer con AJAX?

    Gracias por vuestra ayuda.

  18. GravatarIsmael Dice:

    Godskyller:si lo que necesitas es sólo actualizar una tabla, es más sencillo y eficiente que el script que genera la respuesta Ajax simplemente genere el html para la tabla completa, y en tu página usas Ajax.Updater() para reemplazar la tabla completa por la que viene desde ajax, así:


    /* EN HTML: */
    <div id="contenidos“>
    ..Aquí va la tabla
    </div>
    /* EN javascript */
    function actualiza(){
    new Ajax.Updater(”contenidos“,”/genera-tabla.php”);
    }

    Ajax.Updater se encarga de hacer el request al servidor y de inyectar en el div “contenidos” cualquier cosa que venga en la respuesta, en este caso la tabla completa.

    Relee este artículo para entender cómo enviar parámetros al servidor usando Ajax.Updater.

  19. GravatarIsmael Dice:

    PS: disculpen si no puedo responder las dudas de todos, estoy algo corto de tiempo. trataré de ir respondiendo de a poco. Por supuesto, si alguien tiene una solución para las inquietudes de otros comentaristas, por favor no duden en dejar su aporte aquí mismo!

  20. Gravatargiovanny Dice:

    bueno, les pido disculpas por la pregunta que hice, ya resolvi ese problema, pero no utilizando prototype, de todas formas gracias por el interes, ahora el problema que tengo es que cuando llamo una pagina con AJAX, cosas como el calendario(utilizo la libreria calendar) producen eventos inesperados, en mozilla envia el formulario que contiene, y en ie no hace nada. si alguien ah tenido el mismo problema, por favor ayudeme o digame donde puedo conseguir ayuda o donde puedo buscar…. de nuevo gracias

  21. GravatarGonzalo Dice:

    Antes que nada, muy buen articulo me ha ayudado un monton. Tengo una consulta que hacerles, puedo mediante ajax traer funciones javascript y que funcionen en la pagina “llamadora”.
    He probado de varias maneras y hasta ahora no pude hacerlo.
    Basicamente lo que quiero hacer es que una pagina llamadora, traiga mediante ajax, una lista de imagenes y unas funciones javascript para poder verlas.
    Espero se haya entendido. Gracias de antemano.

  22. GravatarIsmael Dice:

    Gonzalo: le puedes hacer un eval() al texto retornado por el servidor para que el browser lo interprete como javascript. De esa forma puedes disponer de las variables y funciones que vengan en ese texto.

    Por ejemplo, imaginemos que el servidor retorna lo siguiente:

    
    // un array de imágenes
    var imgs = [”img1.jpg”, “img2.jpg”, “img3.jpg”];
    
    // una función que retorna una img. del array
    function getImage(id){
        return imgs[id] ? imgs[id] : false;
    }
    
    
    

    Si usas Prototype para Ajax, puedes hacer lo siguiente:

    
    /*------- Procesa respuesta del servidor --------*/
    function procesa(request){
      // evalua la respuesta como JS
      eval(request.responseText);
      // …Ahora puedes usar el código generado por el server
      var img = getImage(0);
    }
    /*——- Llamada Ajax ———*/
    var a = new Ajax.Request(”generador.php”,{onComplete:procesa});
    
    
    
  23. GravatarIsmael Dice:

    Ezequiel: HTML_AJAX es una librería PHP. Ese tipo de librerías están pensadas para escribir procedimientos en el servidor (php) y “exportar” una interfaz para ese código como javascript (en el browser). Aunque no he usado HTML_AJAX, si conozco Sajax y, en mi opinión, esas librerías son más de lo que uno necesita para hacer la mayoría de las funcionalidades Ajax. Librerías de cliente como Prototype, Mootols o jQuery simplifican tanto el javascript necesario en el cliente (browser), que automáticamente la lógica necesaria en el servidor (php, asp, ruby, etc) se hace mucho más simple también.

  24. Gravatarjordi Dice:

    Pues nada.. a ver si me modernizo un poco.. :P

  25. GravatarAndrès Fuenzalida Dice:

    Excelente!. con esto ya logre usar ajax en mis apps:D

  26. GravatarAlexis Dice:

    Alguien con experticia en Apache y Ajax me puede indicar por qué al momento de hacer una llamada ajax el status que me retorna es 500 (server error)?.
    Hay algo que es impreseindible que deba estar en las variables de ambiente del web server, necesito algún permiso especial en la carpeta de donde esté alojada la página (unix / cgi). El log de errores de apache no me dice nada que indique cómo o por qué se genera este error

  27. GravatarIsmael Dice:

    Alexis, probaste haciendo esa llamada normalmente a traves del browser? (poniendo la url en la barra de dirección del browser). Puede ser algo obvio, pero lo primero en ver si el problema es AJAX o el script en el servidor.

  28. GravatarAlexis Dice:

    Bueno, la verdad el problema me estaba dando con una implementación propia de AJAX sacado de otros tutoriales (desde cero) y hace un par de días lo implementé con la librería prototype y debo decir wuau , es lo más trivial del mundo.he quedado maravillado con la simpleza de su uso. De todas maneras gracias por darte el tiempo de responderme y debo decir que este sitio fue todo un descubrimiento a otros temas muy interesantes como el CSS y la diagramación de sitios web para desarrollo. con todo esto podré mejorar un 100% mis creaciones web. gracias y que tengas un Feliz Año (y a todos los lectores ).

  29. Gravataralejandro Dice:

    Hola, tengo un gran problema con Prototype que no he podido resolver, les comento:

    Tengo un formulario con textareas y checkboxes que envio atravez de ajax hacia guardar.php. El problema biene cuando guardo esos datos en una base, ya que me guarda los datos con caracteres extraños en donde hay acentos y eñes.
    Por ejemplo: “á é í ó ú” lo guarda como “á é í ó ú”

    El formulario es simple, onsubmit=”guardar(’abm/guardar.php’,'form1′); return false ”

    y el codigo en ajax que hace de transferencia:

    function guardar(url, formid){

    new Ajax.Request(url, {

    parameters : //parametros del formulario
    Form.serialize($(formid)),

    method : //metodo
    “post”,

    });

    }

    Si por ejemplo en el form escribo: caño y hago un alert de la serialización caño lo traduce a ca%C3%B1o… entonces lo envia a guardar que lo recibe y lo guarda en la base con el texto: caño

    Ya no se que mas probar, intente agregando:
    contentType: ‘application/x-www-form-urlencoded; charset=ISO-8859-1′,
    pero igualmente los datos se graban mal en la BD.

    Desde ya estaría muy agradecido por cualquier ayuda que me puedan dar…

  30. GravatarRoberto Dice:

    Hola como estan,

    Giovanny me gustaria saber como resolviste el problema que planteaste, al igual que tu yo estoy empezando a utilizar Ajax, si porfavor me puedes enviar la solucion al correo robertojavierpinto@hotmail.com o orientarme un poco te lo agradeceria mucho; de igual manera si otra persona posee la solucion. gracias de antemano……

  31. Gravatarismael Dice:

    Roberto, Giovanny: Con el evento onblur pueden gatillar la llamada Ajax que envía el valor del campo al servidor. Si el servidor valida con éxito, envía de vuelta el html con los nuevos campos, que son insertados en el formulario.

    HTML:


    <fieldset>
    <p>
    <label for="ID">Identificación:</label>
    <input type="text" id="ID" value="" onblur="new Ajax.Updater('nuevos-campos‘,’/consulta.php’,{parameters:’valor=’+this.value})” />
    </p>
    <div id=”nuevos-campos“>

    </div>
    </fieldset>

    Por supuesto, no te olvides de incluír Prototype para que esto funcione!

  32. GravatarBenjamin Dice:

    Hola:
    Si alguien me pudiera ayudar se lo agradeceria de antemano. Primeramente estoy aprendiendo a utilizar ajax para ver si puedo mejorar mis paginas hechas con php, la pregunta que tengo es ¿Como ayuda ajax a agilizar una consulta a una base de datos y si podrian darme un ejemplo?

    La forma en que normal como hago esta consulta es mediante una sentencia sql y el resultado lo muestre en una tabla, el tiempo que se tarda en mostrar una lista de 3160 registros es de 10 min.Por favor ayudenme, Gracias…

  33. GravatarIsmael Dice:

    Benjamin: Ajax es Javascript, se ejecuta en el navegador y no tiene nada que ver con bases de datos o PHP. Ajax puede optimizar ligeramente el tiempo de carga si lo usas para cargar fragmentos pequeños de html dentro de una página ya cargada en el navegador (por ejemplo una tabla de resultados), pero sigue dependiendo del servidor la optimización de consultas a base de datos y generación de resultados en HTML.
    Dicho esto, por lo que cuentas te puedo sugerir (vehementemente!) que no hagas consultas taaaan grandes! Nadie puede digerir una tabla de 3160 registros. Lo que debieras hacer es dividir esos registros en varias páginas de pocos resultados cada uno (usando las sentencia LIMIT de SQL en tus consultas) o implementar un buscador que te permita ver menos resultados pero más relevantes.

  34. GravatarIsmael Dice:

    Ajejandro: muy probablemente tienes un problema de codificación entre tus páginas y tu base de datos. Revisa con paciencia este artículo y sus secuelas.

  35. GravatariMacniatic Dice:

    Excelente artículo. Lo mejor de prototype y de script.aculo.us es que estan integradas en cakephp, mi framework de moda de momento :), antes de sumergirme en RoR.

  36. GravatarBenjamin Dice:

    Ismael: Muchas gracias!!! Sabes logre investigar lo que me dices, sabes estoy queriendo mostrar los datos de 100 en 100, uilizando links de “anterior” y “Siguientes”, pero la direccion que utilizo en los link es la misma pagina, ejemplo &id3=”, pero al hacer esto recarga la pagina,lo que me gustaria es como puedo utilizar ajax para que muestre los siguientes 100 datos, por cierto necesito enviar las dos variables para que continue con los siguientes datos. Espero darme a entender. Gracias

  37. GravatarBenjamin Dice:

    ismael: upss no mando el ejemplo solo lo ultimo //href=”status_order2.php?ano=?=$ano;?&id3=?=$rowe;?>”

  38. GravatarIsmael Dice:

    Benjamin: es simple. Como te decía, Ajax puede cargar fragmentos enteros de HTML dentro de una página. Simplemente haz que tu script php genere la sólo tabla de resultados Y los links de navegación entre las páginas. Nada más.
    Luego, en la página “madre” (la que el usuario ve en el browser, usas Ajax para cargar esa tabla en algun lugar. Los links de paginación deben llamar a la misma función Ajax pero cambiando los parámetros de acuerdo a la página correspondiente. De esa forma sólo se actualiza el fragmento correspondiente a los resultados, no la página completa. Para entender cómo enviarle parámetros a Ajax, relee este artículo, la información está ahí (Ajax.Request y el objeto parameters). También revisa el comentario 18.
    En todo caso, es conveniente que los resultados se carguen por ajax? A lo mejor es mejor para los usuarios que se actualice la página, así pueden guardar la URL en los favoritos para la página que quieren (eso, por supuesto, es decisión tuya como diseñador).

  39. GravatarBenjamin Dice:

    Ismael:Gracias asi quiero hacerle, y me gustaria saber si me podrias mandar un ejemplo sobre esto, sabes estoy aprendiendo a hacer todo este tipo de cosas y la verdad es que estoy interesado en esta tecnica (ajax), te agradeceria muchisimo. mi mail es: le_back_nigga@yahoo.com.mx

  40. GravatarIsmael Dice:

    Benjamin, el ejemplo en el comentario numero 18 de este artículo es lo básico que necesitas en lo referente a Ajax. Lo único que faltaría es el script php que busca los datos en la base de datos y genera la tabla de resultados html, que entiendo tu ya la tienes hecha. Disculpa que no te pueda confeccionar un ejemplo más detallado (por falta de tiempo), pero creo que aquí está toda la información necesaria. Si no te queda claro, creo que necesitas más información sobre PHP, pero por suerte hay mucho de eso en la web.

  41. GravatarBenjamin Dice:

    Ismael:muchas gracias, me puse a leer y a buscar en la web y encontre un ejemplo un poco parecido a lo que estaba buscando. Te agradezco mucho, ya que con articulo logre complementar el ejemplo.

  42. GravatarBeto Dice:

    Ismael, excelente articulo, sin duda me ayudo a entender este tema de la librerias javascript. Ocupe las funciones ajax de jquery y mi codigo cambio de:

    function objetoAjax(){
    var xmlhttp=false;

    try {
    xmlhttp = new ActiveXObject(”Msxml2.XMLHTTP”);
    } catch (e) {
    try {
    xmlhttp = new ActiveXObject(”Microsoft.XMLHTTP”);
    } catch (E) {
    xmlhttp = false;
    }
    }

    if (!xmlhttp && typeof XMLHttpRequest!=’undefined’) {
    xmlhttp = new XMLHttpRequest();
    }

    return xmlhttp;
    }

    function cambiarSelect(value) {
    var doc = null;
    destination = document.getElementById(’div_ciudad’);
    doc = objetoAjax();
    if (doc)
    {
    doc.open(”GET”, “ajax.php?region=”+value, false);
    doc.send(null);
    destination.innerHTML = doc.responseText;
    } else {
    destination.innerHTML = ‘Browser unable to create XMLHttp Object’;
    }
    }

    a esta funcion:
    function cambiarSelect(value) {
    $(’#div_ciudad’).load( “ajax.php”, { region : value } );
    }
    que al parecer hace lo mismo que ajax.updater de prototype.
    Te agradezco nuevamente ya que sin este articulo de introduccion no habría ocupado nunca este tipo de librerías.

  43. GravatarDanny Dice:

    Ismael: de antemano las felicitaciones del caso pues haz explicado el tema de ajax de una manera bastante digerible y amena, sin embargo, como usuario de php tengo un problema y es que antes de usar ajax; en mis paginas de php utilizaba la funcion header(Location:….) pues tenia paginas PHP intermedias que hacian el trabajo de insertar, modificar etc. los datos en la base de datos y con la funcion header(…) redirigia el navegador a las pagina inicial que hizo el llamado, sin embargo ahora en ajax no tengo claro la idea de como hacer esto;

    Espero que me hayas entendido, ¿como sustituyo la funcion header() en ajax?

    gracias de antemano por la ayuda prestada y si deseas puedes contactarme en mi correo: danny.benique@msn.com

    Saludos y gracias nuevamente.

  44. Gravataracuario Dice:

    consulta … despues de enviar por ejemplo un formulario a un div (inicialmente vacio) como puedo establecer el foco a un elemento de dicho formulario …. cuando coloco el script para colocar el foco me dice que no existe sin embargo cuando coloco un alert previo y despues el focus al elemento (ejemplo una caja de texto) si lo hace … lo que no quiero es colocar el alert … pero si lo saco me dice denuevo que el elemento no existe …

  45. GravatarKaro Dice:

    Hola diculpen la pregunta yo soy nuevo en el mundo de la web y programo en php y quiero incorporar un poco de ajax mi pregunta es hay lguna forma de reflejar los cambios sin el # del hash. y otra consulta estadobeta para cambiar de seccion usa ajax o actualizar muy rapido? desde ya muchas gracias

  46. GravatarMax Dice:

    No concuerdo con que Jquery no sea extendible y solo para desarrollos simples, ejemplos de ello, Drupal, unos de los mejores CMS’s lo usa como libreria javascript por defecto y YUI-EXT de yahoo ha unido fuerzas con Jquery

  47. Gravatardimbmmkelt Dice:

    myeptztrz

  48. Gravatarracbfpedmr Dice:

    mroydgnu

  49. GravatarMercedes Dice:

    Buenas tardes.
    Soy nueva en esto de Prototype y no consigo que me funcione :).
    Estoy utilizando Ajax.Request para poder cargar datos en un textarea pero no hay manera de que me funcione. ¿Podríais echarme una mano? Gracias desde ya mismo.

    — Javascript —

    function cargarContenido(){
    var params = “par1″;
    var myAjax = new Ajax.Request(’/cargarContenido.do’, {
    method:’get’,parameters: params,
    onSuccess: function(peticion){
    var response = peticion.responseText || “No se han recibido datos”;
    $(’empresas’).value = response;},
    onFailure: function(){ alert(”Error”) }
    });
    }

    — Html —
    body onload=”cargarContenido();”

    textarea name=”empresas” id=”empresas” readonly

    Tengo que cargar la funcion JS en el onload del body, porque no consigo que me funcione:

    Event.observe(window, ‘load’, cargarContenido );

    Respecto a Ajax.Request, quisiera en la url poner una accion de Struts, pero no sé cómo he de configurar esta..

    Un saludo

  50. Gravatarricardo Dice:

    muy bueno el tutorial, es preciso y conciso para saber lo basico y de alli volar con la mente vamos a ver q tan alto puedo llegar y sigue asi y espero q publiques otro pronto con otros tips chauuuuu

  51. Gravatarx100pre Dice:

    holas a todos haber si me pueden ayudar ojala que si pues, bueno soy nueva px pero tengo la siguiente necesidad.
    QUIERO QUE CUANDO LE DOY CLIK E UN VINCULO EN ESTE CASO LINK1 EN EL DIV SALGA EL CONTENIDO DE LINK1. haber si me ayudan lo mas pronto posible px bye gracias
    function processReqChange(){
    var detalles = document.getElementById(”detalles”);
    if(req.readyState == 4){
    detalles.innerHTML = req.responseText;
    } else {
    detalles.innerHTML = ‘ Loading…’;
    }
    }
    link1

  52. GravatarIsmael Dice:

    Danny: con Ajax no necesitas header("location...")
    porque justamente la idea de Ajax es que no es necesario refrescar o redirigir la página. Tu PHP que hace las transacciones en la base de datos simplemente escribe el HTML de respuesta que quieres inyectar en la página que hace la llamada, o usas header("status...") para enviar de vuelta a Ajax un status 200 para indicar que todo salió bien (o un status 500 si hubo errores).

    Acuario: tienes que establecer el foco después de que Ajax ha actualizado la página. Si lo haces antes o mientras, el input en cuestión todavía no existirá (el alert le da tiempo a Ajax de actualizar la página, y por eso funciona). Para eso dale el foco al input en un callback “onComplete” de la clase Ajax.Request o Ajax.Updater. Relee esa parte del artículo para saber cómo.

    Mercedes: los textarea no tienen un atributo value, sino que les inyectas contenido como a un DIV o similar. En lugar de $(’empresas’).value = response debes usar $(’empresas’).innerHTML = response, aunque es más sencillo si usas Ajax.Updater.
    var a = new Ajax.Updater('empresas','/cargarContenido.do')

    x100pre: por lo que veo estás usando funciones Ajax que no incluyes en tu ejemplo (y no estas usando Prototype, el tema de este artículo). Relee este artículo para usar Ajax con Prototype y verás que es fácil.

  53. GravatarIsmael Dice:

    Max: jQuery es Javascript, por lo tanto es extendible (basta con extender el prototipo de cualquier cosa o copiar sus atributos y listo). Pero comparando con la API de Prototype o MooTools, me quedo con estos últimos. Mejor enfoque del modelo de clases y herencia, creo yo. Además el código es más fácil de entender.

  54. GravatarCarlos Dice:

    Hola, trate de hacer el tutorial pero me sale un error en el firebug de mozilla que dice lo siguiente:

    “Element has no properties
    var method= element.tagname.toLowerCase();”

    Alguien sabe como soluciono esto?

  55. GravatarIsmael Dice:

    Carlos, puedes mostrar más código para saber qué estas haciendo?
    En cualquier caso, no es “tagname” sino “tagName”, con “N” mayúscula. ¿Será ese el problema?

  56. GravatarJulio Andres Dice:

    Cree una consulta Ajax con prototype. Cuando activo la consulta en la pagina me carga todo bien el la pagina en el div correspondiente, pero ahora cuando activo nuevamente la misma consulta me carga nuevamente la pagina de la coneccion anterior.
    La pagina que cargo esta siempre en constante renovacion, por eso no me sirve cargar nuevamente la pagina de la primera coneccion que ejecuta ajax, alguien sabe como se hace esto en prototype…

    Muchas gracias…

  57. GravatarWebmaster Mexico Dice:

    Gracias por el manualito, me ha sido muy util.

  58. GravatarKaro Dice:

    Hola Ismael por ahi mi pregunta no tiene sentido pero e visto paginas similares al tuyo “estado beta” que al cambiar de seccion parece que carga toda la pagina y una vez cargado lo muestra lo que no se si usan ajax o alguna tecnica o simplemente carga rapido y me da esa censacion..

  59. GravatarIsmael Dice:

    @Julio: no me queda muy claro. Si haces haces varios requests Ajax, debiera cargar el contenido nuevo cada vez. Pero necesitaría más detalle para confirmar.

    @Webmaster: de nada.

    @Karo: EstadoBeta no usa nada de Ajax (por ahora). Qué navegador usas?

  60. GravatarKaro Dice:

    Ismael uso IE y firefox lo que noto es lo siguiente en otras paginas al cambiarme de seccion por ej de la home a archivos en otras paginas se pone en blanco el archivo y va cargando pero en el tuyo hago click sobre archivos por ej y en la barra del estado me muestras que esta cargando una vez cargado se cambia de pagina y el parpadeo es minimo por ahi es mi imaginacion o la pagina carga muy rapido y me da la sensacion.

  61. GravatarJulio Andres Dice:

    No hace eso. Por ejemplo tienes:
    url= “cargadatos.php”;
    params: “palabra=prototype”;

    Luego creas la el objeto ajax con esas variables, la respuesta va a ser lo que devuelve “cargadatos.php”, pero ahora si por segunda ves creamos la misma pregunta con los mismos datos prototype verifica si ya se hizo esa pregunta y en ese caso devuelve lo que “cargadatos.php” le mando en la coneccion anterior.
    Pero si despues creas otro objeto ajax con el parametro:
    params: “palabra=prototype1″;
    Ya no te devuelve la coneccion anterior.-
    Lo que hise yo por el momento fue como solucion parche:

    min=new date();
    params: “palabra=prototype&q=”+min.millisecons(0);

    Con eso siempre el parametro va a ser diferente pero no lo encuentro como codigo limpio, quiero encontrar una solucion eficaz, no efectiva.

  62. GravatarCarolina Dice:

    la instale y todo pero igual hace un reload de la página que puede ser?

  63. GravatarIsmael Dice:

    @Carolina: cómo estás usando Ajax? Necesito más detalle para poder ayudar.

  64. GravatarJulio Andres Dice:

    mmmm, y mi pregunta nadie sabe nada, si la mayoria usa este framework.-
    :(

  65. GravatarIsmael Dice:

    Julio, no recuerdo que eso me haya pasado, pero la única solición que se me ocurre es la que ya econtraste. Si quieres que tu código sea más limpio, puedes encapsular la creación de llamadas Ajax en una función sencilla.

    var callAjax(url){
    opts = Object.extend(
    {
    method:”post”,
    parameters: “”
    },arguments[1] || {}
    );
    random = new Date().millisecons(0);
    opts.parameters = [opts.parameters,random].join(”&”);
    new Ajax.Request(url,opts);
    }

    …o algo así.

  66. GravatarJulio Andres Dice:

    Ok, gracias…:(

  67. GravatarAldo Dice:

    Muy buen articulo …. humm… aunque es algo tarde el a ver encontrado jajajja.. tengo un problemilla.. vera.. deceo que mi pagina muestre cargando antes de mostrar toda la pagina completa… bueno…. la mayoria de los objetos a mostrar… y puse el ejemplo que pusiste al ultimo con tu variable “globalCallbacks”
    .. bueno lo modifique a mi pagina.. pero no da… resulta que no crea la variable o bueno no realiza ” Ajax.Responders.register( globalCallbacks ); “… espero q me puedas ayudar.. pues

  68. GravatarTestName Dice:

    Test myfunction comment

  69. GravatarEsteban Dice:

    Hola, esta muy bueno el tema, yo recien me inicio en Ajax, son senior en php, ahora toy buscando información para integrar Ajax con Erlang, el servidor es Yaws, mi pregunta es, se puede Adaptar Ajax a cualquier servidor?

    Muchas Gracias

  70. GravatarIsmael Dice:

    @Esteban: Ajax es JavaScript, o sea todo sucede en el cliente (browser). El servidor recibe POSTs o GETs HTTP como cualquier otro request.

  71. GravatarEsteban Dice:

    Mira te cuento, para las paguinas yaws, se usa erlnag, y la lógica del progrma se hace en modulos q se compilan con .beam, o sea llamo a una pagina controlador.yaws q llama al modulo erlnag, ej. retornarDatos:funcion(Arg), esto se redirije al modulo quien procesa la información y retorna una tupla q contiene una lista de parámetros, la pregunta es como lo integraría, ya q esos parametros en la pagina se obtiene con una api yaws:api_binding -> q tiene todos los parametros pasados por el módulo, no importa esto?, como sería la pagina html, javascript y erlang en la misma pagina, o haria el html por un lado y llamo a una pagina .yaws como si fuerna en php? si me podes orientar te lo agradecería, pa es muy bueno tener una respuesta tan rápida! Sal2!

  72. GravatarMarcelo Dice:

    todo muy lindo pero no mme anda en internet explorer.
    hice esto: si alguien me puede ayudar le agradesco

    me funciona solo en firefox

  73. GravatarMarcelo Dice: