KendoUI filter TreeView

J'utilise la vision arborescente de KendoUI et je souhaite donner à l'utilisateur la possibilité de la filtrer. Il y a même une démo qui fait ce que je veux (http://demos.kendoui.com/web/treeview/api.html)

Le problème est que le filtre n'est appliqué qu'à la 1ère hiérarchie de TreeView, donc si le texte-filtre est présent chez un enfant mais pas par le parent, l'enfant ne sera pas affiché.

Exemple:

  • Objet 1
  • Point 2
    • Article xzy
    • Article abc

Si le texte de recherche serait "abc", aucun élément ne sera affiché. Au lieu de cela, j'aimerais avoir le résultat suivant:

  • Point 2
    • Article abc

Est-ce que quelqu'un sait comment faire ça? C'est le code que j'utilise:

var tree_view_data = new kendo.data.HierarchicalDataSource({ transport: { read: { url: "getall/items", dataType: "json" } }, schema: { model: { children: "ChildItems" } } }); //init tree view itself var $treeview = $("#div-treeview").kendoTreeView({ dataSource: tree_view_data, dataTextField: [ "Text", "ChildrenText" ] }); //allow filter of navigation tree var refreshTree = function () { tree_view_data.filter({ field: "Text", //if I would use "ChildrenText" here nothing be displayed at all if filtertext is set operator: "contains", value: $("#tree-text-search").val() }); }; $("#tree-text-search").change(refreshTree).keyup(refreshTree); 

Mise à jour 2016-01-13 : Il existe maintenant un sujet d'aide qui montre comment effectuer un filtrage TreeView en fonction d'une chaîne d'utilisateurs .

Vous devez filtrer manuellement les sources de données enfant, de sorte que seuls les noeuds nécessaires sont affichés. Le fait de disposer de différentes dataTextField s pour les différents niveaux rend plus difficile à saisir, donc ce code utilise uniquement le champ de text . De plus, comme ce filtrage est effectué sur le côté client, il suppose que vous avez chargé tous les nœuds.

 var treeview = $("#treeview").data("kendoTreeView"), item = treeview.findByText("Item 1.3"), // find the node that will be shown dataItem = treeview.dataItem(item), nodeText = dataItem.text; // loop through the parents of the given node, filtering them to only one item while (dataItem.parentNode()) { dataItem = dataItem.parentNode(); dataItem.children.filter({ field: "text", operator: "contains", value: nodeText }); nodeText = dataItem.text; } treeview.dataSource.filter({ field: "text", operator: "contains", value: nodeText }); 

J'ai trouvé un moyen de le faire en utilisant simplement les sélecteurs jQuery pour cacher et montrer les nœuds enfants nécessaires.

La première chose est lorsque vous créez votre vue arborescente, ajoutez ce paramètre à vos options:

LoadOnDemand: false

De cette façon, l'arbre rendra tout le code HTML de vos nœuds enfants avant d'être demandé, ce qui vous permettra d'utiliser jQuery pour naviguer.

Voici le code jQuery que j'ai travaillé qui filtre les nœuds qui ne correspondent pas, ouvre le groupe de nœuds qui correspondent et les montre.

 $("#searchTextInputField").keyup(function () { var filterText = $("#searchTextInputField").val(); if(filterText !== "") { $("#myTree .k-group .k-group .k-in").closest("li").hide(); $("#myTree .k-group .k-group .k-in:contains(" + filterText + ")").each(function() { $(this).closest("ul").show(); $(this).closest("li").show(); }); } else { $("#myTree .k-group").find("ul").hide(); $("#myTree .k-group").find("li").show(); } }); 

Pour plus de 4 niveaux, traversez tous les parents de type UL et LI et call show ().

 $("#filterText").keyup(function (e) { var filterText = $(this).val(); if (filterText !== "") { $("#treeview-standards .k-group .k-group .k-in").closest("li").hide(); $("#treeview-standards .k-group .k-group .k-in:contains(" + filterText + ")").each(function () { $(this).parents("ul, li").each(function () { $(this).show(); }); }); } else { $("#treeview-standards .k-group").find("ul").hide(); $("#treeview-standards .k-group").find("li").show(); } }); 

Tout d'abord. KendoTreeView est un contrôle de très faible niveau par rapport à Teleriks RadDropDownTree d'ASP.NET http://www.telerik.com/help/aspnet-ajax/dropdowntree-overview.html (je veux dire les js bien sûr!) Le devrait avoir pris cela À jquery / kendo … il fallait améliorer ce filtre, donc si vous préférez un filtrage approprié sur dataitem au lieu de "findByText", ceci:

.1) trouve tous les éléments de données .2) vérifie vos conditions (ici minuscule contient sur la valeur / le texte) .3) élément de drapeau, drapeau des parents .4) nettoyer, supprimer les nœuds laissés dans l'arbre par parent

 that.nodeFilter = { logic: "or", filters: [] }; that.nodeFilter.filters.push({ field: "hidden", operator: "eq", value: false }); tree.element.find(".k-in").each(function () { var dItem = tree.dataItem($(this).closest("li")); dItem.hidden = false; if (dItem[that.options.dataValueField].toLowerCase().indexOf(searchTerm) != -1 || dItem[that.options.dataTextField].toLowerCase().indexOf(searchTerm) != -1) { that.nodeFilter.filters.push({ field: that.options.dataValueField, operator: "eq", value: dItem[that.options.dataValueField] }) while (dItem.parentNode()) { dItem = dItem.parentNode(); dItem.hidden = false; that.nodeFilter.filters.push({ field: that.options.dataValueField, operator: "eq", value: dItem[that.options.dataValueField] }) } } else { dItem.hidden = true; } }); tree.dataSource.filter(that.nodeFilter); tree.element.find(".k-in").each(function () { var node = $(this).closest("li"); var dataItem = tree.dataItem(node); if (dataItem.hidden) { tree.remove(node); } }); 

Cette version recherche l'arbre entier, est insensible à la casse et cache les nœuds qui ne contiennent pas la requête de recherche (jQuery 1.8+).

 $("#search").keyup(function (e) { var query = $(this).val(); if (query !== "") { $("#tree-view .k-in").closest("li").hide(); $("#tree-view .k-item .k-in:Contains(" + query + ")").each(function () { $(this).parents("ul, li").each(function () { $(this).show(); }); }); } else { $("#tree-view .k-group").find("ul").hide(); $("#tree-view .k-group").find("li").show(); } }); jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function (arg) { return function (elem) { return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; }; });