Custom Column Headers

By default, the MultiRow control uses the same layoutDefinition for column headers and for the cell data.

You may use the headerLayoutDefinition property to customize the layout of the column headers.

Learn about MultiRow | MultiRow API Reference

import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo.css'; import './styles.css'; import { MultiRow } from '@mescius/wijmo.grid.multirow'; import { getData, getLayoutDefinition, getHeaderLayoutDefinition } from './data'; document.readyState === 'complete' ? init() : window.onload = init; function init() { // create the MultiRow let theMultiRow = new MultiRow('#theMultiRow', { layoutDefinition: getLayoutDefinition(), headerLayoutDefinition: getHeaderLayoutDefinition(), itemsSource: getData() }); // toggle custom header layout document.getElementById('cbCustomHeaders').addEventListener('click', function (e) { theMultiRow.headerLayoutDefinition = e.target.checked ? getHeaderLayoutDefinition() : null; }); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>MESCIUS Wijmo MultiRow Custom Column Headers</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> <div class="container-fluid"> <label> Custom Headers: <input type="checkbox" checked id="cbCustomHeaders"> </label> <div id="theMultiRow"></div> </div> </body> </html>
// data export function getData() { var data = []; var products = 'Widgets,Gadgets,Sprockets'.split(','); var year = new Date().getFullYear() - 1; for (let i = 0; i < 100; i++) { let item = { id: i, product: products[i % products.length] }; for (let yr = year; yr <= year + 1; yr++) { let total = 0; for (let q = 1; q <= 4; q++) { let key = yr + ' Q' + q; let value = Math.round(Math.random() * 50); item[key] = value; total += value; } item[yr + ' Total'] = total; } data.push(item); } return data; } // data layout definition export function getLayoutDefinition() { let yr = new Date().getFullYear(); return [ { header: 'Product', cells: [ { binding: 'product', header: 'Product' } ] }, { colspan: 5, header: (yr - 1).toString(), align: 'center', cells: [ { binding: (yr - 1) + ' Q1', header: 'Q1' }, { binding: (yr - 1) + ' Q2', header: 'Q2' }, { binding: (yr - 1) + ' Q3', header: 'Q3' }, { binding: (yr - 1) + ' Q4', header: 'Q4' }, { binding: (yr - 1) + ' Total', header: 'Total', cssClass: 'yearly-total' } ] }, { colspan: 5, header: yr.toString(), align: 'center', cells: [ { binding: yr + ' Q1', header: 'Q1' }, { binding: yr + ' Q2', header: 'Q2' }, { binding: yr + ' Q3', header: 'Q3' }, { binding: yr + ' Q4', header: 'Q4' }, { binding: yr + ' Total', header: 'Total', cssClass: 'yearly-total' } ] } ]; } // header layout definition export function getHeaderLayoutDefinition() { let yr = new Date().getFullYear(); return [ { header: 'Product', cells: [ { binding: 'product', header: 'Product' } ] }, { cells: [ { header: (yr - 1).toString(), align: 'center', colspan: 5 }, { binding: (yr - 1) + ' Q1', header: 'Q1' }, { binding: (yr - 1) + ' Q2', header: 'Q2' }, { binding: (yr - 1) + ' Q3', header: 'Q3' }, { binding: (yr - 1) + ' Q4', header: 'Q4' }, { binding: (yr - 1) + ' Total', header: 'Total' } ] }, { cells: [ { header: yr.toString(), align: 'center', colspan: 5 }, { binding: yr + ' Q1', header: 'Q1' }, { binding: yr + ' Q2', header: 'Q2' }, { binding: yr + ' Q3', header: 'Q3' }, { binding: yr + ' Q4', header: 'Q4' }, { binding: yr + ' Total', header: 'Total' } ] } ]; }
.wj-multirow { height: 400px; margin: 6px 0; }
(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.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);