dimanche 30 août 2009

Overflow sur une table qui marche sous IE

Bonjour,
je voulais faire un truc tout simple en HTML : une table avec une scrollbar verticale permettant de faire défiler le contenu tout en gardant les titres des colonnes en haut de la table. Très simple pour FF : 5 min suffisent ! Par contre, comme toujours, là où ça se gatte, c'est avec IE !

Version FF :
Cette table fonctionne parfaitement sous FF : il suffit de rajouter le style overflow: auto; height: 200px; sur le tbody de la table.
Colonne 1Colonne 2Colonne 3Colonne 4
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234


Bien sur avec IE, ça fonctionne pas ! Donc il faut bidouiller un peu :
il faut d'abord une table qui contiendra les titres des colonnes, puis un div contenant une autre table contenant les données. Le overflow sera positionné sur le div uniquement.
En gros :

<table id="tableTitres" style="width:400px">
<thead>
<tr>
<th id="tcol1" style="width:25%">Colonne 1</th>
<th id="tcol2" style="width:25%">Colonne 2</th>
<th id="tcol3" style="width:25%">Colonne 3</th>
<th id="tcol4" style="width:25%">Colonne 4</th>
</tr>
</thead>
</table>

<div id="divContenu" style="height:200px;overflow:auto;width:417px">
<table id="tableContenu" style="width:400px">
<tbody>
<tr>
<td id="ccol1" style="width:25%">1</td>
<td id="ccol2" style="width:25%">2</td>
<td id="ccol3" style="width:25%">3</td>
<td id="ccol4" style="width:25%">4</td>
</tr>
</tbody>
</table>
</div>

Notez : la table du contenu et des titres doivent avoir la même largeur (ici 400px), le div du contenu doit être légèrement plus large (ici 417px) pour avoir la scrollbar sur la droite en dehors de la table
De plus, pour que les titres et les données s'affichent bien en face, on est obligé de préciser les largeurs des colonnes pour qu'elles coïncident.

Ce qui donne :
Colonne 1Colonne 2Colonne 3Colonne 4
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234


Comme vous le constatez, comme les données et les titres ne sont pas dans la même table, les colonnes n'ont pas la même largeur. On peut y remédier en spécifiant les largeurs manuellement : rajouter le style width sur les titres et sur les colonnes :
Colonne 1Colonne 2Colonne 3Colonne 4
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234
1234


Le principal défaut de cette solution est qu'il faut préciser explicitement les largeurs des colonnes. Avec du javascript, on peut faire très facilement un patch qui met automatiquement la largeur des colonnes :

var nbc=4; //nb de colonnes

//table des titres
var tableTitre=document.getElementById('tableTitres');

//table du contenu
var divContenu=document.getElementById('divContenu');

//table du contenu
var tableContenu=document.getElementById('tableContenu');

//largeur de la table des titres
var w=tableTitre.clientWidth;

//regle la largeur du div et de la
//table contenu pour que la scrollbar
//soit en dehors de la table
divContenu.style.width=w+"px";
tableTitres.style.width=w-17;
tableContenu.style.width=w-17;

//regle les largeurs des colonnes
//de la table contenu pour avoir
//exactement les mêmes largeurs
//que les colonnes titres
for(var i=1;i<=nbc;i++) {
var tcolw=document.getElementById('tcol'+i).clientWidth;

var ccol=document.getElementById('ccol'+i);

ccol.width=tcolw;

}

mercredi 5 août 2009

Bug WebSphere avec Struts 2

Bonjour,
j'ai eu un bug en utilisant l'annotation CustomValidator en Struts 2. En effet, quand je passais des paramètres à cette annotations (parameters), la classe plantait à l'éxécution sur le serveur websphere 6.1 :
Caused by: java.lang.ArrayStoreException
at com.ibm.oti.reflect.AnnotationHelper.getReturnValueFromEntry(Native Method)
at com.ibm.oti.reflect.AnnotationHelper.access$000(AnnotationHelper.java:14)
at com.ibm.oti.reflect.AnnotationHelper$AnnotationInvocationHandler.invoke(AnnotationHelper.java:104)

Après avoir retourné la doc Struts 2 dans tous les sens pendant deux heures, en voyant le com.ibm.oti.reflect dans la trace, ça m'a mit la puce à l'oreille : et si c'était pas un bug de la JVM de WebSphere ? (je rappelle WebSphere utilise une JVM IBM et non pas Sun d'où parfois des comportements différents entre les deux implèmentations).

Bingo ! c'est bien un bug de la JVM d'IBM. Y remedier ? pas de soucis, il suffit de télécharger le Java SDK 1.5 SR9 Cumulative pack (le 9 est le dernier en date, 03/03/2009) téléchargeable à l'adresse suivante :
Pour le SDK 1.5 SR9 : http://www-01.ibm.com/support/docview.wss?rs=180&uid=swg24022256

J'ai mis à jour mon WebSphere : magique tout fonctionne à présent ! :)