web-dev-qa-db-ja.com

KendoUIフィルターTreeView

KendoUIのツリービューを使用しており、ユーザーがそれをフィルタリングできるようにしたいと考えています。私がやりたいことを実行するデモもあります(http://demos.kendoui.c​​om/web/treeview/api.html)

問題は、フィルターがTreeViewの第1階層にのみ適用されるため、フィルターテキストが子に存在し、親には存在しない場合、子は表示されないことです。

例:

  • アイテム1
  • アイテム2
    • アイテムxzy
    • アイテムabc

検索テキストが「abc」の場合、アイテムは表示されません。代わりに、次の結果が必要です。

  • アイテム2
    • アイテムabc

誰かがこれを行う方法を知っていますか?これは私が使用しているコードです:

   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);
15
Preli

更新2016-01-13ユーザー文字列に基づいてTreeViewフィルタリングを実行する方法 を示すヘルプトピックがあります。 。

必要なノードのみが表示されるように、子データソースを手動でフィルタリングする必要があります。レベルごとにdataTextFieldsが異なると把握が難しくなるため、このコードではtextフィールドのみを使用します。また、このフィルタリングはクライアント側で実行されるため、すべてのノードがロードされていることを前提としています。

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 });
7
Alex Gyoshev

JQueryセレクターを使用して必要な子ノードを表示および非表示にするだけでこれを実現する方法を見つけました。

まず、ツリービューを作成するときに、次のパラメーターをオプションに追加します。

loadOnDemand:false

このようにして、ツリーは要求される前に子ノードのすべてのHTMLをレンダリングするため、jQueryを使用してナビゲートできます。

これは、一致しないノードを除外し、一致するノードのグループを開いて表示する、私が作業しているjQueryコードです。

$("#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();
        }
    });
11
Mike Woj

4レベルを超える場合は、タイプULおよびLIのすべての親をトラバースし、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();
    }
});
5
user2620454

まず第一に。 KendoTreeViewは、ASP.NETのTeleriks RadDropDownTreeと比較して非常に低レベルの制御です http://www.telerik.com/help/aspnet-ajax/dropdowntree-overview.html (つまり、もちろんjsを意味します!)これをjquery/kendoに持っていく必要があります...このフィルターを改善する必要があるため、「findByText」ではなくデータアイテムで適切なフィルター処理を行う場合は、次のようにします。

.1)すべてのデータ項目を検索します。2)条件をチェックします(ここでは小文字が値/テキストに含まれます)。

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);
    }
});
0
csharpnoob

質問をよく読んだ場合、それはツリービュー自体ではなく、ビュー内のデータのフィルタリングに関するものです。それは再帰によって行うことができます。

動作する再帰の例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>Kendo UI Snippet</title>

    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.117/styles/kendo.common.min.css"/>
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.117/styles/kendo.rtl.min.css"/>
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.117/styles/kendo.silver.min.css"/>
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.117/styles/kendo.mobile.all.min.css"/>

    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="https://kendo.cdn.telerik.com/2018.1.117/js/kendo.all.min.js"></script>
</head>
<body>
  <div class="demo-section k-content">
    <div id="treeview1"></div>
    <div id="showit"></div>
    <div id="treeview2"></div>
  </div>
<script>
    //
    // Define hierarchical data source
    //
    var mydata = new kendo.data.HierarchicalDataSource({ 
      name: "Food", items: [
      { name: "Meat", items:
        [
          { name: "Pork" },
          { name: "Beef" }
        ]
      },
      { name: "Vegetables", items:
        [
          { name: "Pepper" }          
        ]
      }
      ]
    });

    //
    // When debugging
    //    
    var debug=false;
  
    //
    // Find and return Item when found.
    //
    function FindByName(items, myName)
    {
      //Query definition
      var query = kendo.data.Query.process(items, {
              filter: {
                logic: "or",
                filters: [{
                  field: "name",
                  value: myName,
                  operator: "eq"
                }]
              }
            });
      
       if (debug) $("#showit").html($("#showit").html()+"  found:" + JSON.stringify(query.data));
      
       //
       // return Item when found.
       //
       if (query.data != "")       
         return query.data; //ready
       else
       {
         //
         // if sub-items, search further
         //
         for (let i=0; i<items.length; i++)            
         {
           if (debug) $("#showit").html($("#showit").html()+"  test:" + JSON.stringify(items[i]));
           if (items[i].items!=null)
           {           
             if (debug) $("#showit").html($("#showit").html()+"  search sub....");
             var r = FindByName(items[i].items, myName);
             if (r!=null) return r; //ready, else continue searching further
           };
         }
       }
      if (debug) $("#showit").html($("#showit").html()+"  not found.");
      return null; //nothing found.
    }
  
    //
    // print the input
    //
    $("#showit").html($("#showit").html()+"  Food:" + JSON.stringify(mydata.options.items));
    //
    // print the result
    //
        var ret=FindByName(mydata.options.items,"Beef");
    $("#showit").html($("#showit").html()+"<p>  Beef:" + JSON.stringify(ret));
    
    $("#treeview1").kendoTreeView({
      dataSource: mydata.options.items,
      dataTextField: ["name"]
    });

    ret=FindByName(mydata.options.items,"Meat");
    $("#showit").html($("#showit").html()+"<p>  Meat:" + JSON.stringify(ret));
    ret=FindByName(mydata.options.items,"Pepper");
    $("#showit").html($("#showit").html()+"<p>  Pepper:" + JSON.stringify(ret));
    ret=FindByName(mydata.options.items,"Vegetables");
    $("#showit").html($("#showit").html()+"<p>  Vegetables:" + JSON.stringify(ret));
    //
    // Example: bind return value [ret] to treeview.
    //
    $("#treeview2").kendoTreeView({
      dataSource: ret,
      dataTextField: ["name"]
    });
</script>
</body>
</html>
0
David

このバージョンはツリー全体を検索し、大文字と小文字を区別せず、検索クエリ(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;
    };
});
0
Sunden