Attention : Le contenu de ces pages n'a pas été mis à jour depuis longtemps. Il est probablement obsolète pour Firefox 4.0/Gecko 4.0 et supérieur. Pour du contenu plus récent, allez consulter developer.mozilla.org.

Cross table

Avoir des panneaux figés comme dans un tableur.

J'utilise une grille à 4 cases :

A B

C D

Dans A, il y a un blanc à combler avec le titre. Dans B, les titres de colonnes Dans C les titres de lignes Dans D le contenu du tableau.

Cet exemple fonctionne bien si vous assurez que la hauteur de C et D sont les mêmes et si les largeurs de B et D sont les mêmes.

Le code

 <?xml version="1.0" encoding="UTF-8"?>
 <?xml-stylesheet href="[[chrome://global/skin/]]" type="text/css"?><window title="XUL Layout"
        [[xmlns:html="http://www.w3.org/1999/xhtml]]"
        xmlns="[[http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul]]"
				onload="init();"
 >
	<script type="application/x-javascript"><![CDATA[
		var scrx=0,scry=0;
		function init()
		{
			document.getElementById("hscroll_tc").addEventListener("DOMAttrModified",scrollit,false);
			document.getElementById("vscroll_tc").addEventListener("DOMAttrModified",scrollit,false);
		}
		function scrollit(ev)
		{
			if(ev.attrName=="curpos")
			{
				if(ev.target.id=="hscroll_tc")
				{
					if(scrx!=ev.newValue)
					{
						scrx=ev.newValue;
						var cx=new Object();
						var cy=new Object();
						var scrtc;
						var xpScroll;
						scrtc=document.getElementById("TC_content");
						xpScroll=scrtc.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
						xpScroll.getScrolledSize(cx,cy);
						xpScroll.scrollTo((cx.value-xpScroll.width)*scrx/100,(cy.value-xpScroll.height)*scry/100);
						scrtc=document.getElementById("TC_top");
						xpScroll=scrtc.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
						xpScroll.getScrolledSize(cx,cy);
						xpScroll.scrollTo((cx.value-xpScroll.width)*scrx/100,(cy.value-xpScroll.height)*scry/100);
					}
				}
				else
				{
					if(scry!=ev.newValue)
					{
						scry=ev.newValue;
						var cx=new Object();
						var cy=new Object();
						var scrtc;
						var xpScroll;
						scrtc=document.getElementById("TC_content");
						xpScroll=scrtc.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
						xpScroll.getScrolledSize(cx,cy);
						xpScroll.scrollTo((cx.value-xpScroll.width)*scrx/100,(cy.value-xpScroll.height)*scry/100);
						scrtc=document.getElementById("TC_left");
						xpScroll=scrtc.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
						xpScroll.getScrolledSize(cx,cy);
						xpScroll.scrollTo((cx.value-xpScroll.width)*scrx/100,(cy.value-xpScroll.height)*scry/100);
					}
				}
			}
		}
	]]></script>
	<hbox flex="1">
		<grid flex="1">
			<columns>
				<column/>
				<column flex="1"/>
			</columns>
			<rows>
				<row>
					<hbox>Titre</hbox>
					<scrollbox id='TC_top' flex="1" style="background-color:#00FF00;">
						<hbox>METTRE ICI MES TITRES DE COLONNES</hbox>
					</scrollbox>
				</row>
				<row flex="1">
					<scrollbox id='TC_left' flex="1" style="background-color:#0000FF;">
						<vbox> METTRE ICI MES TITRES DE LIGNES</vbox>
					</scrollbox>
					<scrollbox id='TC_content' flex="1" style="background-color:#FF0000;">
						<vbox> METTRE ICI LE CONTENU CENTRAL</vbox>
					</scrollbox>
				</row>
				<scrollbar
				 id="hscroll_tc"
				 orient="horizontal"
				 curpos="0"
				 maxpos="100"
				 increment="1"
				 pageincrement="10"
				/>
			</rows>
		</grid>
		<scrollbar
			id="vscroll_tc"
			orient="vertical"
			curpos="0"
			maxpos="100"
			increment="1"
			pageincrement="10"
		/>
	</hbox>
 </window>

Explications

Les deux scrollbars sont gérées en pourcentage. L'une est placée dans la grille intérieure (horizontale) et l'autre à côté de la grille (verticale).

Les objets scrollbox disposent de méthodes pour scroller et connaître leur taille totale (donc avec la partie non affichée). Ces méthodes ne sont pas directement accessible... pour accéder à ces méthodes, il faut réclamer une interface nsIScrollBoxObject ce qui est fait dans le script de scroll.

Les scollbars n'ont pas d'évènement spécial pour gérer le changement de position. On ajoute donc une gestion d'évènement sur la modification de ses attributs dans la fonction d'init.

L'évènement est lancé plusieurs fois pour un seul changement de position (mais pourquoi donc?), pour éviter de lancer plusieurs fois un scroll inutile, on mémorise les positions des scrollbars entre chaque appel.

Le jeu des flex est sensible. Les titres de ligne sont non flexibles afin de prendre toute leur largeur. Les titres de colonnes sont sensés ne faire qu'une seule ligne.


Copyright © 2003-2013 association xulfr, 2013-2016 Laurent Jouanneau - Informations légales.

Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™ sont des marques de la fondation Mozilla.