Archivo de la categoría ‘JavaScript’

AJAX - XMLHttpRequest

Martes, 8 de Mayo de 2007

XMLHttpRequest, es un API que puede invocarse desde JavaScript, y otros lenguajes de script incluidos en un navegador web, que se usa para transferir y manipular datos XML hacia y desde el navegador web, estableciéndose un canal de conexión independiente entre el lado del cliente de la página web y el servidor.
Los datos devueltos por la llamada a XMLHttpRequest serán, por lo general, obtenidos desde bases de datos en el servidor. La llamada puede devolver datos en XML o en cualquier otro formato textual como JSON o incluso texto plano.

Estos son algunos de los métodos y propiedades que se pueden utilizar con este objeto:

MÉTODOS
abort(): Detiene la petición actual
getAllResponseHeaders(): Devuelve todas las cabeceras de la respuesta como pares de etiqueta y valores en una cadena
getResponseHeader(”headerLabel”): Devuelve el valor de una cabecera determinada
open(”method”, “URL”[, asyncFlag[, "userName"[, "password"]]]): Asigna la URL de destino, el método y otros parámetros opcionales de una petición pendiente
send(content): Envía la petición, opcionalmente se puede enviar una cadena de texto o un objeto DOM
setRequestHeader(”label”, “value”): Asigna un valor al par label/value para la cabecera enviada.

PROPIEDADES
onreadystatechange: El manejador del evento llamado en cada cambio de estado del objeto
readyState: Entero que indica el estado del objeto (0 = sin inicializar, 1 =cargando, 2 = fin de la carga, 3 = actualizando la información recibida, 4 = Operación completada)
responseText: Cadena de texto con los datos devueltos por el servidor
responseXML: Objeto DOM devuelto por el servidor
status: Código numérico devuelto por el servidor, ejemplos: 404 si la página no se encuentra,200 si todo ha ido bien, etc.
statusText: Mensaje que acompaña al código de estado.

Para empezar con un ejemplo, lo primero que necesitamos es crear una nueva
variable y asignarle una instancia del objeto XMLHttpRequest.

<script language="javascript" type="text/javascript">
   var peticion = false;
   try {
      peticion = new XMLHttpRequest();
   } catch (trymicrosoft) {
      try {
          peticion = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (othermicrosoft) {
         try {
            peticion = new ActiveXObject("Microsoft.XMLHTTP");
         } catch (failed) {
            peticion = false;
         }
      }
   }
   if (!peticion)
      alert("ERROR AL INICIALIZAR!");
</script>

Los pasos seguidos son:
1. Crear una nueva variable llamada peticion y asignarle el valor false. Usamos false para significar que el objeto XMLHttpRequest todavía no está creado.

2. Intentamos crear el objeto XMLHttpRequest.

3. Si esto falla (catch (trymicrosoft))

4. Intentamos crear un objeto compatible para los navegadores modernos de (Msxml2.XMLHTTP).

5. Si la cosa sigue fallando (catch (othermicrosoft)), intentamos crear un objeto compatible con los navegadores antiguos de Microsoft (Microsoft.XMLHTTP).

6. Si todo esto falla (catch (failed)), nos aseguramos de que la variable peticion está a false.

7. Comprobamos si la variable peticion esta a false y si es así sacamos un mensaje de alert con el problema (alert(”ERROR AL INICIALIZAR!”))

Si probamos el código veremos que no pasa nada: señal de que todo ha ido bien.

Una vez que se ha creado una instancia podemos empezar a trabajar con XMLHttpRequest. Por ejemplo, vamos a realizar una función para ver el funcionamiento del método getAllResponseHeaders().

function Cabecera() {
   peticion.open("HEAD", "index.php",true);
   peticion.onreadystatechange=function() {
      if (peticion.readyState==4) {
         alert(peticion.getAllResponseHeaders())
      }
    }
    peticion.send(null)
}

1.- Creamos una funcion cabecera en la que lo primero que hacemos es abrir la instancia peticion que previamente habíamos creado (peticion.open(”HEAD”, “index.php”,true)).
- HEAD especifica el método HTTP usado para abrir la conexión. Puede ser GET, POST, o HEAD únicamente.
- index.php especifica la url. Se puede especificar la url de un modo relativo o absoluto pero debido a un modelo de seguridad del objeto XMLHttpRequest, éste solo puede hacer peticiones sobre el mismo dominio donde se está ejecutando.
- true determina que la operación es asíncrona (lo más habitual). Si es true asignamos un callback a la propiedad onreadystatechange para determinar cuando la operación se ha completado.

2.- Si la operación se ha completado (peticion.readyState==4), lanzamos un alert con las cabeceras (peticion.getAllResponseHeaders())

3.- No enviamos nada al servidor peticion.send(null)

Un ejemplo completo que nos mostrase las cabeceras mediante XMLHttpRequest sería:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <script language="javascript" type="text/javascript">
      var peticion = false;
      try {
      peticion = new XMLHttpRequest();
      } catch (trymicrosoft) {
      try {
      peticion = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (othermicrosoft) {
      try {
      peticion = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (failed) {
      peticion = false;
      }
      }
    }
    if (!peticion)
    alert("ERROR AL INICIALIZAR!");

    function Cabecera() {
    peticion.open("HEAD", "lanzadera.html",true);
    peticion.onreadystatechange=function() {
    if (peticion.readyState==4) {
              alert(peticion.getAllResponseHeaders())
    }
    }
              peticion.send(null)
    }
    </script>
    </head>
    <body>
    <a href="javascript:Cabecera()">
    Mostrar cabeceras </a>
    </body>
    </html>

JavaScript y OOP (Object Oriented Programming) II

Lunes, 23 de Abril de 2007

El constructor del objeto y prototyping

En el mundo de OOP las formas anteriores de definir un objeto en muchas situaciones son muy limitadas. Necesitamos crear un tipo “type” objeto que pueda ser utilizado multiples veces sin tener que redefinir todo el objeto a la hora de cambiar un valor o un parámetro. La manera standard de lograr ésto es con una función constructora.

El constructor de un objeto no es más que una función regular de JavaScript, es igual de robusta (recibe, define, inicializa parámetros, llama otras funciones, etc .). La diferencia entre ambas es que la función constructor es llamada a través del operador “new“.

Vamos a usar un objeto del mundo real (perro) como ejemplo. Una propiedad de un gato puede ser su nombre o su color. Un método puede ser “woof”. Lo importante aquí o lo que tenemos que tener en cuenta es que cada gato puede tener un nombre diferente o un color diferente, incluso “woof” distinto a los otros gatos. Para crear un objeto que nos resuelva esta necesidad y nos dé la flexibilidad que necesitamos, usaremos un Constructor.

<script  language="javascript" type="text/javascript">
  <!--
  function perro(nombre) {
    this.nombre = nombre;
    this.ladrar  = function() {
       alert(  this.nombre + " dice woof!" );
    }
  }

  perro1 = new perro("scooby");
  perro1.ladrar();
  //alerts  "scooby dice woof!"

  perro2 =  new perro("droopy");
  perro2.ladrar();
  //alerts  "droopy dice woof!"

  //-->
</script>

La función “perro” es el constructor del objeto y sus propiedades y métodos se encuentran declarados dentro de la función, precedidas con la palabra “this”. Los objetos que son definidos usando un constructor luego serán instanciados usando el operador “new”. Ahora somos capaces de definir fácilmente múltiples instancias de “perro”, cada una con su propio nombre, la flexibilidad que te brindan los constructores te permite personalizar los objetos creados.

Usando prototype con objetos pre-construidos o pre-definidos en JavaScript

Prototype funciona en ambos casos, con objetos creados por uno mismo u objetos pre-construidos como Date() o String(). La regla es que tu puedes usar prototype con cualquier objeto pre-construido que ha sido inicializado con el método “new”. En el siguiente ejemplo voy a agregar funcionalidades adicionales a un objeto pre-definido de JavaScript.

Como IE5 no soporta los métodos shift() y unshift() para el manejo de Arrays y NS4+ si, vamos a construirlos con prototype :-).

<script language="javascript" type="text/javascript">
<!--
// Metodos shift() y unshift().
  if(!Array.prototype.shift) {
    // Si este metodo no existe..
    Array.prototype.shift = function(){
      firstElement = this[0];
      this.reverse();
      this.length = Math.max(this.length-1,0);
      this.reverse();
      return firstElement;
    }
  }
  if(!Array.prototype.unshift) {
    // Si este metodo no existe..
    Array.prototype.unshift = function(){
      this.reverse();
      for(var i=arguments.length-1;i>=0;i--){
        this[this.length]=arguments[i];
      }
      this.reverse();
      return this.length;
    }
  }
//-->
</script>

JavaScript y OOP (Object Oriented Programming) I

Lunes, 23 de Abril de 2007

JavaScript es un excelente lenguaje para diseñar aplicaciones web con programación orientada a objetos. Soporta herencia a través de prototyping también soporta métodos y propiedades. Muchos desarrolladores que están acostumbrados al estilo de clases de C++ o Java no reconocen a JavaScript como un lenguaje OOP.

En JavaScript puedes escribir código orientado a objetos que puede ser reutilizado y encapsulado.

Creando objetos usando new Object()

Hay varias formas de crear objetos en JavaScript. La manera mas sencilla de hacerlo es usando el operador new, especificamente, new Object():

<script language="javascript" type="text/javascript">

<!--

  persona = new Object();
  persona.nonmbre = "alex";
  persona.altura = "170";
  persona.correr = function(){
     this.estado = "corriendo";
     this.velocidad = "40km/h";
  }

//-->

</script>

Crear objetos usando notación literal:

Otra manera lineal de definir un objeto es vía notación lineal. Esta es soportada a partir de JavaScript 1.2 y es una forma mas robusta de de crear objetos.

<script language="javascript" type="text/javascript">
<!--
// Object Literals
timObject = {
   propiedad1 : "Hello",
   propiedad2 : "MmmMMm",
   propiedad3 : ["mmm", 2, 3, 6, "kkk"],
   metodo1 : function(){
      alert("Metodo ha sido llamado" + this.propiedad1);
   }
};

timObject.metodo1();
alert(timObject.propiedad3[2]);
// resultado 3

var circulo = { x : 0, y : 0, radio: 2 } // otro ejemplo

var rectangulo = {
   upperLeft : { x : 2, y : 2 },
   lowerRight : { x : 4, y : 4 }
}
alert(rectangulo.upperLeft.x);
// resultado 2
//-->
</script>

La notación literal puede contener arrays, expresiones regulares o valores.