Nell'articoloTabelle con righe a colori alternati abbiamo visto come Javascript combinato ai
CSS consenta di presentare le tabelle a righe e colonne alterne, cosa che altrimenti
richiederebbe un considerevole lavoro di editing dell'HTML. Ora vedremo invece
come sia possibile manipolare e aggiungere funzionalità alle tabelle stesse.
Il "righello" con Javascript
Un altro articolo interessante di A List Apart da cui ho preso spunto per l'esempio
che vado a presentarvi è The
Table Ruler. Si tratta di agevolare la consultazione di una tabella evidenziando
la riga puntata dal mouse. Ci sono alcune considerazioni da fare: in browser moderni
quali Mozilla e Opera, questo si può ottenere facilmente solo attraverso i CSS
in questo modo:
table tr:hover td{background-color: #F9C}
La questione è che Internet Explorer, purtroppo, supporta la pseudoclasse :hover
solo sui link. Una possibile soluzione è utilizzare IE7,
una collezione di funzioni Javascript per estendere il supporto dei CSS, della
trasparenza delle PNG e alcuni metodi DOM per Internet Explorer dalla versione
5.5 . Ma non è questa la strada che intraprenderemo. E non per il mancato supporto
della regola CSS indicata sopra, ma per un motivo ben più importante. Un effetto
rollover generalmente è associato a un link, e l'utente è abitutato, quando vede
una transizione di stato di un elemento, a cliccarci sopra pensando che sia un
link. Per questo motivo, a parer mio, è altamente sconsigliabile avere un effetto
rollover su qualcosa di diverso da un link.
Supponiamo di avere una tabella con dei prodotti o dei dati e che per ogni
riga ci sia la possibilità di visualizzare una pagina di dettaglio. In tal caso
disporre di un righello che estende la cella contenente il link alla pagina di
dettaglio su tutta la riga potrebbe risultare molto utile, e si ripristinerebbe
il naturale scopo del rollover. Per l'esempio ho preparato una tabella contenente
un po' di link tra i miei preferiti:
Nome Sito | Descrizione | Contenuto | Link |
---|---|---|---|
Alistapart | Articoli sul webdesign | CSS, Accessibilità, Scripting, Tipografia | http://www.alistapart.com |
Brainjar | Tutorial e teoria | CSS e DOM | http://www.brainjar.com |
W3Schools | Tutorial per esempi | Html, CSS, PHP, ASP, XML ecc.. | http://www.w3schools.com |
W3C | Le reference ufficiali | CSS,HTML, Accessibilità, DOM ecc... | http://www.w3c.org |
HTMLhelp | Elenco tag e validatori html e css | HTML e CSS | http://www.htmlhelp.org |
Ora ecco come la trasformeremo con un po' di CSS
e Javascript. Come si vede, abbiamo aggiunto un righello che oltrettutto
"estende" l'area cliccabile del link all'intera riga relativa. Ecco l'unica regola
CSS aggiuntiva oltre la normale presentazione della tabella, ponendo che questa
abbia id "tabella1":
#tabella1 tr.corrente td{background-color: #fcf;border-color:#fcf}
Ora veniamo al Javascript, che ha il compito di aggiungere il righello e associare
l'evento onclick al link di ciascuna riga corrispondente:
onload=function(){
Righello("tabella1");
}
function Righello(IDtabella){
trs=document.getElementById(IDtabella).tBodies[0].rows;
for(i=0;i<trs.length;i++){
tds=trs[i].cells;
trs[i].link=tds[tds.length-1].getElementsByTagName("a")[0].href;
trs[i].title= "Visita " + trs[i].link;
trs[i].style.cursor="pointer";
trs[i].onclick=function(){document.location.href=this.link};
trs[i].onmouseover = function(){this.className="corrente";}
trs[i].onmouseout = function(){this.className="";}
}
}
Due parole di commento sul funzionamento dello script. La funzione Righello
viene richiamata al caricamento della pagina con parametro l'id della
tabella su cui attivare il righello. Vengono passate tutte le righe, e per ogni
riga si reperisce il link dall' ultima cella, si aggiunge un title
e si associano gli eventi onmouseover, onmouseout e onclick. Questo è tutto.
Mostrare e nascondere colonne in una tabella
Sinceramente non so se questo e il prossimo esempio potranno trovare riscontro
pratico nelle vostre pagine, ma sono senza dubbio dimostrativi della potenza di
Javascript/DOM e utili a fini didattici per chi è un po' pratico di questo linguaggio
di scripting.
Javascript ci consente di andare a reperire il contenuto delle celle di una
tabella e di agire sugli stili dei vari elementi. Combinando le due cose è quindi
possibile ricercare in una tabella la colonna con una data intestazione e nasconderla
per intero. A differenza degli script che abbiamo visto finora, quato viene invocato
a richiesta dall'utente. Vediamo com'è la chiamata alla funzione per nascondere
la colonna con intestazione "Descrizione" della tabella con id "tabella1":
<a href="javascript:NascondiColonna('tabella1','Descrizione');">Nascondi la colonna con descrizioni</a>
In sostanza la funzione "NascondiColonna" riceve l'id della tabella e il testo
dell'intestazione della colonna da nascondere. Stessi paremetri per la funzione
duale "MostraColonna". Ho pensato anche che sarebbe utile attraverso Javascript
ripristinare la tabella alla sua presentazione originale: la funzione "Ripristina"
serve proprio a questo scopo e riceve come unico parametro l'id della tabella.
Prima di vedere lo script per intero, vediamo l'esempio.
Ed ecco il codice, che risulta un po' più articolato di quelli visti finora:
function NascondiColonna(IDtabella,voce){
ModificaColonna(IDtabella,voce,"none");
}
function MostraColonna(IDtabella,voce){
ModificaColonna(IDtabella,voce,"");
}
function ModificaColonna(IDtabella,voce,display){
ths=document.getElementById(IDtabella).tHead.rows[0].cells;
for(i=0;i<ths.length;i++){
htext=ths[i].firstChild.nodeValue;
if(htext==voce)
colonna=i;
}
if(colonna>=ths.length) return;
ths[colonna].style.display=display;
trs=document.getElementById(IDtabella).tBodies[0].rows;
for(i=0;i<trs.length;i++){
tds=trs[i].cells;
tds[colonna].style.display=display;
}
}
function Ripristina(IDtabella){
var trs=document.getElementById(IDtabella).tHead.rows;
ths=trs[0].cells;
for(i=0;i<ths.length;i++) ths[i].style.display="";
trs=document.getElementById(IDtabella).tBodies[0].rows;
for(i=0;i<trs.length;i++){
tds=trs[i].cells;
for(j=0;j<tds.length;+j++)
tds[j].style.display="";
}
}
Due parole sull'implementazione. Le funzioni "NascondiColonna" e "MostraColonna"
hanno un comportamento molto simile. Entrambe devono ricercare la colonna della
voce di intestazione della tabella che viene passata come parametro insieme alla
tabella stessa. Fatto ciò, dovranno entrambe ciclare sulle varie righe e agire
sulla proprietà CSS display della cella alla colonna corrispondente.
L'unica differenza sostanziale è il valore su cui imposteranno tale proprietà.
Da questo regionamento, la scelta migliore è realizzare una funzione di appoggio,
che ho chiamato "ModificaColonna" che riceve appunto il valore da attribuire alla
proprietà display come terzo parametro. La funzione "Ripristina" invece non fa
altro che ciclare su tutte le righe della tabella (header incluso) e cella per
cella annullare eventuali impostazioni della proprietà display di ciascuna. Ci
sono alcune considerazioni ulteriori da fare, ne parleremo nel prossimo ed ultimo
esempio.
Filtrare le righe in una tabella grazie a Javascript
Supponiamo di disporre di una tabella di prodotti con codice, prezzo e disponibilità,
e avere la possibilità di "interrogare" la nostra tabella, mostrando solo i prodotti
che corrispondono a determinati parametri. Una funzione Javascript che svolge
questo ruolo è la funzione "Ricerca", che viene richiamata tramite un link in
questo modo:
<a href="javascript:Ricerca('tabella1','Disponibile','Si')">Mostra solo prodotti disponibili</a>
<a href="javascript:Ricerca('tabella1','Prodotto','acciaio')">Mostra solo prodotti in acciaio</a>
<a href="javascript:Ricerca('tabella1','Foto','<img')">Mostra solo prodotti con foto</a>
I parametri della funzione sono nell'ordine l'id della tabella, la colonna
corrispondente e il testo che va ricercato all'interno della cella. Vediamola,
insieme alla funzione "Ripristina" che consente di mostrare la tabella per intero:
function Ricerca(IDtabella,voce,valore){
tdh=document.getElementById(IDtabella).tHead.rows[0].cells;
for(i=0;i<tdh.length;i++){
htext=tdh[i].firstChild.nodeValue;
if(htext==voce)
colonna=i;
}
if(colonna>=ths.length) return;
trs=document.getElementById(IDtabella).tBodies[0].rows;
for(i=0;i<trs.length;i++){
testo=trs[i].cells[colonna].firstChild.nodeValue;
if(testo.indexOf(valore)==-1) trs[i].style.display="none";
}
}
function Ripristina(IDtabella){
trs=document.getElementById(IDtabella).tBodies[0].rows;
for(i=0;i<trs.length;i++){
trs[i].style.display="";
}
}
La funzione è abbastanza semplice. Come nell'esempio precedente reperisce nella
tabella individuata da IDtabella l'indice della colonna a cui corrisponde nell'header
il testo passato come secondo parametro. Vengono poi passate tutte le righe e
nascoste quelle che non contengono la stringa di testo passata come terzo parametro.
La funzione "Ripristina" si occupa invece di ripristinare tutte le righe.
Vediamo un esempio. Prima di proseguire oltre,
ci sono alcune considerazioni da fare.
Database, tabelle, e linguaggi lato server
Senza dubbio l'utilizzo di database per memorizzare i prodotti e interrogazioni
lato server (PHP o ASP ad esempio) con form (select, checkbox e campi di ricerca
multipli) sono una soluzione decisamente migliore per l'usabilità, anche perchè
consentono di scrivere nell'HTML solo gli elementi della tabella che effettivamente
verranno visualizzati, di paginare i risultati e di non avere limiti numerici
sui prodotti. Ma se non si dispone del supporto di una tecnologia lato server,
si può sempre utilizzare una versione Javascript, magari migliorandone l'interfaccia
proprio attraverso un form nella pagina stessa. La funzione che ho appena presentato
si presta certo a ricerche molto elementari, ma un'analogo lato server richiederebbe
molto più tempo per la codifica. C'è ancora una questione da considerare però....
Javascript e il DOM
Bisogna considerare che ci sono persone che non hanno Javascript abilitato,
oppure navigano con browser obsleti che non hanno un adeguato supporto del DOM.
Non si può presentare loro una funzionalità nella pagina di cui non possono beneficiare:
in tal caso è meglio nasconderla. Una buona combinazione di CSS e Javascript può
rivelarsi risolutiva per migliorare l'usabilità: vediamo come procedere.
La nostra pagina ha due tabelle. Per ogni tabella c'è anche un div
che contiene alcuni link per filtrarle. Questi due div vengono nascosti
via CSS in questo modo:
div#t1ricerca, div#t2ricerca{display:none}
Al caricamento della pagina uno script verifica il supporto DOM del browser e in caso di riscontro positivo, mostra i due div di ricerca:
onload=function(){
if(document.getElementById){
document.getElementById("t1ricerca").style.display="block";
document.getElementById("t2ricerca").style.display="block";
}
}
In questo modo, se l'utente ha Javascript disabilitato, o il suo browser non
supporta il DOM, i div di ricerca resteranno nascosti.
Conclusioni
Si conclude qui il mini-viaggio sulla presentazione e manipolazione delle tabelle
tramite Javascript. Con gli ultimi due esempi ho voluto mostrare cosa sia possibile
fare tramite grazie al DOM. Al di là delle applicazioni pratiche, spero che possano
costituire uno spunto e uno stimolo allo studio per l'appassionato. Nell'archivio
zip allegato all'articolo, trovate tutti i file visti negli esempi (il codice
Javascript e CSS è incorporato nei documenti HTML).