Javascript e CSS per la stampa di record selezionati in una tabella: l’approccio unobtrusive

Il rinoceronte: simbolo di javascriptHo trovato nel web questo codice javascript per la stampa selettiva di record che possono essere selezionati da una tabella HTML. L’idea è senz’altro interessante e utile, ma non segue la filosofia unobtrusive. Ho cercato di modificarlo seguendo la logica del progressive enhancement.

La regola principale per scrivere codice javascript non intrusivo, banalmente, è pensare che non venga eseguito…! E’ necessario cambiare il punto di vista, pensare che la presentazione della pagina HTML sia sufficiente a sé stessa con il solo ausilio di una progettazione coerente e dell’uso dei CSS. Il codice javascript, servirà soltanto ad integrare le funzionalità offrendo optional ai quali sia possibile rinunciare.
Lo script in questione permette di selezionare attraverso una checkbox una o più righe di una tabella e di stampare, utilizzando l’attributo CSS @media print solo le righe selezionate. Vediamo, dunque, perché non è unobtrusive: se il supporto javascript è disabilitato o comunque non disponibile, la tabella non verrà mai stampata. Questo succede perché gli elementi <tr> della tabella appartengono per default alla classe DONTPrint nella quale la proprietà display è impostata a none. La funzione javascript select_row() provvede a runtime lo scambio della classe di appartenenza dell’elemento <tr> da DONTPrint a DOPrint, che non essendo definita, per default mostra i contenuti.

La logica del progressive enhancement ci fa pensare invece che, non avendo la possibilità di stampare solo i record selezionati, sia almeno disponibile la stampa dell’intera tabella.
Ecco come impostare la pagina secondo questo approccio:

  1. Assegnamo a tutti gli elementi <tr>, per default la classe DOPrint
  2. Al caricamento del documento, mediante una funzione javascript scambiamo la classe dei <tr>, da DOPrint a DONTPrint
  3. Mediante la funzione select_row() ridefiniamo DOPrint solo le righe selezionate

Un po’ di codice:

1
2
3
4
5
6
7
8
9
<!-- Definizione del css per la stampa -->
<style type="text/css">
<!--
@media print {
 .DONTPrint { display:none; }
 .DONTEverPrint { display:none; }
}
-->
</style>

Le due funzioni principali javascript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!-- ... -->
<script type="text/javascript">
 
<!--
// Funzione lanciata in avvio
function init(){
 var myTableRows = document.getElementsByTagName("tr");
  for (i = 0; i < myTableRows.length; i++) {
    if(myTableRows[i].className=='DOPrint'){
     myTableRows[i].className = 'DONTPrint';
    }
  }
}
// Funzione per la selezione della riga
function select_row(row, color) {
 if (row.value=='on'){
 row.value="off";
 row.parentNode.parentNode.style.backgroundColor = color;
 row.parentNode.parentNode.className = 'DOPrint'
 }
 else{
 row.value="on";
 row.parentNode.parentNode.style.backgroundColor = '';
 row.parentNode.parentNode.className = 'DONTprint'
 }
}
// -->
</script>

Il codice HTML per l’avvio:

<body onload="init()">

Il codice HTML per la definizione delle righe della tabella:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- ... -->
<tr onmouseover="mouseover(this,'#cc6600','#cc6600');"
  onmouseout="mouseout(this,'#000000','#000000')"
  class='DOPrint'>
 
<td><input type="checkbox" class='DONTEverPrint'
  name="checkbox1" onclick="select_row(this, '#cccccc');">
</td>
<td>Arnold </td>
<td>M</td>
<td>45</td>
 
</tr>
<!-- ... -->

Una demo dell’intero esempio è disponibile qui

Con l’occasione, ho anche modificato sia l’HTML che il codice javascript dell’esempio per renderlo un poco più vicino alle direttive degli standard W3C. Probablimente questo codice è stato scritto qualche anno fa, quando ancora, purtroppo, la sensibilità dei programmatori in tal senso era piuttosto scarsa.

Conclusioni:

L’utilizzo di un approccio unobtrusive è utile non soltanto per matenere struttura e presentazione della pagina nei rispettivi ambiti, ma anche per acquisire una forma mentis in grado di pensare preventivamente le vere necessità dell’utente, le caratteristiche di base dell’applicazione e gli elementi facoltativi. Infine si può affermare che “pensare unobtrusive” vuole dire in qualche modo aver compreso meglio il funzionamento delle tecniche utilizzate.

Riferimenti ed approfondimenti: