Filtrando datos con jQuery
Posted by Gazer in Programación on 25/06/2010
Filtrar elementos dentro de una lista o una tabla para realizar una búsqueda inline con jQuery es bastante simple, solo basta entender un poco donde va cada cosa. La función en cuestión que nos permite hacer esto es filter() que junto con un poco de trabajo para hacer un deep-search dentro del DOM nos da esta funcionalidad.
Por ejemplo si queremos mostrar los elementos de una lista que coinciden con una búsqueda deberíamos hacer algo como :
v = 'some word'; /* Ocultamos todos los LI */ $('#list ul li').hide(); /* Filtramos y mostramos los que coinciden */ $('#list ul').contents().filter(function () { return innerSearch(this, v); }).show();
La función innerSearch la pueden ver en el ejemplo, y básicamente hace un recorrido por el DOM y devolviendo true en aquellos tags donde su contenido de texto contiene el patrón buscado.
Eso nos da muchas posibilidades, ya que por ejemplo en lugar de un simple show se podría aplicar alguna clase CSS para resaltar, modificar el color o lo que se les pueda ocurrir.
Por razones de performance no es muy útil para un DOM muy complejo, pero para el caso donde yo lo necesité funciona aceptablemente bien.
Dejo un ejemplo completo con filtrado en listas y tablas.
HTML5 : Guardar el contenido de <canvas> en el servidor
Posted by Gazer in Programación on 13/04/2010
Hoy tenía ganas de hacer algo distinto (vamos, no quería trabajar
) así que me puse a jugar con HTML5, entre otras cosas con el tag <canvas> para poder dibujar. Luego de bajar varios ejemplos y tener un ‘paint’ andando lo que quería era guardar la imagen, y llegué a este post donde el autor deja guardar en PNG, JPG hasta incluso en BMP el contenido del canvas.
Pero que el usuario se pueda guardar la imagen no era mi idea, era más bien guardarle en el servidor. Por ejemplo para hacer una firma digital y usarla después en el sitio para firmar los posts como si fueran documentos
.
Al principio pensé que iba a ser super complicado, pero me encontré que todo fue mucho más fácil de lo que imaginé. Así que vamos por partes.
Vamos a empezar por el server. Como era muy poco código para este ejemplo, hice una aplicación en Sinatra que me permite mostrar un canvas y luego hacer un POST con los datos. Es ideal en este caso, ya que el server queda de tan solo unas 20 líneas de código :
require 'sinatra' require 'RMagick' get '/' do erb :index end post '/' do # Ya completaremos ... end
Como se puede ver tenemos una vista en el root y el POST lo manejamos también en la raiz. Para procesar la imagen decidí usar la única gema que conozco, RMagick, que buscando en la documentación de ImageMagick me encontré con grata sorpresa que sale leer ‘Base64-encoded inline image’ , que resulta que es justo el formato en que se obtienen los datos desde el canvas
. La única diferencia es que hay que preceder el string con ‘inline:’ y ya estamos, nuestro método POST queda así :
post '/' do data = 'inline:' + request.body.read begin image = Magick::Image.read(data).first image.write('image.png') "alert('Image saved successfully')" rescue "alert('Image format not recognized')" end end
Habría que revisar la documentación y bugs de ImageMagick para ver que tipos de implicancia puede llegar a tener en la seguridad del sitio o del sistema, pero son cosas que no vienen al caso
.
La vista (reducida para el ejemplo) puede resumirse en el siguiente HTML :
<canvas id="example" width="200" height="200">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
<input type="button" id="submit" value="Submit" />Y un poco de javascript :
<script type="text/javascript"> $(function () { $("input").click(function () { // jQuery todavía no habla bien con HTML5, hack para // no usar un plugin. var c = $("#example").get(0); $.post('/', c.toDataURL(), null, "script"); }); // Un dibujito estático para probar var example = document.getElementById('example'); var context = example.getContext('2d'); context.fillStyle = "rgb(255,0,0)"; context.fillRect(30, 30, 50, 50); }) </script>
Y ya estamos, al presionar el botón se envían los datos de la imagen dibujada, si está todo bien ImageMagick creará el archivo en el filesystem y por último devolverá algo de javascript para informar al usuario como salió todo. Obviamente si tuviéramos un sistema de usuarios en el server podríamos guardar la imagen para cada uno, pero de nuevo, no viene al caso.
El resultado final :

$ identify -verbose image.png Image: image.png Format: PNG (Portable Network Graphics) Class: DirectClass Geometry: 200x200+0+0 Resolution: 72x72 Print size: 2.77778x2.77778 Colorspace: RGB Depth: 8/1-bit Histogram: 37500: ( 0, 0, 0, 0) #00000000 none 2500: (255, 0, 0,255) #FF0000 red Page geometry: 200x200+0+0 Compression: Zip Properties: create-date: 2010-04-13T00:20:15-03:00 modify-date: 2010-04-13T00:20:15-03:00 signature: 0a42f3c85d6364e38f14dac554d26c62a90b84b06ac7f22264c9d964657ba8d6 Tainted: False Filesize: 503b Number pixels: 39.1kb Version: ImageMagick 6.5.1-0 2009-08-27 Q16 OpenMP http://www.imagemagick.org
Probado en :
- Chromium 5.0.372.0 (44042) Ubuntu
- Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9
Código completo : html5_canvas_submit
Casa y Casamiento
Posted by Gazer in General, Yo Estuve Ahí on 09/04/2010
Y si, volví para seguir molestando con cosas que a nadie le interesa
. En los últimos meses han pasado tantas cosas que ya ni encuentro un rato para sentarme a escribir
.
Para empezar me volví a mudar, si, si, 4 mudanzas en 4 meses, espero que esta vez sea la definitiva. Ahora, y después de 12 años, volví a mi Cipolletti “natal“, el que me vio hacer tantas cagadas de chico. Y más aún, volví al barrio donde viví toda mi secundaria (a menos de 100 mts de la casa donde vivíamos con mis viejos por esa época), toda una regresión
.
Pero la cosa siguió y finalmente llegamos vivos al casamiento con mi (ex) novia y me tuve que disfrazar de “empresario” para aparentar un poco frente a la familia. Siempre es bueno dar una buena impresión, pero a mi me suele alcanzar con que sea buena o mala
.
La fiesta fue, bueno, una fiesta, si me conocen saben como soy cuando hay joda, así que el resto se lo pueden imaginar. No faltó ni comida y mucho menos para tomar, barra libre, etc, etc … más de uno se fue gateando (yo volví manejando, para variar, en piloto automático). Cuando arrancó la joda, luego de que Nacho Morán (imitador/cantante de Choele Choel) hiciera su gracia, se armó alto bailongo, donde nadie se quedó sentado.
Más entrada la noche una mesa dulce para cortar un poco el alcohol y si te agarra el control de alcoholemia poder mentir que fue por metabolizar los dulces
, aunque hay que se realista, en Cipollettia las 8AM no hay controles
.
Ya cuando los gallos empiezan a cantar empezamos a cerrar la joda con un foto de los valientes que duraron hasta el final.
Por último falta la luna de miel, que se da sobre fin de mes (nada de salir corriendo al otro día, hay que aprovechar las vacaciones
).
Ah, y por si todo fue muy sutil y no se notó en las fotos anteriores, pegue “altas llantas” esa noche
Apple iPad
Bueno, no voy a decir lo que ya todo el mundo ya debe haber leído (no multitask, es un iPod Touch grandote, solo con AT&T bla bla bla)
.
Creo que eso resume más que bien lo que la mayoría de los no-fan de Apple piensan cuando leen la ficha técnica
.
Migrando datos desde PHP a Rails
Posted by Gazer in Programación on 22/01/2010
Por esas cosas de la vida me encontré todo el día de hoy migrando datos viejos de un sistema hecho en PHP a uno hecho en Rails. Las cosas venían bastante simples definiendo modelos de ActiveRecord para las tablas de la base de datos vieja y reinsertando con modelos apuntando a las tablas nuevas. Pero … siempre hay un pero.
Resulta que el hermoso sistema anterior para evitar tener muchas tablas (o vaya a saber por qué) tenía en una parte un tabla donde cada field era un gran TEXT que contenía un array de PHP serializado.
class UserTextField < ActiveRecord::Base set_table_name "usertextfield" set_primary_key "userid" def folders field3 end end $> user = UserTextField.find(3) $> user.folders # => 'a:2:{i:0;s:4:"bkps";i:1;s:6:"listas";'
Justo cuando estaba por ponerme a parsear texto me encontré con php-serialize que permite serializar y deserializar estos string en cómodos tipos nativos de Ruby.
El código final queda entonces algo como :
class UserTextField < ActiveRecord::Base set_table_name "usertextfield" set_primary_key "userid" def folders PHP.unserialize(field3) end end $> user = UserTextField.find(3) $> user.folders # => ["bkps", "listas"]
Y la migración de datos pudo continuar sin problemas
.







