Forums : Xul, Xbl, JS...

Aller à la discussion :  Plus récente Plus ancienne

# Mise à jour des données dans un treeview

Envoyé par : Mushu

Date : 31/08/2009 08:32

Bonjour,

Je n'arrive pas à mettre à jour dynamiquement un arbre. Le code que j'utilise ci-dessous se base sur du MDC.

Le bouton exécute la fonction ajout, qui a pour but de rajouter un élément au tableau servant de base au treeview, efface l'interface, redéclare la variable treeview en globale et l'affiche à nouveau. Malheureusement, lorsque l'arbre s'affiche, l'élément ajouté ne s'affiche pas, a moins de réduire la branche par le twitter et de la redévelopper ensuite.

Je suis dans le chrome mais je n'ai pas la possibilité de générer du RDF car tout se passe en local.

Par avance, merci de votre aide.

 <?xml version="1.0" encoding="iso-8859-15"?>
 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
 
 <window onload="init();"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
 <tree id="elementList" flex="1">
   <treecols>
     <treecol id="element" label="Élément" primary="true" flex="1"/>
   </treecols>
   <treechildren id="treechild" />
 </tree>
 
 <script>
 <![CDATA[
 
   var childData = new Array();
   childData["Solides"] = ["Argent", "Or", "Plomb"];
   childData["Liquides"] = ["Mercure"];
   childData["Gaz"] = ["Hélium", "Azote"];
 
   var visibleData = [
     ["Solides", true, false],
     ["Liquides", true, false],
     ["Gaz", true, false]
   ] ;
 
 
 var initTree = function() {
   treeView = {
     treeBox: null,
   
     selection: null,
     
     get rowCount() { return visibleData.length; },
     getRowProperties: function(idx, column, prop) {},
     getCellProperties: function(idx, column, prop) {},
     getColumnProperties: function(column, element, prop) {},
     isContainer: function(idx)         { return visibleData[idx][1]; },
     isContainerOpen: function(idx)     { return visibleData[idx][2]; },
     isContainerEmpty: function(idx)    { return false; },
     isSeparator: function(idx)         { return false; },
     isSorted: function()               { return false; },
     canDrop: function()               { return false; },
     drop: function()               { return false; },
     getParentIndex: function(idx) {
       if (this.isContainer(idx)) return -1;
       for (var t = idx - 1; t >= 0 ; t--) {
         if (this.isContainer(t)) return t;
       }
       return false ;
     },
     hasNextSibling: function(idx, after) {
       var thisLevel = this.getLevel(idx);
       for (var t = idx + 1; t < visibleData.length; t++) {
         var nextLevel = this.getLevel(t) ;
         if (nextLevel == thisLevel) return true;
         else if (nextLevel < thisLevel) return false;
       }
       return false ;
     },
     getLevel: function(idx) {
       if (this.isContainer(idx)) return 0;
       return 1;
     },
     getImageSrc: function(idx, column) {},
     getProgressMode : function(idx,column) {},
     getCellValue: function(idx, column) {},
     getCellText: function(idx, column) { return visibleData[idx][0]; },
     setTree: function(treeBox) { this.treeBox = treeBox; },
     toggleOpenState: function(idx) {
       var item = visibleData[idx];
       if (!item[1]) return;
   
       if (item[2]) {
         item[2] = false;
   
         var thisLevel = this.getLevel(idx);
         var deletecount = 0;
         for (var t = idx + 1; t < visibleData.length; t++) {
           if (this.getLevel(t) > thisLevel) deletecount++;
           else break;
         }
         if (deletecount) {
           visibleData.splice(idx + 1, deletecount);
           this.treeBox.rowCountChanged(idx + 1, -deletecount);
         }
       }
       else {
         item[2] = true;
   
         var label = visibleData[idx][0];
         var toinsert = childData[label];
       dump(visibleData[idx]);
         for (var i = 0; i < toinsert.length; i++) {
           visibleData.splice(idx + i + 1, 0, [toinsert[i], false]);
         }
         this.treeBox.rowCountChanged(idx + 1, toinsert.length);
       }
     },
     cycleHeader: function(col, elem) {},
     selectionChanged: function() {},
     cycleCell: function(idx, column) {},
     isEditable: function(idx, column)  { return false; },
     isSelectable: function(idx, column)  { return false; },
     setCellValue: function(idx, column) {},
     setCellText: function(idx, column) { return visibleData[idx][0]; },
     performAction: function(action) {},
     performActionOnRow: function(action, index, column) {},
     performActionOnCell: function(action, index, column) {}
   };
 };
 
 var delTree = function() {
   dump("delTree exectue") ;
   delete treeView;
 };
 
 
 var init = function() {
   dump("init exectue") ;
   initTree() ;
   document.getElementById("elementList").view = treeView;
 };
 
 var ajout = function() {
   dump("ajout exectue") ;
   efface() ;
   delTree() ;
   childData["Liquides"].push("Test") ;
   initTree() ;
   document.getElementById("elementList").view = treeView;
 };
 
 var efface = function ()
 {
   try
   {
     var tree = document.getElementById("elementList");
     var treechild = document.getElementById("treechild");
     tree.removeChild(treechild);
     
     var treechildren = document.createElement("treechildren");
     treechildren.setAttribute("id","treechild");
     tree.appendChild(treechildren);
   }
  	catch(e)
   {
     alert(e);
   }
 };
 
 ]]></script>
 <button label="Test" oncommand = "ajout() ;" />
 </window>

# Re: Mise à jour des données dans un treeview

Envoyé par : obs

Date : 31/08/2009 13:42

Salut,

Je pense que ta façon de mettre à jour l'arbre n'est pas correct. Dans mon souvenir, tu n'as pas besoin de supprimer l'arbre pour ajouter un élément.

Tu as ici childData et visibleData. Tu modifies childData, ok. Mais si l'élément que tu ajoutes se trouve dans un row ouvert, il faut aussi que tu l'ajoutes à visibleData.

Il faudra aussi que tu notifies la treeBoxque tu as fais une modification regarde la ligne:

this.treeBox.rowCountChanged(idx + 1, toinsert.length);

# Re: Mise à jour des données dans un treeview

Envoyé par : Mushu

Date : 06/09/2009 09:04

Voici les modifications que j'ai apporté au code :

 init: function() {
   dump("init exectue") ;
   document.getElementById("elementList").view = treeView;
 },

 ajout: function() {
   dump("ajout exectue\n") ;
   this.efface() ;
   childData["Liquides"].push("Test") ;
   for (var i = 0 ; i < visibleData.length ; i++){
   dump(" --- " + visibleData[i][0] + "  ///// " + visibleData[i][1] + "  ///// " + visibleData[i][2] + " --- \n") ;
     if (visibleData[i][0] == "Liquides" && visibleData[i][2] == true){
       visibleData[i].push("Test", true, undefined) ;
       this.treeBox.rowCountChanged(i, childData["Liquides"].length);
     }
   }
   document.getElementById("elementList").view = treeView;
 },

 efface: function ()
 {
   try
   {
     var tree = document.getElementById("elementList");
     var treechild = document.getElementById("treechild");
     tree.removeChild(treechild);
     
     var treechildren = document.createElement("treechildren");
     treechildren.setAttribute("id","treechild");
     tree.appendChild(treechildren);
   }
  	catch(e)
   {
     alert(e);
   }
 }

J'ai mis ce code directement dans l'objet afin de faciliter la visibilité des variables.

Toutefois, j'ai l'erreur suivante maintenant lorsque j'exécute la fonction ajout et uniquement lorsque la branche modifiée est ouverte :

Error: this.treeBox has no properties

Ce qui est étonnant, c'est que d'autres fonctions font la même chose sans soucis

L'appel de la fonction est faite par :

<button label="Test" oncommand = "treeView.ajout() ;" />

# Re: Mise à jour des données dans un treeview

Envoyé par : obs

Date : 07/09/2009 10:27

Il y a un truc qui me gêne dans ton code, c'est la fonction efface(). Je ne comprend pas pourquoi tu vires le treechildren. Normalement tu n'en as pas besoin. L'arbre étant dynamique, il suffit de modifier le contenu de visibleData puis de notifier le treeBox qu'il y a des modifications. C'est le treeBox qui va mettre à jour l'affichage de l'arbre.

# Re: Mise à jour des données dans un treeview

Envoyé par : laurentj

Date : 07/09/2009 11:52

oui, à partir du moment où l'on fait un treeview, on ne doit pas manipuler le XUL du tree. Juste les données qui ont servi à builder le tree, et ensuite faire un mytree.builder.rebuild()

# Re: Mise à jour des données dans un treeview

Envoyé par : Mushu

Date : 07/09/2009 18:00

Effectivement, la fonction efface ne sert a rien ^^

Par contre dans quel(s) cas mytree.builder.rebuild() est-il nécessaire car sans cette fonction, la mise à jour s'effectue ?

# Re: Mise à jour des données dans un treeview

Envoyé par : obs

Date : 09/09/2009 13:48

J'utilise mytree.builder.rebuild() uniquement dans le cas d'arbre généré par template. Je ne sais pas si c'est utilisable autre part.

Il n'est plus possible de poster des messages dans ce forum.


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.