Tree Grids

If your data items contain collections of child items, you may use FlexGrid's childItemsPath property to show the data as a tree.

For example, consider a list of 'person' objects which have a 'children' property. The 'children' property contains an array of more person objects. This is sometimes called a homogeneous hierarchy.

The grid below was built by binding the grid to the top-level persons list and setting the childItemsPath property to 'children':

Name
Albert
Anton
Annette
Benjamin
Bridget
Billy
Bernard
Bella
Bob
Charlie
Chris
Connie
Carrie
Douglas
Dinah
Donald

There are also 'heterogeneous' hierarchies, where items at different levels have different types and different child item properties.

For example, the grid below is bound to a collection of 'worker' objects which receive 'checks' which list 'earnings':

name
hours
rate
Jack Smith
check1
hourly
30
15
overtime
10
20
bonus
5
30
check2
hourly
20
18
overtime
20
24
Jack Smith
check1
hourly
30
15
overtime
10
20
bonus
5
30
check2
hourly
20
18
overtime
20
24
Jane Smith
check1
hourly
30
15
overtime
10
20
bonus
5
30
check2
hourly
20
18
overtime
20
24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// This file locates: "Scripts/Lesson/C1FlexGrid/TreeGrids.js".
c1.documentReady(function () {
    // family tree data (homogeneous collection)
    var family = [
    {
        name: 'Albert', children: [
          { name: 'Anton' },
          { name: 'Annette' },
        ]
    },
    {
        name: 'Benjamin', children: [
          {
              name: 'Bridget', children: [
                { name: 'Billy' },
            { name: 'Bernard' },
              ]
          },
          { name: 'Bella' },
          { name: 'Bob' },
        ]
    },
    {
        name: 'Charlie', children: [
          { name: 'Chris' },
          { name: 'Connie' },
          { name: 'Carrie' },
        ]
    },
    {
        name: 'Douglas', children: [
          { name: 'Dinah' },
          { name: 'Donald' }
        ]
    },
    ];
 
    // family tree
    var familyGrid = wijmo.Control.getControl('#familyGrid');
    familyGrid.headersVisibility = 'None';
    familyGrid.childItemsPath = 'children';
    familyGrid.itemsSource = family;
    familyGrid.columns[0].width = '*';
 
    // toggle family tree
    document.getElementById('asTree').addEventListener('click', function (e) {
        familyGrid.childItemsPath = e.target.checked ? 'children' : '';
    })
 
    // workers tree data (heterogeneous collection)
    var workers = [{
        name: 'Jack Smith',
        checks: [{
            name: 'check1',
            earnings: [
              { name: 'hourly', hours: 30.0, rate: 15.0 },
              { name: 'overtime', hours: 10.0, rate: 20.0 },
              { name: 'bonus', hours: 5.0, rate: 30.0 }
            ]
        }, {
            name: 'check2',
            earnings: [
              { name: 'hourly', hours: 20.0, rate: 18.0 },
              { name: 'overtime', hours: 20.0, rate: 24.0 }
            ]
        }]
    }, {
        name: 'Jack Smith',
        checks: [{
            name: 'check1',
            earnings: [
              { name: 'hourly', hours: 30.0, rate: 15.0 },
              { name: 'overtime', hours: 10.0, rate: 20.0 },
              { name: 'bonus', hours: 5.0, rate: 30.0 }
            ]
        }, {
            name: 'check2',
            earnings: [
              { name: 'hourly', hours: 20.0, rate: 18.0 },
              { name: 'overtime', hours: 20.0, rate: 24.0 }
            ]
        }]
    }, {
        name: 'Jane Smith',
        checks: [{
            name: 'check1',
            earnings: [
              { name: 'hourly', hours: 30.0, rate: 15.0 },
              { name: 'overtime', hours: 10.0, rate: 20.0 },
              { name: 'bonus', hours: 5.0, rate: 30.0 }
            ]
        }, {
            name: 'check2',
            earnings: [
              { name: 'hourly', hours: 20.0, rate: 18.0 },
              { name: 'overtime', hours: 20.0, rate: 24.0 }
            ]
        }]
    }];
 
    // workers tree
    var workersGrid = wijmo.Control.getControl('#workersGrid');
    workersGrid.headersVisibility = 'Column';
    workersGrid.childItemsPath = ['checks', 'earnings'];
    workersGrid.itemsSource = workers;
});
1
2
3
4
5
6
7
8
9
10
// This file locates: "Content/css/Lesson/C1FlexGrid/TreeGrids.css".
.wj-flexgrid {
  max-height: 220px;
}
.wj-cell.wj-group {
  border: none;
}
.wj-cell.wj-group:not(.wj-state-selected):not(.wj-state-multi-selected) {
  background-color: white;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
using System.Web.Mvc;
 
namespace LearnMvcClient.Controllers
{
    public partial class C1FlexGridController : Controller
    {
        // GET: TreeGrids
        public ActionResult TreeGrids()
        {
            return View();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<h1>
    @Html.Raw(Resources.C1FlexGrid.TreeGrids_Title)
</h1>
<p>
    @Html.Raw(Resources.C1FlexGrid.TreeGrids_Text1)
</p>
 
<p>
    @Html.Raw(Resources.C1FlexGrid.TreeGrids_Text2)
</p>
<p>
    @Html.Raw(Resources.C1FlexGrid.TreeGrids_Text3)
</p>
 
<label for="asTree">
    @Html.Raw(Resources.C1FlexGrid.TreeGrids_Text4)
    <input id="asTree" type="checkbox" checked="checked">
</label>
 
@Html.C1().FlexGrid().Id("familyGrid")
 
<p>
    @Html.Raw(Resources.C1FlexGrid.TreeGrids_Text5)
</p>
<p>
    @Html.Raw(Resources.C1FlexGrid.TreeGrids_Text6)
</p>
@(Html.C1().FlexGrid().Id("workersGrid")
    .AutoGenerateColumns(false)
    .Columns(cs=>
    {
        cs.Add().Binding("name");
        cs.Add().Binding("hours").DataType(C1.Web.Mvc.Grid.DataType.Number);
        cs.Add().Binding("rate").DataType(C1.Web.Mvc.Grid.DataType.Number);
    })
)