2015-08-02 14 views
5

Ho creato un albero di dijit e una casella di testo e voglio filtrare i nodi dell'albero in base alle parole chiave fornite nella casella di testo. Ho implementato la soluzione fornita in un'altra domanda ma non sembra funzionare. Quando l'utente inserisce una parola nella casella di testo, l'albero viene ripopolato con gli stessi dati.Filtraggio dell'albero di dijit e ricerca non funzionante su ObjectStoreModel

dijit.Tree search and refresh

seguito è il mio codice:

require(["dijit/form/TextBox","dojo/store/Memory","dijit/tree/ObjectStoreModel","dijit/Tree","dojo/domReady!"],  function(TextBox, MemoryStore, ObjectStoreModel, Tree) { 

var searchBox = new TextBox({ 
    placeHolder: "[ Type here to search ]" 
}, "searchBox"); 

searchBox.on("blur", function() { 
    tree.model.store.query({ 
     name: "*" + searchBox.value + "*" 
    }); 

/*the below approach has been taken from the other question*/ 
    tree.model.store.clearOnClose = true; 
    /*tree.model.store.close(); //This is not working?*/ 
    delete tree._itemNodesMap; 
    tree._itemNodesMap = {}; 
    tree.rootNode.state = "UNCHECKED"; 
    delete tree.model.root.children; 
    tree.model.root.children = null; 
    tree.rootNode.destroyRecursive(); 
    tree.model.constructor(tree.model) 
    tree.postMixInProperties(); 
    tree._load(); 

}); 

var store = new MemoryStore({ 
    idProperty: "id", 
    getChildren: function(object) { 
     return this.query({ 
      parent: object.id 
     }); 
    }, 
    data: [{ 
     id: "0", 
     name: "Root Node", 
     parent: null 
    }, { 
     id: "1", 
     name: "File", 
     parent: "0" 
    }, { 
     id: "2", 
     name: "System", 
     parent: "0" 
    }, { 
     id: "3", 
     name: "Diagnosis", 
     parent: "0" 
    }, { 
     id: "4", 
     name: "Management", 
     parent: "0" 
    }] 
}); 

var model = new ObjectStoreModel({ 
    store: store, 
    query: { 
     id: "0" 
    } 
}); 

var tree = new Tree({ 
    model: model, 
    showRoot: false 
}, "treeDiv"); 

tree.startup(); 

}); 

vedere il codice esempio a JSFIDDLE: http://jsfiddle.net/xLfdhnrf/16/

L'albero e testo sta rendendo bene solo ricerca non sta funzionando , eventuali suggerimenti? Inoltre, perché il segno EXPAND (+) viene visualizzato con i nodi foglia?

Snapshot of Filterable Tree

risposta

6

Ho aggiunto una proprietà personalizzata ai dati del modello. Si chiama keep ed è responsabile del filtraggio. Ogni elemento dei dati ha questa proprietà. Se keep è true, l'elemento sarà visibile. se keep è false l'oggetto sarà nascosto.
Quando l'input sfoca, keep viene aggiornato e la struttura viene ricreata.
Al fine di mantenere la struttura ad albero, se un elemento corrisponde al testo, si contrassegna in modo ricorrente tutto il suo genitore come keep, anche se non corrispondono (altrimenti non si vedrebbe l'elemento stesso)
Ho commentato alcune righe non necessarie per la ri-creazione dell'albero.

Come si può vedere, la keep viene utilizzato in

getChildren: function(object) { 
     return this.query({ 
      parent: object.id, 
      keep: true 
     }); 
    }, 

Questo è come l'albero ottenere filtrata.

Ho creato un metodo mayHaveChildren nel modello. Se questo metodo restituisce true hai un nodo espandibile. Se restituisce false hai un nodo normale. Vedi http://dojotoolkit.org/reference-guide/1.10/dijit/tree/Model.html per i dettagli.
mayHaveChildren il valore di ritorno è basato su una query di archivio.

Infine, ho usato un'espressione regolare anziché una stringa semplice in modo che la corrispondenza non sia sensibile al maiuscolo/minuscolo.

require(["dijit/form/TextBox", "dojo/store/Memory", "dijit/tree/ObjectStoreModel", "dijit/Tree", "dojo/domReady!"], function(TextBox, MemoryStore, ObjectStoreModel, Tree) { 
 
    var searchBox = new TextBox({ 
 
     placeHolder: "[ Type here to search ]" 
 
    }, "searchBox"); 
 
    searchBox.on("blur", function() { 
 
     var includeParent = function(itemId) { 
 
      tree.model.store.query({ 
 
      id: itemId 
 
      }).forEach(function(item) { 
 
      item.keep = true; 
 
      //and we include all parent tree 
 
      includeParent(item.parent); 
 
     }); 
 
     } 
 
     
 
     //reset all node, first we exlude them all 
 
     tree.model.store.query().forEach(function(item) { 
 
      item.keep = false; 
 
     }); 
 
     //then we include only the one matching 
 
     tree.model.store.query({ 
 
      name: new RegExp('.*' + searchBox.value + '.*', 'i') 
 
     }).forEach(function(item) { 
 
      item.keep = true; 
 
      //and we include all parent tree 
 
      includeParent(item.parent); 
 
     }); 
 
     
 

 
     //delete tree._itemNodesMap; 
 
     //tree._itemNodesMap = {}; 
 
     //tree.rootNode.state = "UNCHECKED"; 
 
     //delete tree.model.root.children; 
 
     //tree.model.root.children = null; 
 
     tree.rootNode.destroyRecursive(); 
 
     tree.model.constructor(tree.model) 
 
     tree.postMixInProperties(); 
 
     tree._load(); 
 
    }); 
 

 
    var store = new MemoryStore({ 
 
     idProperty: "id", 
 
     getChildren: function(object) { 
 
      return this.query({ 
 
       parent: object.id, 
 
       keep: true 
 
      }); 
 
     }, 
 
     data: [{ 
 
      id: "0", 
 
      name: "Root Node", 
 
      parent: null, 
 
      keep: true 
 
     }, { 
 
      id: "1", 
 
      name: "File", 
 
      parent: "0", 
 
      keep: true 
 
     }, { 
 
      id: "2", 
 
      name: "System", 
 
      parent: "0", 
 
      keep: true 
 
     }, { 
 
      id: "3", 
 
      name: "Diagnosis", 
 
      parent: "0", 
 
      keep: true 
 
     }, { 
 
      id: "4", 
 
      name: "Management", 
 
      parent: "0", 
 
      keep: true 
 
     }, 
 
     { 
 
      id: "5", 
 
      name: "New", 
 
      parent: "1", 
 
      keep: true 
 
     }, 
 
     { 
 
      id: "6", 
 
      name: "Open", 
 
      parent: "1", 
 
      keep: true 
 
     }, 
 
     { 
 
      id: "7", 
 
      name: "Import", 
 
      parent: "1", 
 
      keep: true 
 
     }] 
 
    }); 
 

 
    var model = new ObjectStoreModel({ 
 
     store: store, 
 
     query: { 
 
      id: "0" 
 
     }, 
 
     mayHaveChildren: function (item) { return store.query({parent: item.id}).length > 0; } 
 
    }); 
 

 
    var tree = new Tree({ 
 
     model: model, 
 
     showRoot: false 
 
    }, "treeDiv"); 
 

 
    tree.startup(); 
 

 
});
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script> 
 
<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dijit/themes/claro/claro.css"> 
 

 

 
<body class="claro"> 
 
<div id="searchBox"></div> 
 
<div id="treeDiv"></div>   
 
</div>

+0

Il codice funziona bene per il menu unico livello. Quando aggiungo i nodi figli, non li visualizza perché "mayHaveChildren" restituisce false. Tuttavia, se restituisco true invece di false, visualizza i nodi figlio ma il filtro funziona solo per i nodi di livello superiore. Se i nodi figli possono essere mostrati e filtrati, il mio problema si risolverà e posso accettare la risposta. Vedere il codice aggiornato qui: http://jsfiddle.net/xLfdhnrf/26/ Controllare restituendo "true" in "mayHaveChildren" per visualizzare i nodi figlio dell'albero. –

+0

@ asim-ishaq, ha modificato la risposta – ben

+0

Il codice aggiornato soddisfa tutti i requisiti. Grazie per la risposta. –

Problemi correlati