Javascript Slickgrid树视图搜索
我目前正在使用slickgrid实现一个treeview 我的代码基本上就是基于此 我试图做的是得到一个搜索过滤器,类似于示例中的一个,但它对分支和父级都有效。例如,如果一棵树看起来像这样:Javascript Slickgrid树视图搜索,javascript,jquery,slickgrid,Javascript,Jquery,Slickgrid,我目前正在使用slickgrid实现一个treeview 我的代码基本上就是基于此 我试图做的是得到一个搜索过滤器,类似于示例中的一个,但它对分支和父级都有效。例如,如果一棵树看起来像这样: -Parent 1 -branch 1 -sub_branch 1 -branch 2 -Parent 2 -branch 1 -branch 2 我搜索数字“1”,它应该显示: -Parent 1 -branch 1 -sub_branch 1 -branch 2 -
-Parent 1
-branch 1
-sub_branch 1
-branch 2
-Parent 2
-branch 1
-branch 2
我搜索数字“1”,它应该显示:
-Parent 1
-branch 1
-sub_branch 1
-branch 2
-Parent 2
-branch 1
与此相反:
-Parent 1
对不起,我没有任何代码要显示,我什么地方都没有。有什么想法吗?谢谢就我个人而言,我使用了分组示例,并且我还帮助它进行了多列(嵌套)分组,使用该示例,它可以完全满足您的需要。。。所以不要用你说的那个,我认为它主要是为了缩进,你应该用这个 该示例不包括搜索,但很容易添加,就像在我的项目中一样。是的,父母群体永远不会消失。 在多重分组的示例中,选择50k行,然后单击“按持续时间分组,然后按工作驱动,然后按百分比分组”,您将看到一个漂亮的3列分组:)
复制它,添加搜索栏,它应该可以工作。更新: 我不得不在一年多前的这个星期改进我写的代码,经过大量测试,这就是我最终得到的结果。这种方法比旧方法快得多,而且我的意思是很多!使用5个节点和5100行的节点深度进行测试此数据准备大约需要1.3s,但如果不需要不区分大小写的搜索,删除toLowerCase将花费一半的时间,大约600ms。准备好SearchString后,搜索将立即进行 这是我们准备数据的setData函数
var self = this,
searchProperty = "name";
//if it's a tree grid, we need to manipulate the data for us to search it
if (self.options.treeGrid) {
//createing index prop for faster get
createParentIndex(items);
for (var i = 0; i < items.length; i++) {
items[i]._searchArr = [items[i][searchProperty]];
var item = items[i];
if (item.parent != null) {
var parent = items[item.parentIdx];
while (parent) {
parent._searchArr.push.apply(
parent._searchArr, uniq_fast(item._searchArr)
);
item = parent;
parent = items[item.parentIdx];
}
}
}
//constructing strings to search
//for case insensitive (.toLowerCase()) this loop is twice as slow (1152ms instead of 560ms for 5100rows) .toLowerCase();
for (var i = 0; i < items.length; i++) {
items[i]._search = items[i]._searchArr.join("/").toLowerCase();
items[i]._searchArr = null;
}
//now all we need to do in our filter is to check indexOf _search property
}
所以,这个问题很久以前就被提出了,但是如果有人正在寻找答案,请使用上面的代码。虽然速度很快,但对代码的任何改进都将是值得赞赏的
编辑结束
旧答案(这很慢):
首先,您必须创建一个用于dataView的筛选函数。只要您键入某个内容,dataView就会调用您的函数。将为dataView中的每一行调用该函数,并将该行作为项参数传递。返回false表示该行应隐藏,返回true表示可见
查看,filter函数如下所示
function myFilter(item, args) {
if (item["percentComplete"] < percentCompleteThreshold) {
return false;
}
if (searchString != "" && item["title"].indexOf(searchString) == -1) {
return false;
}
if (item.parent != null) {
var parent = data[item.parent];
while (parent) {
if (parent._collapsed || (parent["percentComplete"] < percentCompleteThreshold) || (searchString != "" && parent["title"].indexOf(searchString) == -1)) {
return false;
}
parent = data[parent.parent];
}
}
return true;
}
第二,是递归函数的时候了。如果你不熟悉它们的工作原理,这是一个棘手的部分
//returns true if a child was found that passed the realFilter
function checkParentForChildren(parent, allItems, args) {
var foundChild = false;
for (var i = 0; i < allItems.length; i++) {
if (allItems[i].parent == parent.id) {
if (realFilter(allItems[i], args) == false && foundChild == false) //if the child do not pass realFilter && no child have been found yet for this row
foundChild = checkParentForChildren(allItems[i], allItems, args);
else
return true;
}
}
return foundChild;
}
//如果找到通过realFilter的子级,则返回true
函数checkParentForChildren(父项、所有项、参数){
var foundChild=false;
对于(变量i=0;i
最后,实现了原始的滤波函数。
这是由slickgrid调用的函数,应该注册到dataView
//registration of the filter
dataView.setFilter(filter);
//the base filter function
function filter(item, args) {
var allRows = args.grid.getData().getItems();
var columnFilters = args.columnFilters;
var grid = args.grid;
var checkForChildren = false;
for (var i = 0; i < allRows.length; i++) {
if (allRows[i].parent == item.id) {
checkForChildren = true;
break;
}
}
for (var columnId in columnFilters) {
if (columnId !== undefined && columnFilters[columnId] !== "") {
var c = grid.getColumns()[grid.getColumnIndex(columnId)];
var searchString = columnFilters[columnId].toLowerCase().trim();
if (c != undefined) {
if (item[c.field] == null || item[c.field] == undefined) {
return false;
}
else {
var returnValue = true;
if (checkForChildren) {
returnValue = checkParentForChildren(item, allRows, args);
if(!returnValue)
returnValue = realFilter(item, args);
}
else
returnValue = realFilter(item, args);
if (item.parent != null && returnValue == true) {
var dataViewData = args.grid.getData().getItems();
var parent = dataViewData[item.parent];
while (parent) {
if (parent._collapsed) {
parent._collapsed = false;
}
parent = dataViewData[parent.parent];
}
}
return returnValue;
}
}
}
}
if (item.parent != null) {
var dataViewData = args.grid.getData().getItems();
var parent = dataViewData[item.parent];
while (parent) {
if (parent._collapsed) {
return false;
}
parent = dataViewData[parent.parent];
}
}
return true;
}
//过滤器的注册
setFilter(filter);
//基本过滤函数
函数筛选器(项,参数){
var allRows=args.grid.getData().getItems();
var columnFilters=args.columnFilters;
var grid=args.grid;
var checkForChildren=false;
对于(var i=0;i
我目前正在做这件事,所以我还没有真正费心去改进代码。据我所知,它正在工作,但您可能需要调整过滤器和realFilter中的一些内容,以使其按预期工作。我今天写了这篇文章,所以它没有在开发阶段进行更多的测试
注:
如果要使用其他输入进行搜索,只需在该字段上使用$.keyup(),然后将数据传递到标题过滤器。这样你就可以得到艾尔
function realFilter(item, args) {
var columnFilters = args.columnFilters;
var grid = args.grid;
var returnValue = false;
for (var columnId in columnFilters) {
if (columnId !== undefined && columnFilters[columnId] !== "") {
returnValue = true;
var c = grid.getColumns()[grid.getColumnIndex(columnId)];
if (item[c.field].toString().toLowerCase().indexOf(
columnFilters[columnId].toString().toLowerCase()) == -1) { //if true, don't show this post
returnValue = false;
}
}
}
return returnValue;
}
//returns true if a child was found that passed the realFilter
function checkParentForChildren(parent, allItems, args) {
var foundChild = false;
for (var i = 0; i < allItems.length; i++) {
if (allItems[i].parent == parent.id) {
if (realFilter(allItems[i], args) == false && foundChild == false) //if the child do not pass realFilter && no child have been found yet for this row
foundChild = checkParentForChildren(allItems[i], allItems, args);
else
return true;
}
}
return foundChild;
}
//registration of the filter
dataView.setFilter(filter);
//the base filter function
function filter(item, args) {
var allRows = args.grid.getData().getItems();
var columnFilters = args.columnFilters;
var grid = args.grid;
var checkForChildren = false;
for (var i = 0; i < allRows.length; i++) {
if (allRows[i].parent == item.id) {
checkForChildren = true;
break;
}
}
for (var columnId in columnFilters) {
if (columnId !== undefined && columnFilters[columnId] !== "") {
var c = grid.getColumns()[grid.getColumnIndex(columnId)];
var searchString = columnFilters[columnId].toLowerCase().trim();
if (c != undefined) {
if (item[c.field] == null || item[c.field] == undefined) {
return false;
}
else {
var returnValue = true;
if (checkForChildren) {
returnValue = checkParentForChildren(item, allRows, args);
if(!returnValue)
returnValue = realFilter(item, args);
}
else
returnValue = realFilter(item, args);
if (item.parent != null && returnValue == true) {
var dataViewData = args.grid.getData().getItems();
var parent = dataViewData[item.parent];
while (parent) {
if (parent._collapsed) {
parent._collapsed = false;
}
parent = dataViewData[parent.parent];
}
}
return returnValue;
}
}
}
}
if (item.parent != null) {
var dataViewData = args.grid.getData().getItems();
var parent = dataViewData[item.parent];
while (parent) {
if (parent._collapsed) {
return false;
}
parent = dataViewData[parent.parent];
}
}
return true;
}