Posts Tagged ‘JavaScript’

Internet Explorer 11 y la…

enero 28, 2014

… cadena que identifca el user-agent.

Síntoma: algo anda en Internet Explorer 10 y al actualizar a 11 deja de andar.

Esto se debe a que nuestros humildes programas web tienen que adaptarse a las características de javascript de cada navegador.

La solución más clásica era buscar el substring “MSIE” en el User Agent String.

Internet Explorer 11 no quiere que lo traten como a sus versiones anteriores y no incluye el substring MSIE.

Para eso recomiendan con mucho tino detectar características en vez de substrings.

En el raro caso de que no se pueda, reconocerlo con el substring Trident.

Mientras hacemos los arreglos el modo de compatibilidad nos puede sacar del paso.

En nuestro caso había que bloquear el F5 y el Control-R. La implementación para IE usaba el evento document.onkeydown, mientras que la versión para Mozilla y Chrome usa addEventListener al evento “keypress”.

Con IE11 trataba de hacer el addEventListener a keypress, lo reconocía, pero al hacer F5 a pesar del return false seguía corriendo el evento. En Mozilla/Chrome esto no pasaba. Lo pasamos a document.onkeydown y todo joya. ¡La próxima será MSIE!

La aplicación no la hicimos nosotros, sino un proveedor externo y el cambio tenía que ser lo menos invasivo posible. Fuimos por el Trident.

Anuncios

¿El fin de xAMP?

diciembre 11, 2013

Para no abandonar el vicio estoy haciendo algunas cositas en PHP.

Pero como adquirí vicios estoy tratando de evitar eso de mezclar lógica con renderizado de html. A lo que llegue fue a armar un html bien básico y jQuery y eventos mediante, circunscribo los pedidos al servidor en una capa javascript que gestiona los requests y renderiza el resultado de los response.

Del lado del servidor quedan unos scripts PHP muy sencillos que se concentran en ejecutar la lógica y devolverlos en un formato javascript friendly. Tan reemplazable con servlets + jaxb…

Hace poco compré un librito(sí… es vintage, pero no hay nada más lindo que recibir del correo tradicional el sobre marrón) de manning acerca de Single Page Web Applications. El libro tiene más o menos la misma arquitectura pero la variante que propone es node.js del lado del servidor reemplazando a PHP y jubilar a MySQL por la cada vez más ubicua MongoDB.

Es muy difícil en el mercado rioplatense vender una aplicación que confía sus datos a Mongo…DB, pero parece que las cosas van para ese lado.

¿será el fin de apache, MySQL y PHP?

interface: widgets para jQuery

agosto 30, 2007

Estoy haciendo un sitio institucional estático para un vivero, muy básico. Puro HTML y trabajo en javascript.

La diseñadora gráfica armó un esquema muy lindo, aunque que muy “à la Flash”. Así que estoy haciendo magia con CSS y javascript para que quede lindo como en el bosquejo que me mandaron.

El problema era un ScrollBar no estándar muy bonito que por más que se presione al CSS, se ponía poco menos que imposible.

Había que apelar a algún widget en javascript y encontré el Slider de la biblioteca Interface para jQuery.

La única observación es que no funciona en Internet Explorer con jQuery 1.1.3 o 1.1.4, pero funciona de pelos con jQuery 1.1.2 que es la que podés descargar del sitio de Interface.

El problema era que en total toda la biblioteca pesa 80KB + 21KB de jQuery es pesadito. Interface también ofrece una solución para esto: se puede seleccionar los widgets que queremos y nos genera la biblioteca con lo que usás y nada más. Para el Slider necesitaba Drag&Drop y el propio Slider, peso del interface personalizado: 24KB + 21KB de jQuery.

Con eso conseguí el bloquecito de texto, y me quedó bastante bien el layout.

¡Hasta la próxima!

JsCalendar Helper para CakePHP

agosto 26, 2007

Necesitaba incluir el JsCalendar y me puse a buscar si estaba implementado el Helper, pero no. Lo más parecido era un controlador que se puede ver en este link.

No está nada mal, pero me resultaba un poco molesto tener que usarlo como controlador. Además el propio Pierpaolo invita a que lo mejoremos.

Yo decidí encararlo como Helper y que a la hora de imprimir el calendario en la vista sea lo más general posible.

El primer problema que se me presentó fue el de incluir los archivos .js y .css. Como estoy trabajando con 1.1.16.5421 necesitaba incluirlos en el layout. Googleando encontré que alguien ya había hecho algo para resolver este problema aquí. Hay que tocar el layout pero esto provee un Helper bastante bonito para lo que necesitaba.

Resuelto esto ya podía armar el Helper.

Tomé la clase PHP que viene con la distribución del JsCalendar. adapté el constructor al esquema de CakePHP. Desde el constructor se selecciona el look, el idioma, el directorio relativo a js, css e img de CakePHP. A su vez se setean otras opciones por defecto. Además tuve que agregar dos parámetros. Uno ‘align’=>”, porque con MSIE salía por cualquier lado. El otro es ‘width’=>’240px’ porque el ancho iba hasta el borde derecho de la pantalla.

El método de carga de los scripts fue modificado para trabajar con HeadHelper.

Por último modifiqué “make_input_field” para que funcione con un input, una image y un link del HtmlHelper. También valida que no se haya invocado el método de carga mediante una variable de instancia. Con eso ya tenía el calendario funcionando como un helper.

¿Cómo lo uso? Cargo el helper en el controlador con la variable $helpers.

<?php
echo $jsCalendar->make_input_field( 'Proyecto/inicio', #tagName del input
array(), #opciones del calendario(*)
array(
'name'=>'data[Proyecto][inicio]', #campo
'value'=>$html->tagValue('Proyecto/inicio' ) #valor inicial
); ?>

(*) se puede ver la documentación del jsCalendar.

No hace falta usar tantas líneas, la idea es usarlo como cualquier otro widget de Html.

Los scripts js del calendario se deben poner en webroot/js/calendar/. Los css en webroot/css/calendar/ y las imágenes en webroot/img/calendar/. En caso de usar Skins deben estar los archivos distribuidos en los directorios de los css y las imágenes.

Se puede descargar el helper con el esquema de directorios.

Bueno, espero que sea útil como me resultó a mí y si quieren mejorarlo, bienvenidos sean.

jQuery

julio 27, 2007

jQuery es una biblioteca javascript. Su slogan es “Escribí menos, hacé más”. La idea es escribir JavaScript de una manera intuitiva.

Ahí me sonó la alarma: ¿escribir JavaScript de una manera intuitiva? ¡Ni loco! Bastante me tomó aprender a garabatear js para andar cambiando a esta altura del partido. Pero seguí, porque me llamaba la atención. Además porque tenía que usarlo con SPIP.

¿En qué consiste entonces esa manera intuitiva?

jQuery nos propone acceder a los elementos mediante consultas al DOM y devolviéndonos un objeto adaptador.

¿Por qué usar esta forma?

La manera de seleccionar los objetos es muy flexible. Se basa en tres formatos, 2 de los cuales son estándar: CSS, XPath y uno propietario (y bastante intuitivo). Se pueden ver acá

A su vez los objetos adaptadores son muy flexibles. Nos permiten manejar los atributos, los eventos, los adyacentes y padres en el DOM, algunos efectos visuales y ajax. Todo esto está muy bien documentado en docs.jquery.com.

¿Cómo empiezo?

Primero hay que bajar la biblioteca. La incluimos en nuestra página mediante:

<script type="text/javascript" src="jquery.js" mce_src="jquery.js">
<script>//mi c&oacute;digo fuente</script>

Una de las primeras cosas que debemos hacer es ejecutar código cuando la estructura del documento está cargada. Esto lo hacíamos con window.onload = function() { … }. Pero había que esperar a que carguen las imágenes. jQuery soluciona esto mediante método $().ready().

$(document).ready(function() { ... })

¿Qué es $()?

Es la consulta propiamente dicha y nos retorna el objeto adaptador. Se le puede pasar un cadena con la consulta, un elemento del DOM o incluso una cadena html que nos genera elementos html en el aire.

Otra propiedad interesante es que los métodos del objeto adapta retornan el mismo objeto (salvo aquellos donde lo que se retorna es un valor, como se verás más abajo). Esto permite encadenar varias acciones sobre los objetos reduciendo las líneas de código.

Para cerrar vamos a mostrar un pequeño ejemplo. Tenemos una lista de títulos y textos descriptivos. Esto podrían ser feeds de un blog. Queremos listar los títulos y ver solo la descripción cuando alguno en particular nos interese.

<ul>
	<li><span>titulo 1</span>
    
Este es el texto de   la descripci&Atilde;&sup3;n colapsable n&Atilde;&ordm;mero 1
    <a href="#" mce_href="#">mostrar</a></li>
	<li><span>titulo 2</span>
   
Este es el texto de   la descripci&Atilde;&sup3;n colapsable n&Atilde;&ordm;mero 2
    <a href="#" mce_href="#">mostrar</a></li>
	<li><span>titulo 3</span>
   
Este es el texto de   la descripci&Atilde;&sup3;n colapsable n&Atilde;&ordm;mero 3
    <a href="#" mce_href="#">mostrar</a></li>
</ul>

El script quedaría de la siguiente forma:

<script>$(document).ready(function(){ //Las etiquetas a que sean contenidas por una etiqueta li $("li > a").click(function() {  //si tienen por rótulo "ocultar"  if ($(this).html()=="ocultar")  {   //ocultan el elemento previo   $(this).html("mostrar").prev().hide("slow");   }  else  {   //sino muestran el elemento previo   $(this).html("ocultar").prev().show("slow");  } 

  return false; }); 

}); 

</script>

De esta manera tenemos descripciones colapsables con pocas líneas. La mitad del espacio son comentarios y llaves para hacer legible el código.

¿Bastante intuitivo, no?

Quería hacer una mención respecto a $(). En otro post dije que las funciones en JavaScript son objetos de tipo Function. Este es un caso. Se puede ver bien en el código como se usa esta función objeto y como final jQuery se puede usar con otras bibliotecas y frameworks JavaScript.

Esto se hace invocando al método $noConflict() del objeto jQuery. De esta manera $() queda libre (por ejemplo para prototype) y con invocar jQuery en vez de $() tenemos la misma funcionalidad.

Con eso ya hay para divertirse. ¡Hasta la próxima!

Objetos en javascript

julio 20, 2007

Los objetos en JavaScript son un tema que siempre me han traído problemas. En este post voy a tratar de ordenar un par de ideas.

Primero que nada podemos definir 3 tipos de objetos (¡no clases!):
– Objetos estándar del navegador: Varían según el navegador. Entre los comunes están Window, document. Mozilla provee XMLHttpRequest, MSIE los propios de ActiveX.
– Objetos del lenguaje: Los objetos de la implementación, como String, Array, Date, etc.
– Objetos propios: Estos son los objetos definidos por nosotros o por una biblioteca en particular.

Los objetos se pueden crear como funciones:

//Definici&Atilde;&sup3;n del objeto, si se quiere la "clase"
function MiObjeto (valor){
  this.unMetodo = function () {
    alert(this.unAtributo);
  }
  this.unAtributo = valor;
}

//instanciando el objeto
var oObjeto = new MiObjeto('hola, mundo!');
var oOtroObjeto = new MiObjeto();
oObjeto.unMetodo();

Con eso tenemos dos objetos en las variable oObjeto y oOtroObjeto construidos según la función MiObjeto(). A su vez tenemos unAtributo que tiene el valor que le pasamos al constructor y unMetodo que imprime el atributo. No es muy útil, pero sirve para mostrar lo básico.

El concepto de clase es un poco ambiguo en JavaScript. Al menos para el que viene de un lenguaje un poco más “prolijo” como Java o C++. En nuestro pequeño ejemplo, la clase sería MiObjeto y la instancia sería oObjeto. JavaScript nos permite extender nuestro objeto. Esto es tan simple como la línea que sigue.

oObjeto.otroMetodo = function ()
{
  confirm('Me entiende?');
}

oObjeto tiene un método nuevo: otroMetodo que nos va a preguntar si lo entendimos. Si invocamos otroMetodo desde oOtroObjeto vamos a comprobar que no nos pregunta nada. Esto se debe a que en la línea de más arriba solo modificamos la instancia oObjeto. Esto es muy interesante y es una fuente de errores. JavaScript nos permite modificar nuestro objeto en “caliente”. Podemos agregar o redefinir métodos existentes y agregar atributos.

¿Pero podemos cambiar nuestras “clase” MiObjeto? Sí, esto se hace mediante el atributo prototype de MiObjeto. La clase se define mediante una función. Las funciones son objetos de tipo Function (sí, suena a traba-lenguas). Podemos agregar atributos y métodos a nuestro objeto Function mediante el atributo protoype:

MiObjeto.prototype.otroMetodo = function ()
{
  confirm('Ahora me lees?');
}

Si probamos invocar ahora oOtroObeto.otroMetodo() vamos a a ver el confirm preguntando si ahora lo lees. Dejo al lector curioso que verifique qué pasa con oObjeto.otroMetodo().

Lo bueno de esto es que nos permite crear clases y objetos, extenderlos o redefinir su comportamiento. En algunos navegadores, como en Firefox, es posible redefinir y extender los objetos estándar. Algunos sin embargo están “sellados” por motivos de seguridad.

Para cerrar voy a hablar de JSON. Yo trabajaba en avatar y un día me pidieron hacer una aplicación que hacía uso intensivo de JavaScript y DOM. Un compañero me recomendó utilizar JSON. JSON es un acrónimo para JavaScript Object Notation y es una manera de definir objetos y funciones en JavaScript así como también un formato liviano de intercambio de datos, como se define en su sitio. Es muy útil como sustituto de XML en algunos casos. En algunas aplicaciones AJAX podemos recibir cadenas JSON en lugar de XML y evitar tener que lidiar con DOM. El framework The Dojo Toolkit es un ejemplo de esto. Pero esto será objeto de otro post, más adelante.

Saludos!