Web Analytics
Mostrando entradas con la etiqueta javascript. Mostrar todas las entradas
Mostrando entradas con la etiqueta javascript. Mostrar todas las entradas

Queridos CSS y Javascript

Os lo he dicho uno a uno, ahora en grupo: No os ajunto más.

Una mala idea

Vamos a ir cerranding esa amalgama de ideas que vengo escribiendo. Voy a proponer una aplicación mínima cliente-servidor que cumpla parte de los requisitos que dije antes.

Voy a recortar en todo lo posible, por ejemplo no se usarán bases de datos y el cliente no persistirá ningún tipo de información. La cuestión es que todo lo que no sea imprescindible para demostrar la viabilidad de un proyecto mayor nos lo saltemos a la torera. Partir de un tablero en el que se puedan mover fichas puede dar lugar a las damas, o a cualquier otro juego de tablero por turnos, con un poco más de lío con la lógica de negocio y la sincronía por red.

Añado requisitos técnicos más específicos del desarrollo o de tecnologías a emplear como la necesidad de pruebas unitarias, incluso la programación orientada a pruebas para poder desarrollar por contratos (se podría pasar a una persona un juego de pruebas y decirle que quieres el software que las cumpla).

A estas propuestas de calidad en desarrollo también se deberán ajustar los scripts de configuración citados anteriormente.

Cito las tecnologías que se usarán y las piezas de software y problemas que resolverán:

1) Servlet/Struts/Struts2/web services.

La centralización del servidor no necesita una conexión viva. Un cliente podrá ser identificado por una sesión web. Incluso se podría descargar al servidor de mantener sesiones si se hiciera un servicio web o se identificara unívocamente al cliente mediante algún oro mecanismo.

El que un cliente haga un “polling” para ver si existen actualizaciones se ve día a día con clientes de correo, rss, etc. Liberará al servidor de hacer un push en los clientes y la posible contratación de un servidor dedicado para realizar procesos batch.

Partidas, torneos, etc se podrían almacenar en base de datos así como configuraciones y sus posibles versiones.

Finalmente, diremos que se preferiría utilizar struts2, servicios web o servlets planos a struts… Soy así de cerdo o lo que sea… Tengo mis razones, una es que estoy hasta la coronilla de struts… Otra es que quisiera programar cliente y servidor sin depender de esa capa de abstracción que me obligaría a usar Struts para poder llamar al negocio. Los demás, hasta cierto punto, implementan una fachada de entrada al modelo más o menos directa.

Inicialmente aunque sea cliente servidor, se podrá hacer que el cliente se ejecute sin comunicación por red aunque sea esta simulada. De todas maneras para funcionar en junit no hará falta matarse.

2) Beanshell

Beanshell, tras mis pruebitas en una kvm y en la jvm completa, parece ser una potentísima herramienta de scripting. Se pueden crear clases enteras o instancias de clases definidas sin tipado…

Los scripts usan la gramática de Java así que si se diera el caso de que una mecánica programada en scripts madurase lo suficiente como para convertirse en parte de una aplicación, se podría compilar y unirse a ella. Se pueden distribuir en jar y un largísimo etcétera que me hace pensar que se podría tner un cliente mínimo y programar un Terminal desde el servidor.

3) Cliente Android

Sí. Me centro en esto. Se enchufa al ordenata y depuras diréctamente sobre la máquina, eso sin instalar rollos raros ni nada de eso.

El SDK pesa poco y es fácil de usar. La API, después de un golpe inicial contra esos conceptillos que se han sacado de la manga los chavales de google, resulta hasta cómoda y hay componentes para todo o pegas una patada a una piedra y salen cinco.

Las interfaces se pueden describir en documentos XML y éstos podrían estar en el servidor.

4) Junit

Hay un tipo de misiles, supongo que basados en la mente de la mujer, que se llaman “fire’n’forget”… Bromas aparte. Esto de junit, medianamente bien usado, hace que puedas programar una parte de tu lógica, probarla unitariamente, incluso hacer pruebas más grandes uniendo más piezas, y no volver a ellas hasta que rompas algo por otra cosa.

Te olvidas, eso está programado y funciona como esperabas.

Últimamente he descubierto algunas cosillas por ahí que me facilitarán la programación de pruebas respetando los estándares de encapsulamiento y herencia. Podré organizar mejor las pruebas.

Con junit se pueden probar los scripts beanshell… Depende de lo que quieras que hagan y todo eso, pero bien organizados se podrían probar. Incluso una serie de scripts pueden ser un proyecto en sí ya que al final no se distribuye una aplicación compilada sino una serie de ficheros .JAVA. Cada fichero Java se puede compilar, ejecutar con junit sus métodos, probar de mil formas y ver de mil maneras.

¿Por qué no actualizar la aplicación con las clases diréctamente? Porque es un engorro que se puede ahorra al usuario. Sin tocar más que una parte de toda esta maraña, se tendría al día el cliente y el servidor.

Quizá sea una muy mala idea. Pero puede intentarse.

Salú.

La lógica de un evento que se convirtió en acción

Vamos a suponer que tenemos un cliente de damas. El cliente es tonto para pintar, siempre pintará el estado del juego y esta lógica nunca se actualizará. En pantalla se pintará el tablero y una superposición de las opciones del jugador después de que éste haya seleccionado una pieza.

Cuando el usuario selecciona una ficha en el tablero se genera un evento que se procesará mediante una entidad representada por un script que puede cambiar en tiempo de ejecución. Normalmente este script formará parte de la configuración del juego, bien sea de la aplicación o de la partida en curso (se podría jugar a las damas inglesas con la misma interfaz pero distinta configuración). Si la ficha está bloqueada no se cambiaría la interfaz. Si no estuviera bloqueada, el script podría activar distintas opciones a mostrar en pantalla y pedir un repintado.

Esta parte está un poco borrosa y sin definir. La entidad que ha resuelto el evento no pasa de ser un EventHandler normal y corriente de los de toda la vida, en ella no intervinen lógica de negocio, sólo presentación. La parte en la que cito “ficha bloqueada” sería lógica de negocio. Ahí entraría una acción que sería, por ejemplo, MoverFicha. La interfaz de las acciones permitirían al código que las llama unas entradas de “seguridad” o, más bien, de comprobación de la posibilidad de ejecución. Varios métodos ayudarían a esto. Un getOptions o algo así, podría, no sólo decir si es posible realizar esta acción sino realizar algún refresco en la vista añadiendo las opciones a un menú que se pueda pintar. En este caso de las damas, en una capa por encima del tablero que estaba pintado, podrían aparecer en sombreado dos fichas en los posibles lugares a los que se puede mover la actual. Si la ficha fuese una dama en las damas inglesas esas casillas serían hasta ocho en un movimiento simple en el que no coma… La configuración lo variaría todo.

Esta acción se convertiría en comando cuando se ejecute. Por ahora estamos en la posibilidad de que se ejecute. El usuario la podría cancelar, la tenemos en cola para un posible fin de turno, es la acción actual y el botón volver la puede deshacer. El usuario confirma, la acción se ejecuta y repintamos el modelo en pantalla con el nuevo tablero… Se ha hecho cambiar el proxy del modelo en el cliente. Incluso, con ser este un juego de damas y sólo podemos mover una ficha cada turno, se podría comunicar al servidor el fin de turno o desencadenar una acción que permita al usuario aceptar para finalizar su turno. Entonces se enviarán los datos al servidor para que se actualicen el resto de clientes.

Ese paso, el de actualizar el resto de clientes, se puede independizar de la arquitectura, del método usado, etc. Habría que ver si hacemos PULL o PUSH desde el terminal. Un límite de tiempo y refresco a petición del cliente sería lo más óptimo a mi entender.

En próximos capítulos, el milagro del remote scripting ^^

Servidor filosofando de clientes

No es que quiera pegar estos pensamientos a una tecnología en particular, pero no está de más centrar la finalidad del proyecto para acotarlo de algún modo. La idea no es hacer el DooM entero y ejecutarlo a ver qué pasa. Hacer un cliente capaz de ejecutar pequeñas lógicas de negocio para descartar eventos de usuario y un servidor que sincronice partidas es ya un trabajo suficientemente grande para una persona. Añadir capas a esta estructura o ampliar esta lógica de negocio sería lo mismo que construir una aplicación sobre un buen framework en el que cada acción de usuario se pueda implementar independientemente. Añadir datos al modelo incluso nuevas reglas de negocio…

Sobre nuevas reglas de negocio, vamos a centrarnos ya en Android. Android es lo que quiero que implemente el primer cliente de la aplicación. Sin quitar que luego haya cliente web o lo que venga. Al tener una aplicación desplegada en un aparato con android, se puede actualizar esta arbitrariamente cuando el desarrollador quiera dentro del Market. Una pega bastante gorda de esto es que el cliente tiene que tener la voluntad de actualizarla porque debe activar él mismo la descarga e instalación de la nueva versión.

Quisiera poder esquivar este tema. Las acciones de usuario deberían tener consecuencias distintas según el modo de juego, incluso si se me apura, poder cambiar dinámicamente. Habría que tener un cliente lo suficientemente inteligente como para decir que no se puede mover una ficha del juego de damas en vertical u horizontal. Se me ocurre flexibilizarlo aun más y poder, desde el servidor, introducir nuevas modalidades de juego de damas distintas a las que yo conozco. Los ingleses juegan con las damas (cuando son damas y se le da vuelta a la ficha que por el otro lado les ponen una cruz negra) con un tipo de movimiento particular, pueden mover en cualquier dirección (incluso vertical u horizontal) pero de uno en uno.

Esto de flexibilizar las reglas de juego no es un problema en sí, se podría anunciar una actualización y decir al cliente que si no se actualiza no podrá jugar a las damas a la inglesa… Pero preferiría que si se actualiza el cliente sea por corregir bugs o añadir algún tipo de funcionalidad que, de veras, no se pueda desde el servidor. Además este nuevo requisito se une al depender en dos aplicaciones (cliente y servidor) de un cambio que se podría dar en una.

Me lleva a pensar esto en distribuir la computación y hacer que el cliente pida “permiso” al servidor para mover de a3 a a4 en un juego de damas. Esto usaría red. Un defecto de los informáticos es que pensamos en el usuario y en sus aparatos. Al programar para una consola portatil se pausa de vez en vez la cpu o los sistemas de sonido mientras no se vayan a usar para ahorrar batería. Parece mentira, pero como usuario te acabas dando cuenta de qué juegos o aplicaciones se comen la batería y cuales no. Así que vamos a descartar eso de tirar la énergia y usar la red sólo cuando se necesite.

Esto del ahorro nos descarta de un juego en tiempo real aunque también es posible algún tipo de juego que ya he pensado en el que los eventos de usuario sean bastante espaciados. Al final, lo que me interesa es hacer un juego por turnos que sea “atemporal” no que exista por siempre si no que se pueda jugar en cualquier momento, incluso flexibilizar los turnos para limitarlos a un tiempo o no tipo civilization.

Como soy medio masoca pa todo esto, lo que más me pone es preparar estas milongas que hay por debajo.

Vamos a hacer un proxy del servidor. El proxy deberá contener la lógica de negocio que decida qué acciones son permitidas al usuario y cuales no. Es absurdo preguntar al servidor cuando el usuario pincha sobre una casilla en blanco. En un cliente Ajax ni siquiera se generaría un evento javascript para esa celda del mapa. Pues un cliente algo listo, debería detener la ejecución antes de pedir por red al servidor que le describa qué mostrar o qué hacer. Parte o toda la lógica de negocio podría almacenarse en scripts o en clases que se puedan servir al cliente (ya me estoy limitando a una tecnología), al menos aquella lógica que diga qué eventos del usuario superan el ámbito del cliente y tienen que pasar como un comando al servidor: Al final de un turno, por ejemplo, el cliente no debería haber contactado con el servidor para nada y entonces enviar un lote de acciones que gestionar de las que ha hecho el usuario. En un juego como el poker llegarían todas las cartas que ha tirado el usuario al final de su turno pero no de una en una sino en un solo comando.

El proxy del cliente actuará como si ya se han movido sus fichas y podrá ver el tablero actualizado con sus movimientos incluso deshacerlos antes de terminar su turno salvo que las reglas no permitan deshacer… “Carta en la mesa” o como se diga en cada sitio.

Evento: será un gesto del usuario ante la interfaz que se le presenta o cualquier tarea repetitiva o programada que desencadene una acción contra la aplicación, cosas del tipo un click de usuario, arrastrar, o un timer que haga el tick de una animación.

Accion: un evento pasará a ser una acción cuando la lógica de negocio tenga que responder a él bien sea cambiando la vista, el modelo o comunicando cualquier cosa a un posible servidor de la aplicación.

Proxy: Un proxy es una representación de un objeto que no esxiste realmente como tal o que es un modelo sobre el modelo. Explico esto diciendo que si se centraliza un servidor con toda la lógica de negocio, por ejemplo, es bastante absurdo para un cliente que no sea tonto (osea que haya que programar cierta lógica en el cliente) el tener que consultar qué hacer con un click del usuario o con un tick de las animaciones. Ver proxy pattern en wikipedia o donde sea.

Comando: Una acción pasa a ser un comando cuando modifica un proxy o el modelo.


Continuará...

El monstruo de las galletas

Como se sabe, Internet explorer es el navegador más usado. También tenemos la puñeta de que los clientes lo suelen tener como un estándar en sus oficinas, así que definen una consola sobre la que deban las aplicaciones funcionar y siempre aparece esa puta mierda de chapuza con capas encima. Cada nuevo release es un paso dentro del mundo del dolor, nunca una versión es compatible con la anterior, es como si otra marca decidiese crear un nuevo navegador pero conservando todos los fallos del anterior, eso sí. Y también, anuncian que, esta vez de verdad, lo han reescrito desde cero. Ja. Ja... Ja...

Bien. Uno de esos fallos se comenta en esta página:

http://stackoverflow.com/questions/1324181/ie8-losing-session-cookies-in-popup-windows

Consiste, y se habla mucho en la internez sobre ello, en que, cuando le da la gana, al abrir un popup no envía las cookies del padre. Para algunos servidores web esto es una cerdada porque conservan la sesión del usuario en una cookie. No digo que guarden datos importantes, pero el identificador de la sesión si que se guarda en una cookie.

En mi caso, es Java, hay un "jsessionid" que se va pasando en cada petición web para que el servidor reconozca a ese cliente como el dueño de la sesión que él tiene por allí almacenada. Por tanto hay una cookie jsessionid. Pues por javascript o con un simple enlace, abres otra ventana. Es muy común eso de poner lupas para buscar valores, un popup de alerta o lo que sea. Se abre la ventana y pumba, pantalla de login porque el servidor no reconoce la sesión...

Mi solución: Mi solución es poner una página en blanco con un javascript para solucionar el tema este. Es javascript porque se tiene que ejecutar en el cliente. A esta página se le envían los parámetros y la acción que queremos ejecutar en el popup, se carga, se ejecuta este javascript y, después, se recarga la página con la acción que se quería hacer desde un principio.

Mi javascript es muy muy sencillo, lo que hace es copiar las cookies de la ventana padre en caso de que sea Internet Explorer. Al ser IE el objeto window tiene opener:

if (window.opener) {
document.cookie = window.opener.document.cookie;
}

//TODO reload here!

Probado, funciona.



--
Nescit vox missa reverti.

El IE y sus locuras

Ocurre que en Internet Explorer, en versiones menores al 7, no se pintan las transparencias en los PNG... Me está jodiending mis imágenes porque las pinta en 8 bits aunque tengan transparencias graduales (Alpha)...

Una posible solución: http://homepage.ntlworld.com/bobosola/

Pero es bastante, aunque diga que no, invasiva. No podría usar las imágenes en los estilos...

¡Cagonlapús! A buscar la forma de pintar mi pantalla...

Actualizo: Una solución "oficial" de Microsoft que probaré mañana: http://support.microsoft.com/kb/294714

Actualizo. La solución definitiva: Decir al usuario que se instale Firefox o, por lo menos, que actualice el Exploter. Pero hay otra: http://www.twinhelix.com/css/iepngfix/

Querido Javascript

Querido Javascript:

No te ajunto más.

A cup of my famous java

Javascript e Internacionalización.

No se por qué lo llamamos "internacionalización"... Si viene diciéndose traducción o doblaje de toda la vida. Pero nada, nada, la cosa es poner letra por letra la misma palabra y a españolear.

Pues nada que, tonto de mí, iba a hacer un par de funciones para poder internacionalizar mi javascript y, de paso, hacer un favor a la línea en la que trabajo en Capgemini para facilitar la separación de javascript incrustado de las jotasepeses... Es una lacra que tenemos que pagar para entregar a tiempo. Símplemente se escribe el javascript, o peor, se copia de otra página.

Pocas cosas aprendí de mi empresa anterior salvo que, a veces, puede ser útil tener a alguien revisanding el código que se hace. La verdad es que para revisar el código aquí, aparte de que, como en la anterior empresa, no hay nadie con la capacidad técnica (me incluyo entre los incapaces) se necesitarían varios a tiempo completo ya que la cantidad de código generado en una línea en un día es inabarcable para un refactor bien estudiado. Pero se debería hacer para evitar tanta repetición y tantas barbaridades y patadas a las biblias (si las hay) de esto del desarrollo web.

Cada línea de javascript que se escribe es un paso a la tumba. Hay quien dice que así, en cliente va todo más rápido y casi sin frotar... Pero es que hay que depurarlo y cuando se corta y se pega en otra página hay que depurarlo dos veces... Y cuando se corta y se pega en otra página y, además, se modifica para que cuando pintaba X ahora ponga Z pues hay que depurar las dos de antes y seis más para que lo nuevo quede bien.

Yo soy más de aquel tutorial por el que parece que nadie ha pasado ya. Si se lee bien, te enseñan por qué usar JSPs, qué es un documento JSP en contra de una página JSP... Qué es un Servlet y por qué no usar más de uno. Además de proponer todos los patrones de diseño que ahora implementa Struts y que se citan en este libro que tengo por ahí de una vez que me volví loco y me dio por comprar libros.

En el tutorial, aparte de usar un controlador y el patrón command o delegate (hay que tener en cuenta que explican cómo usar Java y no una librería de terceros como es Struts, pese a que Sun se implica en el desarrollo de Struts) y de todas las pariditas que a uno se le ocurran, dicen expresamente que las páginas JSP (mejor usar documentos JSP) deberían poder ser escritas por alguien que no tenga ninguna capacidad como programador. Cualquiera con Dreamweaver o Notepad y un poco de idea sobre lo que es un tag HTML debería poder aprender a maquetar para nuestra aplicación. Así que antes de ponerse al meollo habría que pasear el documento funcional, las maquetas y las descripciones de su funcionamiento por los “expertos” en presentación o por alguien que decida qué tags hay que implementar.

El resultado de esta preparación seria una o varias librerías de etiquetas (custom tags) con sus correspondientes ficheros javascript. Todos estos se pueden incluir como librerías en Dreamweaver, Eclipse, Netbeans o a puro ojo en las maquetas con el edit de la línea de comandos.

El maquetista aprenderá a utilizar las etiquetas y a marcar tal o cual opción. Los TLD hoy dia son bastante descriptivos llegando incluso a presentar al cliente (maquetista) los posibles valores para los atributos de la etiqueta.
Visto así nunca haría falta escribir una sóla línea de javascript en las páginas. Salvo, por ejemplo, cuando sea estrictamente necesario. Un ejemplo de esto sería cuando usando Dojo queremos filtrar los parámetros que uno de los tags de Struts2 deberá enviar al servidor para actualizar un DIV pro Ajax…

Bueno… Dada la turria esta que acabamos de tener… Que me he salido totalmente del tiesto, etc… Volvemos al tema.

En mi trabajo ahora mismo utilizo, incluso, Struts1.1. Raro, me decían, que no trabajéis con una beta, ya que las empresas son tan estúpidas de utilizar herramientas tan anticuadas aun siendo gratuitas y no habiendo cambiado su funcionalidad ni las interfaces sino mejorado con el tiempo. Ahora mismo podríamos tener la versión posterior con más bugs corregidos y más facilidades de uso como DownloadAction, cosa necesaria para mis planes y para unas pariditas que he estado haciendo esta semana exportanding cartas en formato PDF…

La cosa estaría en poder internacionalizar el javascript. Actualmente uno de los mayores problemas que tenemos es que en el javascript incrustamos valores que vienen de la petición. Aún hay doctorandos (tócate los cojones) que quieren acceder a la request desde código ejecutado en el cliente (eso es javascript). Tontos aparte, todos sabemos que javascript es texto y, una vez escrito, salvo con algún eval() no se puede cambiar. Así tenemos parámetros a funciones o valores de variables sacados con escrituras de EL (Expresión Language) en mi caso y en el de la gente que trabaja conmigo a los que invito a aprender un poco más, que siempre es bueno. También hay quien escribe scriplets y le cortamos las manos o le dejamos por imposible y le reescribimos lo que haga para no enfadarle porque, encima, se enfadan. Tambien se escriben con bean:write.

La cuestión es que si queremos extraer el javascript de las páginas tendremos que declarar funciones con muchos parámetros para poder pasarles estos valores en su llamada. Los valores se pintarán en la JSP en la sentencia que llama al javascript que estará incluido en un fichero .js.

¿Y los mensajes al usuario? Pues lo mismo. Siempre se pintan con bean:message, ${el} (o con scriplets, no puedo vigilar todo lo que se hace). Y tenemos el mismo batiburrillo. Así que una función para validar un formulario una vez pasada a un fichero externo va a tener una interfaz enorme de la forma:
validate( document.forms[‘miform’], msg1, msg2, msg3, msg4 …);

Porque puede haber muchísimos mensajes de error.

Bueno, pues la solución que se me ocurrió es hacer una función javascript que se descargue los recursos de la aplicación ya internacionalizados (que pasen por la parte online) y que pinte el String que corresponda con la clave que se le de.

Surgen problemas, cada petición de un string a la función generará una petición de los recursos… Esto se puede saltar porque se puede hacer la petición con http GET para que no se cachee en el cliente. Si es que se ha configurado el controlador con parámetros para saltarse la caché del cliente, se podría configurar otra instancia del consolador o un servlet aparte que haga sólo de servidor de recursos.

Así que con una sóla función podríamos internacionalizar la aplicación completa. Pero aun así me estan comiendo los problemas… Tenemos problemas porque el cliente no va a permitir estas chorraditas. Son pariditas molonas pero me se salen del framework, muchacho y como pa hacerme entender el argumento a estas alturas de la película. A mi ponme un solo servlet y no se te ocurra escribir los recursos al cliente que te caneo… Y ya podrás argumentar y regatear que te van a cortar las alas.

Además esto va un pelín en contra de aquello que escribí arriba muy arriba de no ser intrusivo con la página. Cuanto menos código escribamos en la jsp mucho mejor. Una línea menos de javascript, un peldañito más al cielo… Y jQuery se hizo.

Ni por el forro de los jueves podríamos usar jquery en un proyecto. Los clientes se nos iban a chiflar y no veas de qué manera… Bueno, eso también pasa por preguntar y no meterlo sin decir nada a ver si ni lo miran… Pero bueno… Tenemos el problema.

Pero qué cojones. Voy a dejar de ayudar a la empresa y hacer como aquel fulano griego: Ayúdate a ti mismo. Para mis propósitos, si alguna vez tengo que pintar javascript internacionalizado, voy a utilizar jquery, cosa que intento aprender y este plugin para poder incluir mensajes. Además mi acción para descargarme recursos desde el cliente sigue siendo útil: Incluso el plugin jquery me envía el locale del cliente por si no le gusta el que su navegador envía en la petición.

Así quedará una página del tipo holamundo con jquery, el plugin y mi action de descarga de recursos:


Las peticiones hechas por el cliente vistas con firebug:



Y la página en pantalla:


Quod erat demostrandum ^g^

El IE7 y sus locuras

Dolores de cabeza y la chepa angustiada hemos tenido cierto tiempo durante los últimos días.

Ocurre que hay un bug en IE7 en la implementación de la función getElementsByTagName() de su motor javascript. El error ese descrito en muchos foros de internez consiste en que si pides todos los nodos, pasando como parámetro “*”, la función devolverá el conjunto vacío.

Pues hay más. Tengo testigos de que lo que voy a relatar es cierto, que nos hemos roto la cabeza con ello y que dimos con la solución probando cosas tontas a la desesperada.

En muchas páginas de una aplicación que tenemos medio entregada utilizamos una función que nos sirve para que el navegador interprete los bloques script que se incluya dinámicamente mediante AJAX. En esta función utilizamos esa famosa función getElementsByTagName() con buenos resultados en todos los navegadores hasta ahora.

En una nueva aplicación cuyo desarrollo se ha puesto en marcha recientemente y sólo en una de las páginas incluidas nos ocurría que la llamada a getElementsByTagName (“script”) devolvía siempre una lista vacía. Probamos a poner el parámetro en mayúsculas y nada…

Probamos a recorrer el árbol a mano desde firstChild while(nextSibling)… El nodo script no aparecía en el dom. Metimos el nodo dentro de un span y dentro de un div y no aparecía en todo el árbol.

Hubo un momento de luz en el que el nodo apareció, quitamos el recorrido hecho a piñón y la llamada a la función esa de marras pasó a funcionar. Lo dejamos ir como si no hubiéramos visto nada.

Al rato ¡Zas!, otra vez. ¿Qué habíamos hecho? ¿Qué habíamos cambiado antes para que funcionase? ¿Qué hicimos ahora para que dejase de funcionar?

Pues una tontería tan gorda como esta:

Jsp incluida por ajax, primera versión que no funcionaba:
<%--cabeceras--%>
<%--bloque script--%>
<%--un div con cosas--%>

Jsp incluida, segunda versión que funcionaba:
<%--cabeceras--%>
<%--un div con cosas--%>
<%--bloque script--%>

Después la página se manipuló para quitar cosas sobrantes y dejar el script que iba a generar el contenido final para el “div con cosas”:
<%--cabeceras--%>
<%--un div sin cosas--%>
<%--bloque script que genera las cosas para el div sin cosas--%>

Esa página no funcionaba. La “lógica” nos decía que lo que habíamos hecho es quitar contenidos a la página así que añadimos un texto (un literal) escrito antes del div de forma que la página se quedó en:
<%--cabeceras--%>
<%--un div sin cosas--%>
test
<%--bloque script que genera las cosas para el div sin cosas--%>

Y, carajo, funcionó. Risas… Fiesta… Pedro, Pedro, ven acá que necesito un testigo pa esto…

Versión final de la página, para que el texto no estorbe:
<%--cabeceras--%>
<%--un div sin cosas--%>
&nbsp;
<%--bloque script que genera las cosas para el div sin cosas--%>

Hasta conseguir...

A cup of my famous Java

¡Ahhhhh! Las manos ociosas son la semilla del diablo. Con tiempo en las manos otra vez puedo retomar las tonterías de siempre. Este fin de semana de medio descanso medio oficina no he tocado el compilador, antes me he puesto con 3dmax otra vez y a hacer "papercrafts", figuritas de papel en broma para unos compañeros de la ofi, espero que les molen. Me reí mucho haciendolas y me han quedado aceptables.

Pero Java, java, esto era de Java y algo quería contar... Ah, sí, la cosa iba de struts 2 y struts. Bueno, en realidad debería decir struts1.3 y struts2 ya que en esto no va la cosa como con el cine y eso que uno dice Regreso al Futuro y Regreso al Futuro II... Pero no Regreso al Futuro I, ya que nunca existió...

Bien, pues por qué con un proyecto funcionando y al que sólo faltaba la maquetación, validaciones de entrada y un par más de diálogos le hay que repasar toda la interfaz de usuario y mudarse a struts2... Pues por cuestiones de productividad en cuanto a la interfaz. El mantener los componentes que yo mismo estaba haciendo me hacía perder muchiiisimo tiempo en escribir estúpido, estúpido, estúpido y sucio javascript que, aunque mantenía separado de mis jotasepeses, seguía siendo javascript que yo mismo tenía que mantener...

Uno que es dado a esto de pelearse con librerías, se metió con DOJO dándose cuenta de que todo venía ya hecho, más que probado y hasta en explotación. Es más, se entera uno de que la librería de componentes visuales de Struts2 se basa en DOJO y hasta se separa de DOJO si falta hiciera... Así que, qué carajo, a por Struts 2.

Una del par de pantallas que me quedan por hacer es un editor. Tenía otro pero era un cacota de textarea... Ahora gracias a las librerías tengo un editor con el que obtener html completo donde mis usuarios pueden editar entradas, poner imágenes, cambiar tipos de letra... Sólo por esa tontería había que incluir DOJO y sólo por incluir DOJO y no tener que escribir ni una sola línea más de la cuenta en cuanto a javascript se refiere... Struts2

Struts 2 Autocompleter y JSONOptionsResultType

Juganding con Google Code he creado un proyecto con una sola clase, le he visto cierta utilidad y dije yo, qué carajo, vamos a compartir que de eso se trata. Al final los informáticos somos como aquellos románticos que cultivan el perejil en el sketch de Faemino y Cansado… Lo hacemos todo por amor al arte y todos nos beneficiamos de ello…

Con los foros no, están llenos de retrasadinos, pero en muchos otros sitios hay mucho que aprender y bastante de ello aprovechable.

Esta vez me toca a mí poner un granito de arena. Quizá publique una pequeña librería de componentes visuales que tenía montada sobre los de Struts 1.3.8, les tengo que lavar la cara, pero puede que los deje chulos y los publique, les veo utilidad para quien quiera o tenga que seguir pegándose con ese framework.

He hecho una clase estúpida pero que me quita dependencias y dolores de cabeza… Soy yo de esos que prefiere tener controladas las tecnologías que usa en los proyectos, sobre todo porque cuando me preguntan y no se de algo, hasta me da vergüenza, y de esos que dice felix qui potuit rerum cognoscere causas aunque sea mentira ya que es uno más feliz en la ignorancia de bastantes cosas…

Así que en el ejemplo de Struts2 utilizan pffff… ni me acuerdo… Un template Velocity que en mi proyecto uso para que mis usuarios editen páginas web y cuyo uso quiero limitar a esto y no salirme de lo que es Java y JSP para presentación. Así que, siguiendo las filosofías de Struts2 y de Webworks, me he construido mi propio tipo de resultado “result type” de forma que si un action mapea su result para que pase por mi transformador, éste obtendrá una lista de la pila de valores y la pintará al cliente en forma de JSON para que los autocompleter se puedan rellenar dinámicamente.

Guay, chulo, furrulanding y quitada dependencia del framework para dejarla sólo en mi lógica de negocio, de donde nunca debió salir.

Dejo el enlace al proyecto tonto que he creado con una sola clase ^g^. Qué ridiculez.



http://code.google.com/p/jsonoptionsresulttype



A cup of my famous Java

Ha vuelto la programación. Programación Web en este caso.

He decidido reabrir viejas heridas, como a diario. Me he vuelto a poner con viejos proyectos y he estado buscanding incluso alojamiento web por si algún día se ponen en público uso. Por lo menos yo les veo utilidad.

En estos primeros pasos de adaptar a web lo que antes era un mero script en Java (sí, Java es un lenguaje de script), me ha dado quebraderos de cabeza. Puestos a hacerlo bien, ya que lo hago, he echado más tiempo en arrancar metiending librerías al proyecto y hacieding que funcionen a la vez que lo que programo en realidad.

He metido de todo lo que yo creo que son estándares del mercado web en Java y he pasado de Struts2 que sigue siendo experimental en su mayor parte, aunque era lo que tenía previsto, meterme en Struts2, por lo menos para aprender algo nuevo. Pero liándola con Spring e Hibernate también se aprende. Lo uno porque no lo había utilizado nunca y lo otro porque lo que hago en el curro con ello no tiene ni la remota paredicencia con esto.

Pero lo que iba a comentar era lo del Ajax. Ajax es la forma elegante de decir que cargas cachos de página sin recargarla toda usando Javascript por aquello de ahorrar ancho de banda y recursos en el servidor.

Me pasé un tiempo remirando el estado del arte por los ahises y no me acababa de convencer. He visto ajax-tags que generan javascript y que se integran con Struts, también eso de Ajax Anywhere... Y más cosas como implementaciones que dependen sólo de cliente...

Son cosas como cañones de grandes para matar mi mosca. La mosca es cambiar algún cachico de página, cosa que puedo conseguir haciendo el post con XMLHttpRequest a pelo con un código que amablemente plagié de Peter ^^.

Vale, lo que descarté de todos los otros era que no se podía manejar un redirect devuelto por el servidor. pero es que después de tirar un poco de la manta resulta que el XMLHttpRequest [wiki, w3c] no soporta redirections... Lo que hace es pedir lo que sea al navegador y puedes ir viendo cómo cambia de estado y cómo se pide otra dirección en debug pero, en tiempo de ejecución, no hay acceso ni a la URL de la petición por mucho que cambie...

Pos estamos chungos. Hombre, o invades las páginas con cienes de líneas de supérfluo javascript o usas un redirect... Es que con lo bien que nos iba cuando tras modificar un registro podíamos redireccionar para que se vuelva a pedir la lista actual y ver los cambios... Qué felices eramos entonces... Bueno, pues nada, que ha habido que hacer una solución "ad hoc" que no deja de ser cerda como sólo el Javascript en una página puede ser... No invasivo con las acciones... No invasivo en las páginas que lo incrustan... ¡Oh, Dios! ¡Cómo me gusta el resultado, carajo!

Si no es a lo cerdo, tendremos que esperar, porque al parecer en el w3c sugieren que en próximas implementaciones van a dejar que manejemos los redirect como nos salga... Verase cuando se vea.

Salú.