Master Detail

The simplest way to deal with hierarchical data is the master-detail model. Use a control to select the main item and one or more additional controls to show the main item's details.

For example, the ComboBox below is used as a master control. Select a country from the combo and the grid below will show the items in that country:

Id
Country
Product
Date
Sales
Expenses
0
US
Phones
7/12/2025
5,605.96
3,966.75
6
US
Cars
7/18/2025
905.84
1,682.36
12
US
Stereos
7/24/2025
1,530.07
3,818.35
18
US
Watches
7/30/2025
4,770.05
4,582.90
24
US
Computers
8/5/2025
806.84
4,137.52
30
US
Phones
8/11/2025
673.43
1,333.89
36
US
Cars
8/17/2025
2,967.98
2,909.98
42
US
Stereos
8/23/2025
4,720.74
2,270.59
48
US
Watches
8/29/2025
3,059.50
453.83

In the next example, FlexGrid is used as the master control. Select an item on the grid and see the details in the controls below:

Master

Id
Country
Product
Date
Sales
Expenses
0
US
Phones
7/12/2025
5,605.96
3,966.75
1
Germany
Cars
7/13/2025
2,059.76
4,524.33
2
UK
Stereos
7/14/2025
5,375.35
2,198.32
3
Japan
Watches
7/15/2025
3,232.98
425.33
4
Italy
Computers
7/16/2025
1,811.63
723.34
5
Greece
Phones
7/17/2025
4,800.70
4,660.45
6
US
Cars
7/18/2025
905.84
1,682.36
7
Germany
Stereos
7/19/2025
958.84
3,042.83
8
UK
Watches
7/20/2025
1,833.71
4,856.97
9
Japan
Computers
7/21/2025
2,506.13
4,105.96
10
Italy
Phones
7/22/2025
9,058.61
1,819.51
11
Greece
Cars
7/23/2025
7,135.53
4,506.60
12
US
Stereos
7/24/2025
1,530.07
3,818.35
13
Germany
Watches
7/25/2025
5,376.00
2,919.46
14
UK
Computers
7/26/2025
3,132.21
2,258.33
15
Japan
Phones
7/27/2025
7,955.42
1,350.31
16
Italy
Cars
7/28/2025
8,795.63
2,478.68
17
Greece
Stereos
7/29/2025
9,486.63
3,296.05
18
US
Watches
7/30/2025
4,770.05
4,582.90
19
Germany
Computers
7/31/2025
7,972.13
2,313.70
20
UK
Phones
8/1/2025
5,756.28
4,783.73
21
Japan
Cars
8/2/2025
9,042.49
1,015.20
22
Italy
Stereos
8/3/2025
1,794.23
4,009.24
23
Greece
Watches
8/4/2025
8,764.48
3,393.72
24
US
Computers
8/5/2025
806.84
4,137.52
25
Germany
Phones
8/6/2025
347.11
3,283.60
26
UK
Cars
8/7/2025
4,488.21
1,891.25
27
Japan
Stereos
8/8/2025
5,957.40
2,421.34
28
Italy
Watches
8/9/2025
4,152.94
4,971.00
29
Greece
Computers
8/10/2025
1,974.83
2,803.47
30
US
Phones
8/11/2025
673.43
1,333.89
31
Germany
Cars
8/12/2025
7,750.57
694.45
32
UK
Stereos
8/13/2025
9,630.07
587.64
33
Japan
Watches
8/14/2025
6,587.01
1,585.89
34
Italy
Computers
8/15/2025
6,428.55
4,092.74
35
Greece
Phones
8/16/2025
1,402.30
916.88
36
US
Cars
8/17/2025
2,967.98
2,909.98
37
Germany
Stereos
8/18/2025
9,766.87
1,422.92
38
UK
Watches
8/19/2025
3,438.31
2,418.24
39
Japan
Computers
8/20/2025
93.40
9.74
40
Italy
Phones
8/21/2025
6,923.20
4,601.49
41
Greece
Cars
8/22/2025
8,865.96
3,922.28
42
US
Stereos
8/23/2025
4,720.74
2,270.59
43
Germany
Watches
8/24/2025
378.16
3,187.48
44
UK
Computers
8/25/2025
7,894.48
3,022.93
45
Japan
Phones
8/26/2025
2,182.85
1,256.49
46
Italy
Cars
8/27/2025
5,962.54
413.83
47
Greece
Stereos
8/28/2025
1,699.59
142.63
48
US
Watches
8/29/2025
3,059.50
453.83
49
Germany
Computers
8/30/2025
512.85
3,197.89

Detail

Country:
Product:
Date:
Sales:
Expenses:
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
// This file locates: "Scripts/Lesson/C1FlexGrid/MasterDetail.js".
c1.documentReady(function () {
    // create some random data
    var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
    var products = 'Phones,Cars,Stereos,Watches,Computers'.split(',');
    var data = [];
    for (var i = 0; i < 50; i++) {
        data.push({
            id: i,
            country: countries[i % countries.length],
            product: products[i % products.length],
            date: wijmo.DateTime.addDays(new Date(), i),
            sales: Math.random() * 10000,
            expenses: Math.random() * 5000,
        });
    }
 
    // show countries in combo
    var theCombo = wijmo.Control.getControl('#theCombo');
    theCombo.selectedIndexChanged.addHandler(function (s, e) {
        view.refresh();
    });
 
    // show items for the selected country in the detail grid
    var theGridDetail = wijmo.Control.getControl('#theGridDetail');
    theGridDetail.itemsSource = data;
 
    //show items for the selected country
    var view = theGridDetail.collectionView;
    view.filter = function (item) {
        return item.country == theCombo.text;
    }
 
    // using a grid as the master
    var theGridMaster = wijmo.Control.getControl('#theGridMaster');
    theGridMaster.itemsSource = data;
    theGridMaster.selectionChanged.addHandler(function (s, e) {
        updateDetailControls();
    });
 
    // update detail controls when selection changes
    function updateDetailControls() {
        var item = theGridMaster.collectionView.currentItem;
        var bndCtls = document.querySelectorAll('.bnd-ctl');
        for (var i = 0; i < bndCtls.length; i++) {
            var host = bndCtls[i];
            var prop = host.id.substr(3).toLowerCase();
            var ctl = wijmo.Control.getControl(host);
            if (wijmo.isString(item[prop])) {
                ctl.text = item[prop];
            } else {
                ctl.value = item[prop];
            }
        }
    }
 
    // set a property on the current item
    function setProperty(prop, val) {
        var v = theGridMaster.collectionView;
        v.editItem(v.currentItem);
        v.currentItem[prop] = val;
        v.commitEdit();
    }
 
    // define detail controls
    var theCountry = wijmo.Control.getControl('#theCountry');
    theCountry.textChanged.addHandler(function (s, e) {
        setProperty('country', s.text);
    });
    var theProduct = wijmo.Control.getControl('#theProduct');
    theProduct.textChanged.addHandler(function (s, e) {
        setProperty('product', s.text);
    });
    var theDate = wijmo.Control.getControl('#theDate');
    theDate.valueChanged.addHandler(function (s, e) {
        setProperty('date', s.value);
    });
    var theSales = wijmo.Control.getControl('#theSales');
    theSales.valueChanged.addHandler(function (s, e) {
        setProperty('sales', s.value);
    });
    var theExpenses = wijmo.Control.getControl('#theExpenses');
    theExpenses.valueChanged.addHandler(function (s, e) {
        setProperty('expenses', s.value);
    });
});
1
2
3
4
5
6
7
8
// This file locates: "Content/css/Lesson/C1FlexGrid/MasterDetail.css".
.wj-flexgrid {
  max-height: 220px;
}
.tbl-spaced td {
  vertical-align: middle;
  margin: 3px;
}
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: MasterDetail
        public ActionResult MasterDetail()
        {
            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
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
@{
    var countries = new[] { "US", "Germany", "UK", "Japan", "Italy", "Greece" };
    var products = new[] { "Phones", "Cars", "Stereos", "Watches", "Computers" };
}
 
<h1>
    @Html.Raw(Resources.C1FlexGrid.MasterDetail_Title)
</h1>
<p>
    @Html.Raw(Resources.C1FlexGrid.MasterDetail_Text1)
</p>
 
<p>
    @Html.Raw(Resources.C1FlexGrid.MasterDetail_Text2)
</p>
 
<label>
    @Html.Raw(Resources.C1FlexGrid.MasterDetail_Text3)
    @Html.C1().ComboBox().Id("theCombo").Bind(countries)
</label>
@Html.C1().FlexGrid().Id("theGridDetail")
 
<p>
    @Html.Raw(Resources.C1FlexGrid.MasterDetail_Text4)
</p>
 
<h3>
    @Html.Raw(Resources.C1FlexGrid.MasterDetail_Title1)
</h3>
@Html.C1().FlexGrid().Id("theGridMaster").SelectionMode(C1.Web.Mvc.Grid.SelectionMode.Row).IsReadOnly(true)
 
<h3>
    @Html.Raw(Resources.C1FlexGrid.MasterDetail_Title2)
</h3>
<table class="tbl-spaced">
    <tr>
        <td>@Html.Raw(Resources.C1FlexGrid.MasterDetail_Text5)</td>
        <td id="theCountry" class="bnd-ctl"></td>
        @Html.C1().ComboBox("#theCountry").Bind(countries)
    </tr>
    <tr>
        <td>@Html.Raw(Resources.C1FlexGrid.MasterDetail_Text6)</td>
        <td id="theProduct" class="bnd-ctl"></td>
        @Html.C1().ComboBox("#theProduct").Bind(products)
    </tr>
    <tr>
        <td>@Html.Raw(Resources.C1FlexGrid.MasterDetail_Text7)</td>
        <td id="theDate" class="bnd-ctl"></td>
        @Html.C1().InputDate("#theDate")
    </tr>
    <tr>
        <td>@Html.Raw(Resources.C1FlexGrid.MasterDetail_Text8)</td>
        <td id="theSales" class="bnd-ctl"></td>
        @Html.C1().InputNumber("#theSales").Format("n2").Step(10)
    </tr>
    <tr>
        <td>@Html.Raw(Resources.C1FlexGrid.MasterDetail_Text9)</td>
        <td id="theExpenses" class="bnd-ctl"></td>
        @Html.C1().InputNumber("#theExpenses").Format("n2").Step(10)
    </tr>
</table>