Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ordering data when using slickgrid tree

Tags:

tree

slickgrid

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?

like image 624
arieljake Avatar asked Jun 28 '12 04:06

arieljake


1 Answers

  1. You have to order your data before you add it to the grid. There are no built in functions that can understand and sort the data for you (as far as i know). If you use a Binary Search Tree, I think you can just sort by left leaf. With other tree structures, you probably have too loop through the data or write a recursive SQL-query to sort it.
  2. 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>&nbsp;" + 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.

like image 143
Binke Avatar answered Sep 18 '22 14:09

Binke