Column Groups (Object Model)

In addition to the possibility to define grid's columnGroups property using a POJO array, you can use reactive ColumnGroupCollection of ColumnGroup objects for this purpose. In frameworks, you can use corresponding components in framework templates, along with cell templates defining cells and group headers content.

This object model gives you a possibility to change group properties and to restructure the groups tree without recreating the whole tree.

Learn about FlexGrid | FlexGrid API Reference

The demo is being dynamically compiled to support real-time code editing... For quicker access to features, switch to the "JavaScript" tab for a smoother experience! :)
app.js
index.html
data.js
styles.css
Copy to CodeMine
loading...
import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo-core.css'; import './styles.css'; import { FlexGrid, ColumnGroup, ColumnGroupCollection } from '@mescius/wijmo.grid'; import { toggleClass } from '@mescius/wijmo'; import * as DataService from './data'; document.readyState === 'complete' ? init() : window.onload = init; function init() { let theGrid = new FlexGrid('#theGrid', { headersVisibility: 'Column', alternatingRowStep: 0, showMarquee: true, showSelectedHeaders: 'All', autoGenerateColumns: false, columnGroups: new ColumnGroupCollection([ new ColumnGroup({ binding: 'name', header: 'Name', width: 150 }), new ColumnGroup({ binding: 'currency', header: 'Curr', width: 80, align: 'center' }), new ColumnGroup({ header: 'Allocation', align: 'center', collapseTo: 'alloc.amount', columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'alloc.stock', header: 'Stocks', format: 'p0', width: 80 }), new ColumnGroup({ binding: 'alloc.bond', header: 'Bonds', format: 'p0', width: 80 }), new ColumnGroup({ header: 'Detail', align: 'center', columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'alloc.cash', header: 'Cash', format: 'p0', width: 80 }), new ColumnGroup({ binding: 'alloc.other', header: 'Other', format: 'p0', width: 80 }), ]) }), new ColumnGroup({ binding: 'alloc.amount', header: 'Amount', format: 'c0', width: 100, cssClass: 'main-column' }), ]) }), new ColumnGroup({ header: 'Perf', align: 'center', columns: new ColumnGroupCollection([ new ColumnGroup({ header: 'Short', align: 'center', collapseTo: 'perf.ytd', isCollapsed: true, columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'perf.ytd', header: 'YTD', format: 'p2', width: 100, cssClass: 'main-column' }), new ColumnGroup({ binding: 'perf.m1', header: '1 M', format: 'p2', width: 80 }), ]) }), new ColumnGroup({ header: 'Long', align: 'center', collapseTo: 'perf.m12', isCollapsed: true, columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'perf.m6', header: '6 M', format: 'p2', width: 80 }), new ColumnGroup({ binding: 'perf.m12', header: '12 M', format: 'p2', width: 100, cssClassAll: 'main-column' }), ]) }), ]) }), ]), itemsSource: DataService.getData(), }); // init collapse/expand animation checkbox const setAnimation = (animated) => { toggleClass(theGrid.hostElement, 'animated', animated); }; const animChk = document.getElementById('animated'); animChk.addEventListener('click', e => setAnimation(e.target.checked)); animChk.checked = true; setAnimation(animChk.checked); // init use cell templates checkbox const setUseTemplates = (useTemplates) => { const cellTemplate = useTemplates ? cell => { const grid = cell.row.grid; const rowIdx = cell.row.index; const colIdx = cell.col.index; const cssClass = grid.getCellData(rowIdx, colIdx, false) > .2 ? 'big-val' : 'small-val'; const value = grid.getCellData(rowIdx, colIdx, true); return `<span class="${cssClass}">${value}</span>`; } : null; theGrid.getColumn('alloc.stock').cellTemplate = cellTemplate; theGrid.getColumn('alloc.bond').cellTemplate = cellTemplate; theGrid.getColumn('alloc.cash').cellTemplate = cellTemplate; theGrid.getColumn('alloc.other').cellTemplate = cellTemplate; }; const tplChk = document.getElementById('templates'); tplChk.addEventListener('click', e => setUseTemplates(e.target.checked)); tplChk.checked = true; setUseTemplates(tplChk.checked); }
import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo-core.css'; import './styles.css'; import { FlexGrid, ColumnGroup, ColumnGroupCollection } from '@mescius/wijmo.grid'; import { toggleClass } from '@mescius/wijmo'; import * as DataService from './data'; document.readyState === 'complete' ? init() : window.onload = init; function init() { let theGrid = new FlexGrid('#theGrid', { headersVisibility: 'Column', alternatingRowStep: 0, showMarquee: true, showSelectedHeaders: 'All', autoGenerateColumns: false, columnGroups: new ColumnGroupCollection([ new ColumnGroup({ binding: 'name', header: 'Name', width: 150 }), new ColumnGroup({ binding: 'currency', header: 'Curr', width: 80, align: 'center' }), new ColumnGroup({ header: 'Allocation', align: 'center', collapseTo: 'alloc.amount', columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'alloc.stock', header: 'Stocks', format: 'p0', width: 80 }), new ColumnGroup({ binding: 'alloc.bond', header: 'Bonds', format: 'p0', width: 80 }), new ColumnGroup({ header: 'Detail', align: 'center', columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'alloc.cash', header: 'Cash', format: 'p0', width: 80 }), new ColumnGroup({ binding: 'alloc.other', header: 'Other', format: 'p0', width: 80 }), ]) }), new ColumnGroup({ binding: 'alloc.amount', header: 'Amount', format: 'c0', width: 100, cssClass: 'main-column' }), ]) }), new ColumnGroup({ header: 'Perf', align: 'center', columns: new ColumnGroupCollection([ new ColumnGroup({ header: 'Short', align: 'center', collapseTo: 'perf.ytd', isCollapsed: true, columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'perf.ytd', header: 'YTD', format: 'p2', width: 100, cssClass: 'main-column' }), new ColumnGroup({ binding: 'perf.m1', header: '1 M', format: 'p2', width: 80 }), ]) }), new ColumnGroup({ header: 'Long', align: 'center', collapseTo: 'perf.m12', isCollapsed: true, columns: new ColumnGroupCollection([ new ColumnGroup({ binding: 'perf.m6', header: '6 M', format: 'p2', width: 80 }), new ColumnGroup({ binding: 'perf.m12', header: '12 M', format: 'p2', width: 100, cssClassAll: 'main-column' }), ]) }), ]) }), ]), itemsSource: DataService.getData(), }); // init collapse/expand animation checkbox const setAnimation = (animated) => { toggleClass(theGrid.hostElement, 'animated', animated); }; const animChk = document.getElementById('animated'); animChk.addEventListener('click', e => setAnimation(e.target.checked)); animChk.checked = true; setAnimation(animChk.checked); // init use cell templates checkbox const setUseTemplates = (useTemplates) => { const cellTemplate = useTemplates ? cell => { const grid = cell.row.grid; const rowIdx = cell.row.index; const colIdx = cell.col.index; const cssClass = grid.getCellData(rowIdx, colIdx, false) > .2 ? 'big-val' : 'small-val'; const value = grid.getCellData(rowIdx, colIdx, true); return `<span class="${cssClass}">${value}</span>`; } : null; theGrid.getColumn('alloc.stock').cellTemplate = cellTemplate; theGrid.getColumn('alloc.bond').cellTemplate = cellTemplate; theGrid.getColumn('alloc.cash').cellTemplate = cellTemplate; theGrid.getColumn('alloc.other').cellTemplate = cellTemplate; }; const tplChk = document.getElementById('templates'); tplChk.addEventListener('click', e => setUseTemplates(e.target.checked)); tplChk.checked = true; setUseTemplates(tplChk.checked); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>MESCIUS Wijmo FlexGrid Column Groups with Templates</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.5/system.src.js" integrity="sha512-skZbMyvYdNoZfLmiGn5ii6KmklM82rYX2uWctBhzaXPxJgiv4XBwJnFGr5k8s+6tE1pcR1nuTKghozJHyzMcoA==" crossorigin="anonymous"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <main class="container-fluid"> <label> Collapse/Expand Animation <input id="animated" type="checkbox" /> </label> <label> Use cell templates <input id="templates" type="checkbox" /> </label> <div id="theGrid" /> </main> </body> </html>
// get some sample data export function getData() { return [{ name: 'Constant Growth', currency: 'USD', perf: { ytd: .0523, m1: 0.0142, m6: 0.0443, m12: 0.0743 }, alloc: { stock: 0.17, bond: 0.32, cash: 0.36, other: 0.15, amount: 23432 } }, { name: 'Optimus Prime', currency: 'EUR', perf: { ytd: .0343, m1: 0.043, m6: 0.0244, m12: 0.0543 }, alloc: { stock: 0.61, bond: 0.8, cash: 0.9, other: 0.22, amount: 43223 } }, { name: 'Crypto Planet', currency: 'BTC', perf: { ytd: .0343, m1: 0.014, m6: 0.034, m12: 0.01243 }, alloc: { stock: 0.1, bond: 0, cash: 0, other: 0.9, amount: 2234 } }, { name: 'MegaZone', currency: 'EUR', perf: { ytd: .0443, m1: 0.034, m6: 0.0424, m12: 0.0343 }, alloc: { stock: 0.51, bond: 0.9, cash: 0.8, other: 0.12, amount: 32234 } }, { name: 'Serenity', currency: 'YEN', perf: { ytd: .0522, m1: 0.0143, m6: 0.0458, m12: 0.0732 }, alloc: { stock: 0.66, bond: 0.09, cash: 0.19, other: 0.06, amount: 65624 } }]; }
label { display: block; } .wj-flexgrid { margin: 10px 0; } /* highlight the main column in the group */ .wj-flexgrid .wj-cells .wj-cell.main-column { background: #e3f4ff; } /* some conditional formatting */ .big-val { font-weight: bold; color: darkgreen; } .small-val { font-style: italic; color: rgb(202, 0, 0); } /* some animation when collapsing/expanding the groups */ .wj-flexgrid.animated .wj-colheaders .wj-header.wj-cell.wj-colgroup { transition: all .2s; }
(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', '@mescius/wijmo': 'npm:@mescius/wijmo/index.js', '@mescius/wijmo.input': 'npm:@mescius/wijmo.input/index.js', '@mescius/wijmo.styles': 'npm:@mescius/wijmo.styles', '@mescius/wijmo.cultures': 'npm:@mescius/wijmo.cultures', '@mescius/wijmo.chart': 'npm:@mescius/wijmo.chart/index.js', '@mescius/wijmo.chart.analytics': 'npm:@mescius/wijmo.chart.analytics/index.js', '@mescius/wijmo.chart.animation': 'npm:@mescius/wijmo.chart.animation/index.js', '@mescius/wijmo.chart.annotation': 'npm:@mescius/wijmo.chart.annotation/index.js', '@mescius/wijmo.chart.finance': 'npm:@mescius/wijmo.chart.finance/index.js', '@mescius/wijmo.chart.finance.analytics': 'npm:@mescius/wijmo.chart.finance.analytics/index.js', '@mescius/wijmo.chart.hierarchical': 'npm:@mescius/wijmo.chart.hierarchical/index.js', '@mescius/wijmo.chart.interaction': 'npm:@mescius/wijmo.chart.interaction/index.js', '@mescius/wijmo.chart.radar': 'npm:@mescius/wijmo.chart.radar/index.js', '@mescius/wijmo.chart.render': 'npm:@mescius/wijmo.chart.render/index.js', '@mescius/wijmo.chart.webgl': 'npm:@mescius/wijmo.chart.webgl/index.js', '@mescius/wijmo.chart.map': 'npm:@mescius/wijmo.chart.map/index.js', '@mescius/wijmo.gauge': 'npm:@mescius/wijmo.gauge/index.js', '@mescius/wijmo.grid': 'npm:@mescius/wijmo.grid/index.js', '@mescius/wijmo.grid.detail': 'npm:@mescius/wijmo.grid.detail/index.js', '@mescius/wijmo.grid.filter': 'npm:@mescius/wijmo.grid.filter/index.js', '@mescius/wijmo.grid.search': 'npm:@mescius/wijmo.grid.search/index.js', '@mescius/wijmo.grid.style': 'npm:@mescius/wijmo.grid.style/index.js', '@mescius/wijmo.grid.grouppanel': 'npm:@mescius/wijmo.grid.grouppanel/index.js', '@mescius/wijmo.grid.multirow': 'npm:@mescius/wijmo.grid.multirow/index.js', '@mescius/wijmo.grid.transposed': 'npm:@mescius/wijmo.grid.transposed/index.js', '@mescius/wijmo.grid.transposedmultirow': 'npm:@mescius/wijmo.grid.transposedmultirow/index.js', '@mescius/wijmo.grid.pdf': 'npm:@mescius/wijmo.grid.pdf/index.js', '@mescius/wijmo.grid.sheet': 'npm:@mescius/wijmo.grid.sheet/index.js', '@mescius/wijmo.grid.xlsx': 'npm:@mescius/wijmo.grid.xlsx/index.js', '@mescius/wijmo.grid.selector': 'npm:@mescius/wijmo.grid.selector/index.js', '@mescius/wijmo.grid.cellmaker': 'npm:@mescius/wijmo.grid.cellmaker/index.js', '@mescius/wijmo.nav': 'npm:@mescius/wijmo.nav/index.js', '@mescius/wijmo.odata': 'npm:@mescius/wijmo.odata/index.js', '@mescius/wijmo.olap': 'npm:@mescius/wijmo.olap/index.js', '@mescius/wijmo.rest': 'npm:@mescius/wijmo.rest/index.js', '@mescius/wijmo.pdf': 'npm:@mescius/wijmo.pdf/index.js', '@mescius/wijmo.pdf.security': 'npm:@mescius/wijmo.pdf.security/index.js', '@mescius/wijmo.viewer': 'npm:@mescius/wijmo.viewer/index.js', '@mescius/wijmo.xlsx': 'npm:@mescius/wijmo.xlsx/index.js', '@mescius/wijmo.undo': 'npm:@mescius/wijmo.undo/index.js', '@mescius/wijmo.interop.grid': 'npm:@mescius/wijmo.interop.grid/index.js', '@mescius/wijmo.touch': 'npm:@mescius/wijmo.touch/index.js', '@mescius/wijmo.cloud': 'npm:@mescius/wijmo.cloud/index.js', '@mescius/wijmo.barcode': 'npm:@mescius/wijmo.barcode/index.js', '@mescius/wijmo.barcode.common': 'npm:@mescius/wijmo.barcode.common/index.js', '@mescius/wijmo.barcode.composite': 'npm:@mescius/wijmo.barcode.composite/index.js', '@mescius/wijmo.barcode.specialized': 'npm:@mescius/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);