2012-09-06 93 views
15

我使用KendoUI的樹視圖,並希望給用戶過濾它的可能性。 甚至有一個演示,做我想要的(http://demos.kendoui.c​​om/web/treeview/api.html)KendoUI過濾器TreeView

問題是該過濾器只適用於TreeView的第一層次,所以如果過濾文本存在於小孩而不是父項中,那麼該小孩將不會顯示。

實施例:

  • 項目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); 

回答

7

更新2016年1月13日:現在有一個幫助主題,顯示how to perform TreeView filtering based on a user string

您需要手動篩選子DataSources,以便只顯示必要的節點。對於不同的級別有不同的dataTextField使得難以掌握,所以此代碼僅使用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 }); 
+0

看來,它只能如果存在一個節點(需要調整處理時,有與相同的文本多個節點的情況下)與文本與過濾文本完全匹配。假設節點文本是「Item abc」,並且用戶輸入「abc」作爲過濾器文本,則findByText(「abc」)會返回null,因爲它會嘗試匹配確切的節點文本。糾正我,如果我的假設是錯誤的。 –

+0

的確如此。如果你需要鬆散地匹配節點,你可以像這樣使用[jQuery contains selector](http://api.jquery.com/contains-selector/):'$(「。k-in:contains('photo ')「)' –

+0

試過jQuery包含選擇器,但問題是它只搜索展開的節點(以HTML呈現)並且不會與摺疊節點的子節點相匹配。任何其他的替代方案? –

11

我發現了一個方法,使這只是利用jQuery選擇隱藏和顯示必要的子節點出現。

的第一件事是,當你創建你的樹視圖中,此參數添加到您的選擇:

loadOnDemand:假

這樣樹會呈現出你的子節點的所有的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(); 
     } 
    }); 
+0

+!爲了這。我唯一需要做的就是擴展jQuery,使其不區分大小寫。 – eadam

+0

這很好,但我有一個樹狀視圖,可以下降到4個級別,而這段代碼似乎只搜索前兩個級別..我如何獲得它來搜索整棵樹? – user2206329

+0

這太棒了,但我有一個樹狀圖,可以降到4級,它看起來像是在搜索整棵樹,但沒有顯示任何東西。這個元素被發現是4級的,父母沒有被看見?我怎樣才能讓它顯示父母? – user2206329

5

超過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(); 
    } 
}); 
+1

這是唯一適用於我的解決方案。 –

+0

感謝您使用此解決方案。唯一的事情是它沒有隱藏不匹配的節點,所以我改變了一點:'$(「#treeview-standards .k-in」)。closest(「li」)。hide();'and it完美地工作。比Kendo文檔爲您提供的解決方案快得多。 – Sunden

0

首先。 KendoTreeView與Teleriks RadDropDownTree的ASP.NET http://www.telerik.com/help/aspnet-ajax/dropdowntree-overview.html(我的意思是當然是js!) 的應該採取這種將jQuery /劍道......它需要,如果你喜歡上的DataItem而不是「findByText」適當的過濾,以提高該過濾器,所以 ,這樣做:

0.1)查找所有dataitems 。2)檢查您的條件(這裏小寫包含價值/文) 。3)標誌項目,標誌父母 。4)清理,由家長

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

去除留在樹節點此版本搜索整個樹,不區分大小寫,並隱藏不包含搜索查詢(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

如果我很好地讀了這個問題,它是關於過濾視圖中的數據而不是樹視圖本身。它可以通過遞歸完成。

遞歸的例子,工作原理:

<!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 
 
    // 
 
    \t 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>