2015-08-02 12 views
5

Utworzono drzewo dijit i pole tekstowe i chcę filtrować węzły drzewa na podstawie słów kluczowych podanych w polu tekstowym. Zaimplementowałem rozwiązanie dostarczone w innym pytaniu, ale wydaje się, że nie działa. Gdy użytkownik wprowadzi jakieś słowo w polu tekstowym, drzewo zostanie ponownie wypełnione tymi samymi danymi.Filtrowanie drzewa Dijit i wyszukiwanie nie działa na ObjectStoreModel

dijit.Tree search and refresh

Po to mój kod:

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(); 

}); 

Zobacz przykładowy kod w JSFIDDLE: http://jsfiddle.net/xLfdhnrf/16/

drzewo i pole tekstowe jest świadczenie porządku tylko wyszukiwarka nie działa , jakieś sugestie? Również dlaczego znak EXPAND (+) wyświetla się z węzłami liści?

Snapshot of Filterable Tree

Odpowiedz

6

Dodałem właściwość niestandardową do danych modelu. Nazywa się keep i odpowiada za filtrowanie. Każda pozycja danych ma tę właściwość. Jeśli keep jest true element będzie widoczny. jeśli keep jest false element zostanie ukryty.
Gdy wejście zaciera się, keep jest aktualizowane i drzewo jest ponownie tworzone.
Aby zachować strukturę drzewa, jeśli element pasuje do tekstu, rekursywnie zaznaczamy wszystkie jego elementy macierzyste jako keep, nawet jeśli nie są one zgodne (w przeciwnym razie nie zobaczymy samego obiektu).
Skomentowałem niepotrzebne wiersze do ponownego stworzenia drzewa.

Jak widać, keep jest stosowany w

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

To jest jak drzewo się sączy.

W modelu utworzyłem metodę mayHaveChildren. Jeśli ta metoda zwróci true, masz węzeł rozwijany. Jeśli zwróci false, masz normalny węzeł. Aby uzyskać szczegółowe informacje, patrz http://dojotoolkit.org/reference-guide/1.10/dijit/tree/Model.html.
mayHaveChildren Wartość zwracana jest oparta na zapytaniu o sklep.

W końcu użyłem wyrażeń regularnych zamiast zwykłego łańcucha, dlatego w dopasowaniu nie jest uwzględniana wielkość liter.

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

Kod działa poprawnie na poziomie pojedynczego menu. Kiedy dodaję węzły potomne, to ich nie wyświetla, ponieważ "mayHaveChildren" zwraca false. Jednak jeśli zwrócę true zamiast false, wyświetla węzły potomne, ale filtr działa tylko dla węzłów najwyższego poziomu. Jeśli węzły podrzędne mogą być wyświetlane i filtrowane, mój problem zostanie rozwiązany i mogę zaakceptować odpowiedź. Zobacz zaktualizowany kod tutaj: http://jsfiddle.net/xLfdhnrf/26/ Sprawdź, zwracając "true" w "mayHaveChildren", aby wyświetlić węzły potomne drzewa. –

+0

@ asim-ishaq, zredagowano odpowiedź – ben

+0

Zaktualizowany kod spełnia wszystkie wymagania. Dziękuję za odpowiedź. –

Powiązane problemy