20090629 lunes junio 29, 2009

Script para ordenar una tabla html print friendly (2/2)

Bueno, pues lo prometido es deuda. Vamos a hacer print friendly el soberbio script TinyTable Sorter de Michael Leigeber.

Las técnicas para hacer que una página web sea print friendly, término que se podría traducir por página web amigable para la impresión, aplicadas en el desarrollo de aplicaciones web, nos dan diferentes beneficios. El más inmediato es el ahorro de tiempo al no tener que confeccionar listados para imprimir al poder reutilizar las pantallas para este fin.

Empecemos ya con la transformación. Lo primero que tenemos que hacer es tener una hoja de estilos especifica para el media print, es decir, para cuando se use la impresora en vez de la pantalla, o estemos en modo "vista previa de impresión". El fichero para ese estilo lo llamaremos print.css, y para empezar le pondremos el selector de clase siguiente:

.rowhidden { display: table-row }

cuyo efecto consiste en hacer que el elemento con dicha clase se visualize con la propiedad CSS display en modo table-row. Este valor, a pesar de ser el estándar de la W3C.org para mostrar una fila de una tabla, no es válido para los raritos IE 6-7, el IE8 por fin, sí soporta la propiedades table-row.

En segundo lugar añadiremos este mismo selector de clase al final de la css utilizada por defecto y que se llama style.css, pero con estos otros valores:

.rowhidden { display: none } 

que lo que hará es ocultar los elementos con dicha clase.

Se utiliza esta propiedad CSS en vez de visibility por ser crossbrowser y, porque al usarla, el elemento desaparece del flujo de visualización, es decir, no ocupa espacio, al contrario que visibility cuyos valores no son crossbrowser y además el elemento oculto sí que ocupa su espacio en la página.

En tercer lugar la css para la impresora la incluiremos en nuestra página después de la css utilizada por defecto, para que tenga mayor prioridad. Además indicaremos al navegador que dicha hoja de estilos sólo es aplicable para la impresora. El código quedará así:

<link rel="stylesheet" href="style.css" />
<link rel="stylesheet" href="print.css" type="text/css" media="print"/>

 

Ahora, antes de aplicar los dos cambios al código javascript, una pequeña explicación de cómo funciona el script, con lo que se verá porque no actúa correctamente con la impresora.

En el momento de mostrar la tabla, el script mira si se ha seleccionado la paginación y el tamaño en filas de esta. Entonces a las filas que no se han de mostrar les asigna dinámicamente la propiedad display:none, mientras que a las que hay que mostrar le resetea el valor de display (esto es un hack crossbrowser). Evidentemente el comportamiento en la impresora es el mismo que en la pantalla, y sólo se mostrarán las filas de la paginación, ocultándose el resto.


Para hacer que el Tiny Table se comporte print-friendly, lo que haremos es que a la filas a ocultar les asignaremos la clase "rowhidden" que en modo pantalla tendrá el mismo comportamiento que antes,  permanercerá oculta, pero  que en modo impresora mostrará las filas. Y para las filas a mostrar le quitaremos esta clase con lo que se mostrarán siempre. Con estos dos cambios emularemos el comportamiento que antes se hacía con la propiedad display.

Esto se implementa con dos cambios en dos lineas, en los siguientes métodos del fichero script.js:

sorter.prototype.wk=function(y){
    var t=ge(this.e), x=t.h.cells[y], i=0;
    for(i;i<this.l;i++){
      t.a[i].o=i; var v=t.r[i].cells[y]; t.r[i].className=i%2==0?this.even:this.odd;
[...]
sorter.prototype.page=function(s){
    var t=ge(this.e), i=0, l=s+parseInt(this.pagesize);
    if(this.currentid&&this.limitid){T$(this.currentid).innerHTML=this.g}
    for(i;i<this.l;i++){t.r[i].className=(i%2==0?this.even:this.odd)+(i>=s&&i<l?'':' rowhidden')}
};

Estos cambios habrá que traspasarlos al código condensado (packed.js) si se desea utilizar dicho script que ocupa algo menos espacio, o alternativamente comprimir el javascript normal.

Finalmente podemos tunear la apariencia de la tabla específicamente para la impresión especificando los atributos pertinentes en la hoja de estilos de la impresora. Por ejemplo podemos hacer que no se muestren los controles de navegación por las páginas, quitar las imagenes del fondo y ajustar los colores, con los selectores:

#controls { display: none }
body { background:#fff none; color:#000 }
.sortable th { background: none; color:#000; border-color:#000 }
.sortable .desc, .sortable .asc { background:none }
.sortable .head h3 { background:none }
.sortable td { border-bottom:1px solid #000; border-right:1px solid #000 }

 

Para acabar, hay que aplicar un hack css para hacer display:block para los navegadores IE 6-7, que se consigue duplicando dicho selector antes del estándar. A pesar de esto, IE 7 no repite las cabeceras de las columnas para las otras páginas.

Espero que os sea de utilidad..

 

Avisos:

Esta modificación del script original de Michael Leigeber sólo está probada con FF3 e IE7, por lo que en otros navegadores puede o no funcionar. Este script modificado está disponible libre de cualquier cargo para cualquier proyecto, personal o comercial, bajo una licencia creative commons y se ofrece TAL CUAL y sin soporte gratuito. Además  el autor original no tiene por que apoyar esta modificación y por tanto puede o no ofrecer soporte de pago para ella.

En relación al script original: "TinyTable has been tested in Firefox 2/3, IE 6/7/8, Opera, Safari and Chrome. Please send bug reports to michael@leigeber.com with the subject “BUG REPORT”. This script is available free of charge any project, personal or commercial, under the creative commons license and is offered AS-IS, no free support provided. Click here to inquire about paid support."


Posted by Feliciano Borrego in Java at 20090629 Comentarios[4]

Comentarios:

Muy bueno este aporte!

Tenes alguna forma de que el Tyni Table ordene correctamente las fechas en formato dd/mm/aaaa ? estuve haciendo varias pruebas y no consegui nada, no logro entender del todo como realiza el ordenamiento!

Gracias!

Enviado por nacho cano en julio 27, 2009 a las 12:12 AM CEST #

Por si a alguien le interesa, despues de mucho dolor de cabeza consegui ordenar las fechas en formato dd/mm/aaaa.

El sitio me lo marca como Spam cuando lo comparto, si lo queres me lo puedes pedir por mail!, saludos!!

Enviado por nacho cano en julio 27, 2009 a las 03:18 AM CEST #

Yo uso el formato AAAA/MM/DD y se ordena quitando el cast a Date().

En los comentarios del post del autor original hay varias soluciones publicadas, a pesar de que no está claro el locale que utiliza la persona que propone la solución.

Enviado por feli en agosto 08, 2009 a las 10:43 PM CEST #

disculpa feli, dices que lo ordena dando formato AAAA/MM/DD y quitandole el cast a Date(), me podrias decir cual es el cast, la verdad no se mucho de javascript, ya puse el formato de la fecha asi, pero no se cual es el cast, espero puedas responderme, saludos y gracias

Enviado por adrian en agosto 12, 2009 a las 09:38 PM CEST #

Enviar un comentario:
Los comentarios han sido deshabilitados.