Reputation: 515
The example on the slickgrid wiki for producing a tree generates data that is ordered in the exact order the tree needs for outputting the parents and children. See: http://mleibman.github.com/SlickGrid/examples/example5-collapsing.html - you can see for example that if the parent is Task 1, the children are Task 2 and Task 3, etc.
How do we tell slick grid how to order nodes when outputting a tree if the nodes don't have a property that can easily be used to sort the nodes so that children immediately follow their parents?
Also, can a slick-tree support sorting, i.e. how does that play with node order?
Upvotes: 6
Views: 1989
Reputation: 1587
I have the same issue, with a 3-level hierarchy. I spent a good amount of time trying to get Binke's solution to work but it just resulted in the lower hierarchy elements grouping together, while first-and-second level ones sort-worked but had issues. Ultimately I decided that it's best to just use server-side sorting, and so my on-sort method literally just sets the chosen column to sort by and refreshes the grid:
grid.onSort.subscribe(function(e, args) {
sortColumn = args.sortCol.field;
refreshCasesList();
});
I recommend the same.
Upvotes: 0
Reputation: 900
Since the data needs to be ordered, there is not an easy way to support sorting of the tree. The basic sorting will destroy your structured data. However, if you have a property on the data sortOrder, you should be able to sort the data. If you have all level 1 nodes as sortOrder = 1, level 2 nodes as sortOrder = 2 and so on, first sort it by sortorder and then by the column in ascending or descending order. Check Multi column sort to get a good grasp of how you can do this.
grid.onSort.subscribe(function (e, args) {
var cols = args.sortCols;
data.sort(function (dataRow1, dataRow2) {
//first sort by your parameter, then combine it with example sort:
var sortOrderResult = (dataRow1["sortOrder"] == dataRow2["sortOrder"] ? 0
: (dataRow1["sortOrder"] > dataRow2["sortOrder"] ? 1 : -1));
if(sortOrderResult != 0)
return sortOrderResult;
else {
var field = cols[i].sortCol.field;
var sign = cols[i].sortAsc ? 1 : -1;
var value1 = dataRow1[field], value2 = dataRow2[field];
var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
if (result != 0) {
return result;
}
}
}
});
Some things to consider if you are going to try column sorting the tree:
If you look at example 5 you can see that both the filter and the formatter are implemented so that the data needs to be sorted.
The filter:
//part of the filter.
var parent = dataViewData[item.parent];
while (parent) {
if (parent._collapsed) {
parent._collapsed = false;
}
parent = dataViewData[parent.parent];
}
And here's a part of the formatter:
//part of the formatter for showing collapse/open nodes
if (dataViewData[idx + 1] && dataViewData[idx + 1].indent > dataViewData[idx].indent) {
if (dataContext._collapsed) {
return spacer + " <span class='toggle expand'></span> " + value;
} else {
//.......
}
}
I rewrote these to use the actual id instead of checking against the order of the data in the dataView. This requires you too loop through all your data to see if the current node has any children. You also need to replace the dataViewData[idx] calls:
//instead of dataViewData[item.parent];
var parent = dataView.getItemById(item.parent);
This will make the tree work even though the nodes are not sorted, but when expanding a node, the children will probably end up after another node, where they do not reside.
If you need to implement header filter search I responded to another question here a few days ago.
Upvotes: 1