Row Details

Sometimes rows are bound to data objects that contain more information than would fit easily on FlexGrid. In these scenarios, you may want to use the FlexGridDetailProvider class that is included with the wijmo.grid.detail module. The FlexGridDetailProvider extends the FlexGrid by adding collapse/expand buttons to row headers, and a createDetailCell method you can use to provide additional details about an item.

Learn about FlexGrid | Nested Grids Documentation | FlexGrid API Reference

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjOdata from '@grapecity/wijmo.odata'; import * as wjGrid from '@grapecity/wijmo.grid'; import * as wjGridDetail from '@grapecity/wijmo.grid.detail'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // // get OData categories and products var url = 'https://services.odata.org/Northwind/Northwind.svc'; var categories = new wjOdata.ODataCollectionView(url, 'Categories', { fields: ['CategoryID', 'CategoryName', 'Description'] }); var products = new wjOdata.ODataCollectionView(url, 'Products'); // // shared column definitions var categoryColumns = [ { binding: 'CategoryName', header: 'Category Name', width: '*' }, { binding: 'Description', header: 'Description', width: '2*' } ]; // // get products for a given category function getProducts(categoryID) { var arr = []; products.items.forEach(function (product) { if (product.CategoryID == categoryID) { arr.push(product); } }); return arr; } // // grid with HTML detail var htmlDetail = new wjGrid.FlexGrid('#htmlDetail', { autoGenerateColumns: false, columns: categoryColumns, itemsSource: categories, isReadOnly: true }); // // html detail provider var dpHtml = new wjGridDetail.FlexGridDetailProvider(htmlDetail, { // // use animation when showing details isAnimated: true, // // create detail cells for a given row createDetailCell: function (row) { // // build detail content for the current category var cat = row.dataItem; var prods = getProducts(cat.CategoryID); var html = 'ID: <b>' + cat.CategoryID + '</b><br/>'; html += 'Name: <b>' + cat.CategoryName + '</b><br/>'; html += 'Description: <b>' + cat.Description + '</b><br/>'; html += 'Products: <b>' + prods.length + ' items</b><br/>'; html += '<ol>'; prods.forEach(function (product) { html += '<li>' + product.ProductName + '</li>'; }); html += '</ol>'; // // create and return detail cell var cell = document.createElement('div'); cell.innerHTML = html; return cell; } }); // // grid with grid detail var gridDetail = new wjGrid.FlexGrid('#gridDetail', { autoGenerateColumns: false, columns: categoryColumns, itemsSource: categories, isReadOnly: true }); // // grid detail provider var dpGrid = new wjGridDetail.FlexGridDetailProvider(gridDetail, { // // use animation when showing details isAnimated: true, // // limit height of detail rows maxHeight: 150, // // create detail cells for a given row createDetailCell: function (row) { var cell = document.createElement('div'); var detailGrid = new wjGrid.FlexGrid(cell, { headersVisibility: wjGrid.HeadersVisibility.Column, isReadOnly: true, autoGenerateColumns: false, itemsSource: 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' } ] }); return cell; } }); // }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexGrid Nested Grids</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div class="container-fluid"> <h3> HTML in Row Details</h3> <p> This grid shows product categories on each row. Expanding the rows shows an HTML element with information about the products in that category:</p> <div id="htmlDetail"></div> <h3> Grids in Row Details</h3> <p> You can add anything you want to the detail rows, including other grids. This example shows the same categories, but the detail row uses another grid to show the products:</p> <div id="gridDetail"></div> </div> </body> </html>
.wj-flexgrid { max-height: 350px; } body { margin-bottom: 20pt; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'jszip': 'npm:jszip/dist/jszip.js', '@grapecity/wijmo': 'npm:@grapecity/wijmo/index.js', '@grapecity/wijmo.input': 'npm:@grapecity/wijmo.input/index.js', '@grapecity/wijmo.styles': 'npm:@grapecity/wijmo.styles', '@grapecity/wijmo.cultures': 'npm:@grapecity/wijmo.cultures', '@grapecity/wijmo.chart': 'npm:@grapecity/wijmo.chart/index.js', '@grapecity/wijmo.chart.analytics': 'npm:@grapecity/wijmo.chart.analytics/index.js', '@grapecity/wijmo.chart.animation': 'npm:@grapecity/wijmo.chart.animation/index.js', '@grapecity/wijmo.chart.annotation': 'npm:@grapecity/wijmo.chart.annotation/index.js', '@grapecity/wijmo.chart.finance': 'npm:@grapecity/wijmo.chart.finance/index.js', '@grapecity/wijmo.chart.finance.analytics': 'npm:@grapecity/wijmo.chart.finance.analytics/index.js', '@grapecity/wijmo.chart.hierarchical': 'npm:@grapecity/wijmo.chart.hierarchical/index.js', '@grapecity/wijmo.chart.interaction': 'npm:@grapecity/wijmo.chart.interaction/index.js', '@grapecity/wijmo.chart.radar': 'npm:@grapecity/wijmo.chart.radar/index.js', '@grapecity/wijmo.chart.render': 'npm:@grapecity/wijmo.chart.render/index.js', '@grapecity/wijmo.chart.webgl': 'npm:@grapecity/wijmo.chart.webgl/index.js', '@grapecity/wijmo.gauge': 'npm:@grapecity/wijmo.gauge/index.js', '@grapecity/wijmo.grid': 'npm:@grapecity/wijmo.grid/index.js', '@grapecity/wijmo.grid.detail': 'npm:@grapecity/wijmo.grid.detail/index.js', '@grapecity/wijmo.grid.filter': 'npm:@grapecity/wijmo.grid.filter/index.js', '@grapecity/wijmo.grid.search': 'npm:@grapecity/wijmo.grid.search/index.js', '@grapecity/wijmo.grid.grouppanel': 'npm:@grapecity/wijmo.grid.grouppanel/index.js', '@grapecity/wijmo.grid.multirow': 'npm:@grapecity/wijmo.grid.multirow/index.js', '@grapecity/wijmo.grid.transposed': 'npm:@grapecity/wijmo.grid.transposed/index.js', '@grapecity/wijmo.grid.transposedmultirow': 'npm:@grapecity/wijmo.grid.transposedmultirow/index.js', '@grapecity/wijmo.grid.pdf': 'npm:@grapecity/wijmo.grid.pdf/index.js', '@grapecity/wijmo.grid.sheet': 'npm:@grapecity/wijmo.grid.sheet/index.js', '@grapecity/wijmo.grid.xlsx': 'npm:@grapecity/wijmo.grid.xlsx/index.js', '@grapecity/wijmo.grid.selector': 'npm:@grapecity/wijmo.grid.selector/index.js', '@grapecity/wijmo.grid.cellmaker': 'npm:@grapecity/wijmo.grid.cellmaker/index.js', '@grapecity/wijmo.nav': 'npm:@grapecity/wijmo.nav/index.js', '@grapecity/wijmo.odata': 'npm:@grapecity/wijmo.odata/index.js', '@grapecity/wijmo.olap': 'npm:@grapecity/wijmo.olap/index.js', '@grapecity/wijmo.pdf': 'npm:@grapecity/wijmo.pdf/index.js', '@grapecity/wijmo.pdf.security': 'npm:@grapecity/wijmo.pdf.security/index.js', '@grapecity/wijmo.viewer': 'npm:@grapecity/wijmo.viewer/index.js', '@grapecity/wijmo.xlsx': 'npm:@grapecity/wijmo.xlsx/index.js', '@grapecity/wijmo.undo': 'npm:@grapecity/wijmo.undo/index.js', '@grapecity/wijmo.interop.grid': 'npm:@grapecity/wijmo.interop.grid/index.js', '@grapecity/wijmo.touch': 'npm:@grapecity/wijmo.touch/index.js', '@grapecity/wijmo.cloud': 'npm:@grapecity/wijmo.cloud/index.js', '@grapecity/wijmo.barcode': 'npm:@grapecity/wijmo.barcode/index.js', '@grapecity/wijmo.barcode.common': 'npm:@grapecity/wijmo.barcode.common/index.js', '@grapecity/wijmo.barcode.composite': 'npm:@grapecity/wijmo.barcode.composite/index.js', '@grapecity/wijmo.barcode.specialized': 'npm:@grapecity/wijmo.barcode.specialized/index.js', 'jszip': 'npm:jszip/dist/jszip.js', 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);