//////////////////////////////////////////////////////////////////////////////////////////////////
// PROJET : TreeView.js //
// AUTEUR : GOLINSKI Ludwig - Ludinski //
// DATE : Mercredi 21 juillet 04 //
// //
// DESCRIPTION : Implémente toutes les functions nécessaires à la création, à l'affichage et //
// au fonctionnement d'une treeview //
// Ce fichier doit se trouver dans un dossier nommé 'TreeView' et le code qui //
// y fait appel, à la racine de ce dossier //
// //
// CLASSES : TreeView -> Gère l'apparence de la racine, ainsi que celle du cadre situé autour//
// de la treeview ( DIV ). //
// Noeud ----> Gère l'apparence de chacun des noeuds de la treeview ainsi que leur //
// Position dans la treeview. //
//////////////////////////////////////////////////////////////////////////////////////////////////
// VARIABLE GLOBALE CONTENANT L'INSTANCE SUR LA CLASSE 'TREEVIEW'
// IL FAUT UTILISER CETTE VARIABLE
var treeView
// CONSTRUCTEUR DE LA CLASSE 'TREEVIEW'
function TreeView( styleBorder,icoRacine, txtRacine, style, styleOnOver, funOnClick )
{
// chaine contenant l'icone de la racine
this.icone = icoRacine
// chaine contenant le texte situé à côté de l'icone
this.texte = txtRacine
// chaine contenant la classe de style du texte
this.style = style
// chaine contenant la classe de style lorsque le curseur est dessus
this.styleOnOver = styleOnOver
// chaine contenant la fonction à appeler lors d'un clique sur le texte
this.onClick = funOnClick
// Chaine contenant l'index (unique) du noeud
this.index = "0"
// entier contenant la taille horizontale (en pixel) du cadre de la treeview
this.styleBorder = styleBorder
// Nom de la table qui contient le noeud
this.table = "TABLE_" + this.index
// tableau contenant les noeuds fils de la racine
this.tableauEnfants = new Array
// méthodes de la classe
this.Start = TreeView_Start
this.Add = TreeView_Add
this.Contient = TreeView_Contient
this.Noeuds = TreeView_Noeuds
}
// PERMET D'AJOUTER UN NOEUD A L'ARBORESCENCE
// PARAMETRES : icoNoeud - Chaine contenant l'image symbolisant le noeud
// txtNoeud - Chaine contenant le texte affiché à côté de l'icone
// funOnClick - Chaine contenant la fonction (sans les parenthèses) à appeler lors d'un click sur le noeud
// Cette fonction doit prendre deux chaines en paramètres ( l'index et le texte du noeud )
function TreeView_Add( icoNoeud, txtNoeud, style, styleOnOver, funOnClick )
{
// Recherche le prochain emplacement libre du tableau de noeud
var indice = 0
while( this.tableauEnfants[ indice ] != null )
indice ++
// Crée l'index unique du noeud
var indexNoeud = "0_" + indice
// Crée le noeud et l'ajoute dans le tableau
this.tableauEnfants[ indice ] = new Noeud( icoNoeud, txtNoeud, style, styleOnOver, indexNoeud, funOnClick, this )
// retourne le noeud pour pouvoir y ajouter des sous-noeuds
return this.tableauEnfants[ indice ]
}
// PERMET DE LANCER L'AFFICHAGE DE LA TREEVIEW
// A APPELER APRES AVOIR AJOUTER TOUS LES NOEUDS VOULUS
function TreeView_Start()
{
// Crée le DIV où sera intégré la treeview ( qui se muniera de scroll barres si nécessaire )
document.write( "
" )
// Crée un tableau d'une ligne et sans bord
document.write( "
" )
document.write( "" )
// Ajoute l'icone
document.write( "" )
// Change de colonne
document.write( " | " )
// Ajoute le texte
document.write( "" )
document.write( this.texte + "" )
// Referme la colonne et le tableau
document.write( " |
" )
// Parcourt le tableau de noeuds
var indice = 0
while( this.tableauEnfants[ indice ] != null )
{
// Lance l'affichage du noeud
this.tableauEnfants[ indice ].Draw()
// Passe au noeud suivant
indice ++
}
// Referme le DIV
document.write( "
" )
}
// INDIQUE SI UN NOEUD EST PRESENT DANS L'ARBORESCENCE
// PARAMETRE : indexNoeud - Chaine contenant l'index du noeud recherché
// RETOUR : booléen, indiquant si le noeud est présent ou non
function TreeView_Contient( indexNoeud )
{
// Parcourt le tableau de noeuds fils
var indice = 0
while( this.tableauEnfants[ indice ] != null )
{
// Fait appel à la méthode du noeud et vérifie s'il contient ou s'il est le noeud recherché
if( this.tableauEnfants[ indice ].Contient( indexNoeud ) )
{
// Retourne comme quoi le noeud est présent
return true
}
// Passe au noeud suivant
indice ++
}
// Retourne comme quoi le noeud n'est pas présent
return false
}
// PERMET DE RECUPERER L'INSTANCE D'UN NOEUD D'APRES SON INDEX
// PARAMETRE : indexNoeud - Chaine contenant l'index du noeud recherché
// RETOUR : l'instance sur le noeud ou 'null' s'il n'est pas présent dans l'arbre
function TreeView_Noeuds( indexNoeud )
{
// Il s'agit de la racine
if( indexNoeud == "0" )
return this
// Parcourt le tableau de noeuds fils
var indice = 0
while( this.tableauEnfants[ indice ] != null )
{
// Récupère le noeud
var noeudRecherche = this.tableauEnfants[ indice ].Noeuds( indexNoeud )
// Vérifie s'il a été trouvé
if( noeudRecherche != null )
{
// Retourne le noeud
return noeudRecherche
}
// Passe au noeud suivant
indice ++
}
// Retourne comme quoi le noeud n'est pas présent
return null
}
// CONSTRUCTEUR DE LA CLASSE 'NOEUD'
function Noeud( icoNoeud, txtNoeud, style, styleOnOver, indexNoeud, funOnClick )
{
// Chaine contenant l'icone du noeud
this.icone = icoNoeud
// Chaine contenant le texte situé à côté de l'icone
this.texte = txtNoeud
// Chaine contenant la classe de style du texte
this.style = style
// chaine contenant la classe de style lorsque le curseur est dessus
this.styleOnOver = styleOnOver
// Chaine contenant l'index (unique) du noeud
this.index = indexNoeud
// Chaine contenant la méthode (sans parenthèses) à appeler lors d'un click sur le noeud
this.onClick = funOnClick
// Tableau contenant les noeud fils
this.tableauEnfants = new Array
// Indique si le noeud est compacté ou non
this.isExpand = true
// Nom de la table qui contient le noeud
this.table = "TABLE_" + this.index
// Méthodes de la classe
this.Add = Noeud_Add
this.Draw = Noeud_Draw
this.IsEnd = Noeud_IsEnd
this.HaveAChild = Noeud_HaveAChild
this.Contient = Noeud_Contient
this.Noeuds = Noeud_Noeuds
this.Cacher = Noeud_Cacher
this.Montrer = Noeud_Montrer
this.ChangerExpand = Noeud_ChangerExpand
}
// PERMET D'AJOUTER UN NOEUD FILS
// PARAMETRES : icoNoeud - Chaine contenant l'image symbolisant le noeud
// txtNoeud - Chaine contenant le texte affiché à côté de l'icone
// funOnClick - Chaine contenant la fonction à appeler lors d'un click sur le noeud
// RETOUR : l'instance sur le noeud
function Noeud_Add( icoNoeud, txtNoeud, style, styleOnOver, funOnClick )
{
// Recherche le prochain emplacement libre du tableau
var indice = 0
while( this.tableauEnfants[ indice ] != null )
indice ++
// Crée l'index unique du noeud
var indexNoeud = this.index + "_" + indice
// Crée le noeud et le stocke dans le tableau
this.tableauEnfants[ indice ] = new Noeud( icoNoeud, txtNoeud, style, styleOnOver, indexNoeud, funOnClick )
// Retourne le noeud, pour pouvoir y ajouter un noeud fils
return this.tableauEnfants[ indice ]
}
// PERMET D' AFFICHER LE NOEUD SUR LA PAGE
function Noeud_Draw()
{
// Crée la table servant à contenir chaqu'une des icones et le texte du noeud
document.write( "" )
document.write( "" )
// Récupère le booléen, servant à indiquer si le noeud possède ou non un noeud sous lui
var isEnd = this.IsEnd()
// Récupère le booléen, servant à indiquer si le noeud possède au moin un noeud fils
var haveAChild = this.HaveAChild()
// Parcourt l'index du noeud pour déterminer les icones à placer devant le noeud
var indice = 2
while( indice < this.index.length - 1 )
{
// Recherche le nombre de chiffres du nombre suivant
var tailleNombre = 1
while( indice + tailleNombre < this.index.length && this.index.substring( indice + tailleNombre, indice + tailleNombre + 1 ) != "_" )
{
tailleNombre ++
}
// Récupère l'indice suivant
var indiceSuivant = parseInt( this.index.substring( indice, indice + tailleNombre ), 10 )
// Vérifie qu'il y ait un indice et qu'il ne sagisse pas du noeud courant
if( ! isNaN( indiceSuivant ) && this.index != this.index.substring( 0, indice ) + indiceSuivant )
{
// Incrémente l'indice
indiceSuivant ++
// Crée l'index du noeud devant se situer directement en dessous
var indexSuivant = this.index.substring( 0, indice ) + indiceSuivant
// Buffer où sera stocké le nom de l'icone à ajouter
var icone
// La treeview contient l'index créé
if( treeView.Contient( indexSuivant ) )
{
// Met l'icone de la ligne pointillée
icone = "TreeView/PointillesLigne.gif"
}
// La treeview ne contient pas l'index créé
else
{
// Met une icone vide
icone = "TreeView/Vide.gif"
}
// Ajoute l'icone dans la table, puis passe à la colonne suivante
document.write( "" )
document.write( " | " )
}
// Continue à parcourir l'index du noeud
indice = indice + tailleNombre
indice ++
}
// Buffer où sera stocké le nom de l'icone à ajouter
var icone
// Le noeud contient au moin un noeud fils
if( haveAChild )
{
// Le noeud est développé
if( this.isExpand )
{
// Met l'icone indiquant que le noeud peut être compacté
icone = "Moin"
}
// Le noeud est compacté
else
{
// Met l'icone indiquant que le noeud peut être développé
icone = "Plus"
}
}
// Le noeud ne contient aucun noeud fils
else
{
// Met l'icone contenant les pointillés
icone = "Pointilles"
}
// Le noeud ne possède aucun autre noeud en dessous de lui
if( isEnd )
{
// Modifie l'icone pour qu'elle finisse la branche
icone += "Fin.gif"
}
// Le noeud possède au moin un noeud en dessous de lui
else
{
// Ajoute l'extension à l'icone
icone += ".gif"
}
// Le noeud possède au moin un noeud fils
if( haveAChild )
{
// Crée le nom que possèdera l'icone servant à développer/compacter le noeud
var nomIcone = "EXPAND_" + this.index
// Ajoute l'icone en lui indiquant la méthode à appeler lors d'un clique dessus
document.write( "" )
}
// Le noeud ne possède aucun fils
else
{
// Ajoute l'icone
document.write( "" )
}
// Passe à la colonne suivante et lui met l'icone du noeud dedans
document.write( " | " )
document.write( "" )
// Passe à la colonne suivante où sera affiché le texte du noeud
document.write( " | " )
// Crée le nom unique du FONT
var nomFont = "TEXTE_" + this.index
// Ajoute le texte dans la table
document.write( "" )
document.write( this.texte + "" )
// Referme la colonne et la table
document.write( " |
" )
// Vérifie si le noeud possède des fils et s'il est développer
if( haveAChild )
{
// Parcourt le tableau de noeud fils
var indiceNoeud = 0
while( this.tableauEnfants[ indiceNoeud ] != null )
{
// Lance l'affichage du noeud
this.tableauEnfants[ indiceNoeud ].Draw()
// Passe au noeud suivant
indiceNoeud ++
}
}
}
// PERMET DE RECUPERER L'INSTANCE D'UN NOEUD D'APRES SON INDEX
// PARAMETRE : indexNoeud - Chaine contenant l'index du noeud recherché
// RETOUR : l'instance sur le noeud, ou 'null' si le noeud n'est pas présent
function Noeud_Noeuds( indexNoeud )
{
// S'il s'agit du noeud courant
if( this.index == indexNoeud )
{
// Retourne l'instance du noeud
return this
}
// Parcourt le tableau de noeuds fils
var indice = 0
while( this.tableauEnfants[ indice ] != null )
{
// Récupère l'instance sur le noeud
var noeudRecherche = this.tableauEnfants[ indice ].Noeuds( indexNoeud )
// Vérifie qu'il ait été trouvé
if( noeudRecherche != null )
{
// Retourne l'instance du noeud
return noeudRecherche
}
// Passe au noeud suivant
indice ++
}
// Retourne comme quoi le noeud n'a pas été trouvé
return null
}
// PERMET DE DETERMINER S'IL S'AGIT DU DERNIER NOEUD DE SA BRANCHE
// RETOUR : booléen indiquant si le noeud est le dernier de sa branche, ou non
function Noeud_IsEnd()
{
// Recherche le dernier nombre de l'index du noeud
var indice = this.index.length - 1
while( this.index.substring( indice, indice + 1 ) != "_" )
indice --
// Crée l'index du noeud qui devrait se trouver juste aprés celui-ci
var indiceSuivant = parseInt( this.index.substring( indice + 1, this.index.length ), 10 )
var indexSuivant = this.index.substring( 0, indice + 1 ) + ( ++ indiceSuivant )
// Vérifie s'il existe dans la treeview
if( treeView.Contient( indexSuivant ) )
{
// Le noeud existe, il ne s'agit donc pas de la fin de la branche
return false
}
else
{
// Le noeud n'existe pas, il s'agit donc bien de la fin de la branche
return true
}
}
// PERMET DE DETERMINER SI LE NOEUD POSSEDE DES FILS
// RETOUR : booléen indiquant si le noeud possède ou non des enfants
function Noeud_HaveAChild()
{
// Vérifie s'il existe un élément dans la première case du tableau de noeuds fils
if( this.tableauEnfants[ 0 ] != null )
{
// Retourne comme quoi le noeud possède des fils
return true
}
else
{
// Retourne comme quoi le noeud ne possède aucun fils
return false
}
}
// PERMET DE DETERMINER SI UN NOEUD EST PRESENT DANS LA TREEVIEW, D'APRES SON INDEX
// PARAMETRE : indexNoeud - Chaine contenant l'index du noeud recherché
// RETOUR : booléen indiquant si le noeud est présent ou non
function Noeud_Contient( indexNoeud )
{
// Il s'agit du noeud courant
if( this.index == indexNoeud )
{
// Retourne comme quoi le noeud est présent
return true
}
// Parcourt le tableau de noeuds fils
var indice = 0
while( this.tableauEnfants[ indice ] != null )
{
// Vérifie s'il contient ou s'il est le noeud recherché
if( this.tableauEnfants[ indice ].Contient( indexNoeud ) )
{
// Retourne comme quoi le noeud est présent
return true
}
// passe au noeud suivant
indice ++
}
// Retourne comme quoi le noeud n'est pas présent dans la treeview
return false
}
// PERMET DE RENDRE INVISIBLES, LES NOEUDS FILS
function Noeud_Cacher()
{
// Parcourt le tableau de noeuds fils
var indice = 0
while( this.tableauEnfants[ indice ] != null )
{
// Cache la table contenant le noeud
GetElement( this.tableauEnfants[ indice ].table ).style.display = "none"
// Cache les fils du noeud
this.tableauEnfants[ indice ].Cacher()
// Passe au noeud suivant
indice ++
}
}
// PERMET DE RENDRE VISIBLES, LES NOEUDS FILS
function Noeud_Montrer()
{
// Vérifie s'il faut développer ce noeud
if( ! this.isExpand )
return
// Parcourt le tableau de noeuds fils
var indice = 0
while( this.tableauEnfants[ indice ] != null )
{
// Rend visible la table contenant le noeud
GetElement( this.tableauEnfants[ indice ].table ).style.display = "block"
// Rend visibles les fils du noeud
this.tableauEnfants[ indice ].Montrer()
// Passe au noeud suivant
indice ++
}
}
// PERMET DE CHANGER L'APPARENCE D'UN NOEUD
// A APPELER UNIQUEMENT APRÉS LA MÉTHODE TREEVIEW.START()
// PARAMETRE : booléen, indiquant s'il faut déployer le noeud ou le compacter
function Noeud_ChangerExpand( isExpand )
{
// Vérifie si un changement est nécessaire
if( this.isExpand == isExpand || ! this.HaveAChild() )
{
// Retourne de la fonction sans rien faire
return
}
// Récupère l'instance sur l'icone d'extension du noeud
var icone = GetElement( "EXPAND_" + this.index )
OnExpand( icone )
}
// Méthode executée lorsque l'utilisateur développe ou compacte un noeud
// PARAMETRE : ClickedIcone - L'instance sur l'icone concernée
function OnExpand( ClickedIcone )
{
// Récupère l'index du noeud, puis son instance
var indexNoeud = ClickedIcone.id.substring( 7, ClickedIcone.id.length )
var noeudConcerne = treeView.Noeuds( indexNoeud )
// Crée le nom de la table du noeud
var nomTable = "TABLE_" + indexNoeud
// Recherche, dans le chamin complet de l'icone, l'indice à partir duquel son nom commence
var indice = ClickedIcone.src.length - 1
while( ClickedIcone.src.substring( indice, indice + 1 ) != "/" )
indice --
// Récupère le nom de l'icone cliquée
var icone = ClickedIcone.src.substring( indice + 1, ClickedIcone.src.length )
// Met l'icone et le booléen indiquant si le noeud doit être développé, à jour
if( icone == "Moin.gif" )
{
ClickedIcone.src = "TreeView/Plus.gif"
noeudConcerne.isExpand = false
}
else if( icone == "MoinFin.gif" )
{
ClickedIcone.src = "TreeView/PlusFin.gif"
noeudConcerne.isExpand = false
}
else if( icone == "Plus.gif" )
{
ClickedIcone.src = "TreeView/Moin.gif"
noeudConcerne.isExpand = true
}
else if( icone == "PlusFin.gif" )
{
ClickedIcone.src = "TreeView/MoinFin.gif"
noeudConcerne.isExpand = true
}
// Le noeud à été developpé
if( noeudConcerne.isExpand )
{
// Rend les fils du noeud visible
noeudConcerne.Montrer()
}
// Le noeud à été compacté
else
{
// Cache les fils du noeud
noeudConcerne.Cacher()
}
}
// FONCTION APPELEE LORSQUE LE CURSEUR SE TROUVE AU DESSUS D'UN ELEMENT DE LA TREEVIEW
// PARAMETRE : indexNoeud - L'index du noeud concerné
function OnOver( indexNoeud )
{
// Récupère l'instance sur le noeud
var noeud = treeView.Noeuds( indexNoeud )
// Change la classe de style du texte
GetElement( "TEXTE_" + indexNoeud ).className = noeud.styleOnOver
// Compte le nombre de fils du noeud
var nbrFils = 0
while( noeud.tableauEnfants[ nbrFils ] != null )
nbrFils ++
// Affiche le nombre de fils dans la barre d'état du navigateur
if( nbrFils == 1 )
window.defaultStatus = "contient " + nbrFils + " élément"
else if( nbrFils > 0 )
window.defaultStatus = "contient " + nbrFils + " éléments"
}
// FONCTION APPELEE LORSQUE LE CURSEUR SORT D'UN ELEMENT DE LA TREEVIEW
// PARAMETRE : indexNoeud - L'index du noeud concerné
function OnOut( indexNoeud )
{
// Change la classe de style du texte
GetElement( "TEXTE_" + indexNoeud ).className = treeView.Noeuds( indexNoeud ).style
// Efface le texte contenu dans la barre d'état du navigateur
window.defaultStatus = ""
}
// FONCTION PERMETTANT D'OBTENIR UN ELEMENT DE LA PAGE D'APRES SON ID
function GetElement( idElement )
{
// Appel la méthode en fonction du navigateur
if( document.all )
return document.all[ idElement ]
else
return document.getElementById( idElement )
}