Row Details

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.

Using the FlexGridDetailProvider class

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;
    }
});

Using the wj-flex-grid-detail directive

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.

True False

Select the value for the detailVisibilityMode property to determine when the row details are visible.

Code Selection ExpandSingle ExpandMulti

Using the wj-flex-grid-detail directive with another template

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>
ID: {{$item.CategoryID}}
Name: {{$item.CategoryName}}
Description: {{$item.Description}}
  1. {{p.ProductName}}

Using custom elements to show or hide details

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}}
ID: {{$item.CategoryID}}
Name: {{$item.CategoryName}}
Description: {{$item.Description}}