Custom Merging (Vue)

By default, FlexGrid applies merging to cells based on their content.

In some cases, you may want to use different strategies for merging. You can achieve this by defining a class that extends the wijmo.grid.MergeManager class and assigning an object of that type to the grid's mergeManager property.

Learn about FlexGrid | Custom Merging Documentation | FlexGrid API Reference

This example uses Vue.

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.vue
index.html
Copy to CodeMine
loading...
<template> <main class="container-fluid"> <wj-flex-grid :initialized="onInitialized"></wj-flex-grid> </main> </template> <script setup> import * as wjCore from "@mescius/wijmo"; import * as wjGrid from "@mescius/wijmo.grid"; import { ref } from "vue"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __()); }; })(); var CustomMergeManager = (function (_super) { __extends(CustomMergeManager, _super); function CustomMergeManager() { return _super.call(this) || this; } CustomMergeManager.prototype.getMergedRange = function (panel, r, c, clip) { if (clip === void 0) { clip = true; } var rng = new wjGrid.CellRange(r, c); for (var i = rng.col; i < panel.columns.length - 1; i++) { if ( panel.getCellData(rng.row, i, true) != panel.getCellData(rng.row, i + 1, true) ) break; rng.col2 = i + 1; } for (var i = rng.col; i > 0; i--) { if ( panel.getCellData(rng.row, i, true) != panel.getCellData(rng.row, i - 1, true) ) break; rng.col = i - 1; } for (var i = rng.row; i < panel.rows.length - 1; i++) { if ( panel.getCellData(i, rng.col, true) != panel.getCellData(i + 1, rng.col, true) ) break; rng.row2 = i + 1; } for (var i = rng.row; i > 0; i--) { if ( panel.getCellData(i, rng.col, true) != panel.getCellData(i - 1, rng.col, true) ) break; rng.row = i - 1; } return rng; }; return CustomMergeManager; })(wjGrid.MergeManager); function onInitialized(flexGrid) { while (flexGrid.columns.length < 7) { flexGrid.columns.push(new wjGrid.Column()); } while (flexGrid.rows.length < 5) { flexGrid.rows.push(new wjGrid.Row()); } // configure the grid flexGrid.mergeManager = new CustomMergeManager(); flexGrid.formatItem.addHandler(centerCell); flexGrid.rowHeaders.columns[0].width = 80; flexGrid.rows.defaultSize = 40; flexGrid.alternatingRowStep = 0; flexGrid.isReadOnly = true; // populate the grid setData(flexGrid.columnHeaders, 0, ",Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday".split(",")); setData(flexGrid.cells, 0, "12:00,Walker,Morning Show,Morning Show,Sport,Weather,N/A,N/A".split(",")); setData(flexGrid.cells, 1, "13:00,Today Show,Today Show,Sesame Street,Football,Market Watch,N/A,N/A".split(",")); setData(flexGrid.cells, 2, "14:00,Today Show,Today Show,Kid Zone,Football,Soap Opera,N/A,N/A".split(",")); setData(flexGrid.cells, 3, "15:00,News,News,News,News,News,N/A,N/A".split(",")); setData(flexGrid.cells, 4, "16:00,News,News,News,News,News,N/A,N/A".split(",")); } function setData(p, r, cells) { if (p.cellType == wjGrid.CellType.Cell) { p.grid.rowHeaders.setCellData(r, 0, cells[0]); } for (var i = 1; i < cells.length; i++) { p.setCellData(r, i - 1, cells[i]); } } function centerCell(s, e) { if (e.cell.children.length == 0) { e.cell.innerHTML = "<div>" + e.cell.innerHTML + "</div>"; wjCore.setCss(e.cell, { display: "table", tableLayout: "fixed", }); wjCore.setCss(e.cell.children[0], { display: "table-cell", textAlign: "center", verticalAlign: "middle", }); } } </script> <style> .wj-flexgrid { margin-bottom: 12px; } body { margin-bottom: 24px; } </style>
<template> <main class="container-fluid"> <wj-flex-grid :initialized="onInitialized"></wj-flex-grid> </main> </template> <script setup> import * as wjCore from "@mescius/wijmo"; import * as wjGrid from "@mescius/wijmo.grid"; import { ref } from "vue"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __()); }; })(); var CustomMergeManager = (function (_super) { __extends(CustomMergeManager, _super); function CustomMergeManager() { return _super.call(this) || this; } CustomMergeManager.prototype.getMergedRange = function (panel, r, c, clip) { if (clip === void 0) { clip = true; } var rng = new wjGrid.CellRange(r, c); for (var i = rng.col; i < panel.columns.length - 1; i++) { if ( panel.getCellData(rng.row, i, true) != panel.getCellData(rng.row, i + 1, true) ) break; rng.col2 = i + 1; } for (var i = rng.col; i > 0; i--) { if ( panel.getCellData(rng.row, i, true) != panel.getCellData(rng.row, i - 1, true) ) break; rng.col = i - 1; } for (var i = rng.row; i < panel.rows.length - 1; i++) { if ( panel.getCellData(i, rng.col, true) != panel.getCellData(i + 1, rng.col, true) ) break; rng.row2 = i + 1; } for (var i = rng.row; i > 0; i--) { if ( panel.getCellData(i, rng.col, true) != panel.getCellData(i - 1, rng.col, true) ) break; rng.row = i - 1; } return rng; }; return CustomMergeManager; })(wjGrid.MergeManager); function onInitialized(flexGrid) { while (flexGrid.columns.length < 7) { flexGrid.columns.push(new wjGrid.Column()); } while (flexGrid.rows.length < 5) { flexGrid.rows.push(new wjGrid.Row()); } // configure the grid flexGrid.mergeManager = new CustomMergeManager(); flexGrid.formatItem.addHandler(centerCell); flexGrid.rowHeaders.columns[0].width = 80; flexGrid.rows.defaultSize = 40; flexGrid.alternatingRowStep = 0; flexGrid.isReadOnly = true; // populate the grid setData(flexGrid.columnHeaders, 0, ",Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday".split(",")); setData(flexGrid.cells, 0, "12:00,Walker,Morning Show,Morning Show,Sport,Weather,N/A,N/A".split(",")); setData(flexGrid.cells, 1, "13:00,Today Show,Today Show,Sesame Street,Football,Market Watch,N/A,N/A".split(",")); setData(flexGrid.cells, 2, "14:00,Today Show,Today Show,Kid Zone,Football,Soap Opera,N/A,N/A".split(",")); setData(flexGrid.cells, 3, "15:00,News,News,News,News,News,N/A,N/A".split(",")); setData(flexGrid.cells, 4, "16:00,News,News,News,News,News,N/A,N/A".split(",")); } function setData(p, r, cells) { if (p.cellType == wjGrid.CellType.Cell) { p.grid.rowHeaders.setCellData(r, 0, cells[0]); } for (var i = 1; i < cells.length; i++) { p.setCellData(r, i - 1, cells[i]); } } function centerCell(s, e) { if (e.cell.children.length == 0) { e.cell.innerHTML = "<div>" + e.cell.innerHTML + "</div>"; wjCore.setCss(e.cell, { display: "table", tableLayout: "fixed", }); wjCore.setCss(e.cell.children[0], { display: "table-cell", textAlign: "center", verticalAlign: "middle", }); } } </script> <style> .wj-flexgrid { margin-bottom: 12px; } body { margin-bottom: 24px; } </style>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>MESCIUS Wijmo FlexGrid Custom Merging</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="compiler.js" type="module"></script> <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.js'); </script> </head> <body> <div id="app"> </div> </body> </html>
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' }, '*.vue': { loader: '../plugin-vue/index.js' } //'*.vue': { loader: 'systemjs-plugin-vue' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@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', "@mescius/wijmo.vue2.chart.analytics": "npm:@mescius/wijmo.vue2.chart.analytics/index.js", "@mescius/wijmo.vue2.chart.animation": "npm:@mescius/wijmo.vue2.chart.animation/index.js", "@mescius/wijmo.vue2.chart.annotation": "npm:@mescius/wijmo.vue2.chart.annotation/index.js", "@mescius/wijmo.vue2.chart.finance.analytics": "npm:@mescius/wijmo.vue2.chart.finance.analytics/index.js", "@mescius/wijmo.vue2.chart.finance": "npm:@mescius/wijmo.vue2.chart.finance/index.js", "@mescius/wijmo.vue2.chart.hierarchical": "npm:@mescius/wijmo.vue2.chart.hierarchical/index.js", "@mescius/wijmo.vue2.chart.interaction": "npm:@mescius/wijmo.vue2.chart.interaction/index.js", "@mescius/wijmo.vue2.chart.radar": "npm:@mescius/wijmo.vue2.chart.radar/index.js", '@mescius/wijmo.vue2.chart.map': 'npm:@mescius/wijmo.vue2.chart.map/index.js', "@mescius/wijmo.vue2.chart": "npm:@mescius/wijmo.vue2.chart/index.js", "@mescius/wijmo.vue2.core": "npm:@mescius/wijmo.vue2.core/index.js", "@mescius/wijmo.vue2.gauge": "npm:@mescius/wijmo.vue2.gauge/index.js", "@mescius/wijmo.vue2.grid.detail": "npm:@mescius/wijmo.vue2.grid.detail/index.js", "@mescius/wijmo.vue2.grid.filter": "npm:@mescius/wijmo.vue2.grid.filter/index.js", "@mescius/wijmo.vue2.grid.grouppanel": "npm:@mescius/wijmo.vue2.grid.grouppanel/index.js", '@mescius/wijmo.vue2.grid.search': 'npm:@mescius/wijmo.vue2.grid.search/index.js', "@mescius/wijmo.vue2.grid.multirow": "npm:@mescius/wijmo.vue2.grid.multirow/index.js", "@mescius/wijmo.vue2.grid.sheet": "npm:@mescius/wijmo.vue2.grid.sheet/index.js", '@mescius/wijmo.vue2.grid.transposed': 'npm:@mescius/wijmo.vue2.grid.transposed/index.js', '@mescius/wijmo.vue2.grid.transposedmultirow': 'npm:@mescius/wijmo.vue2.grid.transposedmultirow/index.js', "@mescius/wijmo.vue2.grid": "npm:@mescius/wijmo.vue2.grid/index.js", "@mescius/wijmo.vue2.input": "npm:@mescius/wijmo.vue2.input/index.js", "@mescius/wijmo.vue2.olap": "npm:@mescius/wijmo.vue2.olap/index.js", "@mescius/wijmo.vue2.viewer": "npm:@mescius/wijmo.vue2.viewer/index.js", "@mescius/wijmo.vue2.nav": "npm:@mescius/wijmo.vue2.nav/index.js", "@mescius/wijmo.vue2.base": "npm:@mescius/wijmo.vue2.base/index.js", '@mescius/wijmo.vue2.barcode.common': 'npm:@mescius/wijmo.vue2.barcode.common/index.js', '@mescius/wijmo.vue2.barcode.composite': 'npm:@mescius/wijmo.vue2.barcode.composite/index.js', '@mescius/wijmo.vue2.barcode.specialized': 'npm:@mescius/wijmo.vue2.barcode.specialized/index.js', 'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css', 'jszip': 'npm:jszip/dist/jszip.js', 'css': 'npm:systemjs-plugin-css/css.js', 'vue': 'npm:vue/dist/vue.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', '@vue/compiler-dom':'npm:@vue/compiler-dom/dist/compiler-dom.global.prod.js', '@vue/runtime-dom':'npm:@vue/runtime-dom/dist/runtime-dom.global.prod.js', '@vue/shared':'npm:@vue/shared/dist/shared.cjs.js', 'vue-loader': 'npm:systemjs-vue-browser/index.js', //'systemjs-plugin-vue': 'npm:systemjs-plugin-vue/index.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' }, rxjs: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, wijmo: { defaultExtension: 'js', } } }); })(this);