Each row on the grids below represents a product category. To see the products in each category, expand the rows by clicking the plus sign. Expanded rows show a "detail" row below containing arbitrary content (in this case a nested grid with product information).
The detail rows are implemented using the FlexGridDetailProvider class. The FlexGridDetailProvider class has a createDetailCell function that creates HTML elements to show the details for any row. The content of the detail cells is completely customizable.
In addition to the createDetailCell function, the FlexGridDetailProvider class has other properties that allow you to customize when the detail rows are displayed, their dimensions, etc.
This grid uses the FlexGridDetailProvider class directly. It specifies a createDetailCell function that creates child grids to show the products in the category represented by the main row.
The code looks like this:
// create FlexGridDetailProvider for "flex" control
var dp = new wijmo.grid.detail.FlexGridDetailProvider(s, {
// use animation when showing details
isAnimated: true,
// limit height of detail rows
maxHeight: 250,
// create detail cells for a given row
createDetailCell: function (row) {
var cell = document.createElement('div');
s.hostElement.appendChild(cell);
var detailGrid = new wijmo.grid.FlexGrid(cell, {
headersVisibility: wijmo.grid.HeadersVisibility.Column,
autoGenerateColumns: false,
itemsSource: $scope.getProducts(row.dataItem.CategoryID),
columns: [
{ header: 'ID', binding: 'ProductID' },
{ header: 'Name', binding: 'ProductName' },
{ header: 'Qty/Unit', binding: 'QuantityPerUnit' },
{ header: 'Unit Price', binding: 'UnitPrice' },
{ header: 'Discontinued', binding: 'Discontinued' }
]
});
cell.parentElement.removeChild(cell);
return cell;
},
// remove details from items with odd CategoryID
rowHasDetail: function (row) {
return row.dataItem.CategoryID % 2 == 0;
}
});
This grid uses the wj-flex-grid-detail directive. The directive contains a template with a child FlexGrid that shows the products in the category represented by the main row.
The markup looks like this:
<wj-flex-grid
items-source="categories">
<wj-flex-grid-column header="Name" binding="CategoryName"></wj-flex-grid-column>
<wj-flex-grid-column header="Description" binding="Description" width="*"></wj-flex-grid-column>
<wj-flex-grid-detail max-height="250" detail-visibility-mode="detailMode">
<wj-flex-grid
items-source="getProducts($item.CategoryID)"
headers-visibility="Column">
</wj-flex-grid>
</wj-flex-grid-detail>
</wj-flex-grid>
Select the value for the isAnimated property to determine whether to use animation when showing row details.
Select the value for the detailVisibilityMode property to determine when the row details are visible.
The grid below uses the wj-flex-grid-detail directive and specifies a template defined as HTML content, including a list created with an ng-repeat directive.
The markup looks like this:
<wj-flex-grid
items-source="categories">
<wj-flex-grid-column header="Name" binding="CategoryName"></wj-flex-grid-column>
<wj-flex-grid-column header="Description" binding="Description" width="*"></wj-flex-grid-column>
<wj-flex-grid-detail detail-visibility-mode="ExpandSingle" is-animated="true">
ID: <b>{{$item.CategoryID}}</b><br />
Name: <b>{{$item.CategoryName}}</b><br />
Description: <b>{{$item.Description}}</b><br />
<ol>
<li ng-repeat="p in getProducts($item.CategoryID).items">{{p.ProductName}}</li>
</ol>
</wj-flex-grid-detail>
</wj-flex-grid>
The wj-flex-grid-detail directive has a "control" attribute that you can use to access the methods in its FlexGridDetailProvider class. In this example, we use these methods in the markup to provide custom icons for expanding and collapsing the detail rows.
The nice thing about this approach is that it gives you total control over the user experience, including the appearance and behavior of the elements used to show and hide the detail rows.
The markup looks like this:
<wj-flex-grid
items-source="categories"
headers-visibility="Column"
selection-mode="Row">
<wj-flex-grid-column header="Name" binding="CategoryName" is-read-only="true" width="200">
<img ng-show="dp.isDetailVisible($row)" ng-click="dp.hideDetail($row)" src="resources/hide.png" />
<img ng-hide="dp.isDetailVisible($row)" ng-click="dp.showDetail($row, true)" src="resources/show.png" />
{{$item.CategoryName}}
</wj-flex-grid-column>
<wj-flex-grid-column header="Description" binding="Description" width="2*"></wj-flex-grid-column>
<wj-flex-grid-detail control="dp" detail-visibility-mode="Code" is-animated="true">
<div style="padding:12px;background-color:#cee6f7">
ID: <b>{{$item.CategoryID}}</b><br />
Name: <b>{{$item.CategoryName}}</b><br />
Description: <b>{{$item.Description}}</b><br />
<button class="btn btn-default" ng-click="dp.hideDetail($row)">Hide Detail</button>
</div>
</wj-flex-grid-detail>
</wj-flex-grid>
{{$item.CategoryName}}