Archive for the ‘Javascript’ Category

Historia de los frameworks web

Wednesday, February 24th, 2010


By @mraible

Testeando respuestas JSON con Grails

Friday, November 20th, 2009

Aunque en la documentación de Grails aparece un ejemplo de como escribir un test para una acción que recibe una petición en formato XML o JSON, no lo hace de como escribir un test de una acción que genera el JSON, que tampoco es que sea precisamente complicado.

Si lo único que quisieramos probar es que, en una cadena JSON, se está devolviendo algún valor que estuvieramos esperando, podríamos utilizar el contenido que devuelve la response como una cadena(con contentAsString) y hacer alguna comprobación sobre el texto:

def response = controller.response.contentAsString
assertTrue response.contains('"name":"Gustavo Poyet"')
assertTrue response.contains('"goals":63')

Pero claro, este test es un muy ligero y no prueba demasiado. Si quisieramos probar más a fondo la respuesta(estructura, un elemento concreto de un array, etc), podríamos usar contains sobre la cadena devuelta, convertir tipos… vamos, que sería más que posible que el código del test terminara siendo infumable. Pero está disponible out of the box el converter JSON de Grails, que permite testear más a fondo fácilmente y con un código mucho más claro.

Es muy posible que si alguien se ve en la necesidad de escribir un test para una acción que devuelve un JSON, ya conozca el converter, por que es una de las alternativas que hay para hacerlo:

render object as JSON

Pues esa misma clase, tiene el paso contrario, pasar una cadena a un objeto groovy/java(JSONElement). De esta forma ya nos ahorraremos trabajo sucio y el código quedará bastante claro:

def response = controller.response.contentAsString
def responseJSON = grails.converters.JSON.parse(response)
assertNotNull responseJSON.players
assertEquals 5, responseJSON.players.size()
assertEquals 63, responseJSON.players[0].goals
assertEquals "Gustavo Poyet", responseJSON.players[0].name

Cambiando de prototype a YUI con Grails

Tuesday, September 8th, 2009

Días antes del último despliegue de Jobsket, estuve dándole vueltas a un problemilla con Grails 1.0.5 y los taglibs estándar para usar Ajax, por defecto Grails utiliza la librería javascript prototype para abstraerse de los distintos navegadores. Para que funcionen los taglibs remoteFunction, remoteLink y formRemote debemos utilizar <g:javascript library=”prototype” /> para que cargue el .js de la librería, la cuestión es que estamos utilizando algunos componentes de YahooUI(y de GrailsUI) y para aligerar el peso de las peticiones, queríamos quitar todas nuestras dependencias con prototype.

Después de refactorizar nuestro código javascript dependiente de prototype, donde hemos encontrado que hay efectos muy sencillos de implementar gracias a script.aculo.us que no lo son tanto con YahooUI(la librería Effects Widget nos ha ayudado en esta transición), nos encontramos que teniendo en el layout la declaración de qué librería deben usar para renderizar esos taglibs de Ajax, en las vistas seguía haciéndolo con el código para prototype, por lo que daba errores javascript. Para que en cada vista renderizara usando el código de YUI, debemos poner la declaración <g:javascript library=”yui” /> en cada vista, yendo con cuidado en el orden de las dependencias, ya que si hay un <g:javascript library=”yui”/> en el layout y en la vista sólo se renderizará el segundo, por lo que habría que hacer algo así:

En el layout:
<g:javascript library="yui" />
<g:layoutHead />
<yui:javascript dir="..." file="..." />
<yui:javascript dir="..." file="..." />
<g:javascript library="application" />

En la vista:
<g:javascript library="yui" />
<yui:javascript dir="..." file="..." />

En este orden se renderizarán primero las dependencias básicas de la librería YUI, luego las que necesitemos para usar componentes, y por último nuestro propio código que puede depender de algún componente.

En fin, no es una solución DRY, pero funciona para los pocos casos en los que lo necesitamos.

Otra de las soluciones de las que nos hemos ayudado, como muchos seguro que imaginaréis ;) , es implementar una función $(), que aunque no nos dé las bondades de las extensiones DOM de prototype, nos ha ayudado a tener que cambiar mucho menos código:

function $(id){ return YAHOO.util.Dom.get(id)}

Bug con IE 6 y LiveValidation

Thursday, January 17th, 2008

Este dolor de cabeza en forma de bug hacía bastantes días que lo tenía, utilizando la librería LiveValidation para validaciones con javascript con IE 6.

Pues resulta que cuando intentaba crear una nueva validación a un textarea concreto en un formulario, me daba un error:

LiveValidation::getElementType – Element must be an input, select, or textarea!.

A base de “debuggar” el código de la librería vi que al final la causa era porque ese textarea tenía un id=description, y al hacer la comprobación de si el elemento con ese id es un input, un textarea o un select devolvía un meta por el meta name=description… del header.

La solución tan sencilla como cambiar el dichoso id y seguidamente informar a los autores de la librería sobre el bug.

La forma correcta de usar window.onload

Tuesday, November 20th, 2007

En ocasiones, necesitamos ejecutar funciones javascript al cargarse una página (validaciones, autocompletados…).

Lo típico es hacerlo en el evento onload del body o poniendo las llamadas a nuestras funciones javascript dentro del código para que se vayan ejecutando mientras se carga la página, ésta sería la forma intrusiva de hacerlo, la forma no intrusiva sería utilizar window.onload.

window.onload = mifuncion();

Hay un problema que fácilmente nos puede surgir, cuando tenemos varias asignaciones a window.onload, ya que se ejecutará sólo la última.

En un principio se me ocurrió solucionarlo con una asignación común para toda la web, el problema es evidente, para una web más o menos grande llegaría a ser una macro-función, además de ser una solución nada elegante.
Al final a googleando un poco, acabé encontrando la solución en el blog de Robert Hahn, donde plantea tres formas de hacerlo para “que funcione”, y una solución que al parecer es la ideal, simplemente es asignar a window.onload ésta función que nos devuelve una función anónima:

function makeDoubleDelegate(function1, function2) {
return function() {
if (function1)
function1();
if (function2)
function2();
}
}

Para probarlo simplemente con éste código, podemos ver que funcina correctamente:

window.onload = makeDoubleDelegate(window.onload, alert('1'));
window.onload = makeDoubleDelegate(window.onload, alert('2'));
window.onload = makeDoubleDelegate(window.onload, alert('3'));

Hijax, otro “sabor” de Ajax

Monday, October 29th, 2007

Leyendo el blog de Olga Carreras me encuentro un post explicando qué significa otro acrónimo(o palabreja;)) más, Hijax, de la que soy consciente que existe desde que Daniel Torres nos explicaba lo que iba ocurriendo en Fundamentos Web. Parece que existe una manía a poner nombres a cada “invento”, que como con Ajax no tenemos suficiente, encontramos los términos Ajaj(devolver JSON) y Ahah(devolver HTML), pues casi que me voy a adelantar y voy a acuñar Hihah y Hijaj:).

Pues resulta, que Hijax, es una “técnica” de uso de Ajax(y javascript en general) para realizar desarrollos accesibles, que se basa en no utilizar javascript hasta que no esté desarrollado el funcionamiento accesible, y una vez que introduzcamos el uso de javascript éste no sea intrusivo.

En mi opinión a raíz de lo vivido en carnes propias, es la mejor forma de enfocar un desarrollo que tenga como requisito ser accesible, ya que considero más sencillo desarrollar los efectos y añadidos a posteriori, que definir una forma accesible de uso de una aplicación sin haberlos tenido en cuenta desde el inicio, ya que puede suponer prácticamente un doble desarrollo. Y siendo egoístas, como desarrolladores, corremos el riesgo de que ese tiempo de trabajo extra no esté planificado, y luego pasa lo que pasa.

Clase XHConn

Saturday, June 30th, 2007

Hasta ahora no he utilizado librerías javascript, únicamente algún componente configurable (calendario, autocompletado…), quizás porque no soy un apasionado de javascript y no las he trasteado, además de que utilizando algunos de esos componentes me he tenido que liar con su código para modificar algún detalle a mi gusto.

Cosa que nunca me ha pasado con la clase XHConn, que es una sencilla clase que soluciona los problemas de las compatibilidades entre navegadores al crear un objeto XMLHTTPRequest, y nos ahorra ese trabajo.

Su uso es muy sencillo, sólo tiene un método, connect al que se le pasan la url, el method(POST/GET), parametros de la url y la función de callback

Aquí un ejemplo:

//Instanciamos el objeto
var con = new XHConn();
//Comprobamos que el navegador tenga soporte al objeto XMLHTTPRequest
if (!con) alert("El navegador no soporta el objeto XMLHTTPRequest.");
//Definimos la función de callback
var fnWhenDone = function (obj) { alert(obj.responseText); };
//Llamamos al método connect
con.connect("urldeejemplo.php", "POST", "parametro1=a&parametro2=b", fnWhenDone);

Curiosidad con un array JSON

Tuesday, June 26th, 2007

Últimamente estoy empezando a utilizar JSON en vez de XML para recuperar datos con llamadas al objeto XMLHTTPRequest.
Trasteando, me he encontrado al devolver un array de objetos , que me daba un error en Iexplorer mientras que en Firefox funcionaba correctamente.

Esto se debía a un error mío, simplemente, a que me había colado al montar el array en el lado del servidor poniendo una coma ‘,’ al final del último objeto del array y explorer contaba como si tuviera un objeto más, mientras que firefox no.

Ej:

{"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "New", "onclick": "CreateNewDoc()"},
]}

En vez de:

{"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "New", "onclick": "CreateNewDoc()"}
]}

El error era mío, esto está claro, ¿pero no sería más lógico que los dos navegadores, al hacer el eval(), dieran error de javascript?, ¿o cuál sería el comportamiento más correcto?

Tuitermaps, jugando con google maps

Monday, June 25th, 2007

Hace un tiempo, estuve un par de días jugando un poco con el api de google maps y el de twitter, más que nada por la excusa del google maps, la de twitter es muy sencilla (bueno, twitter en sí lo es). El resultado es TuiterMaps.

Es algo parecido a twittermap, puedes ver de dónde son las personas que escriben, siempre que tegan puesto en su perfil el location.
En un principio muestra los mensajes del public timeline, también se puede seleccionar un usario en concreto y un usuario con sus amigos.

Es muy chorras, pero ya he visto lo fácil que es mostrar una localización gracias a la clase GClientGeocoder, simplemente le pasas al método getLatLng una cadena de la localización y una función callback que recibe un obeto GLatLng, y a partir de ahí puedes crear un GMarker para añadir al mapa.

Lo que le falta es un poco de diseño, pero para eso yo soy muy malo.

Usar Ajax y accesibilidad

Wednesday, May 30th, 2007

A mi personalmente nunca me ha gustado, como usuario, que la navegación dependa de las recargas del objeto XMLHTTPRequest, más que nada por los problemas del botón de actualizar o atrás de los navegadores, por lo que no lo veo sólo como un problema de accesibilidad, de usabilidad también.

Como desarrollador, tampoco me gusta hacer el doble de trabajo para cumplir con la accesibilidad, y eso si no hay que hacer modificaciones con el desarrollo acabado, cosa que NUNCA se cumple o yo no he tenido esa suerte.

Por esto recomiendo un post muy interesante sobre este tema, AJAX accesible en el blog de Olga Carreras, del que me ha llamado la atención que la etiqueta noscript desaparecerá en el estándar XHTML 2.0, por lo que abrá que tomarse más en serio el uso de javascript no intrusivo y empezar a olvidarnos de usar los eventos del html.