Cell Templates (Vue)

Wijmo interops for popular frameworks allow you to define custom content for MultiRow cells declaratively, by using each frameworks' own template markup in conjunction with Wijmo's MultiRowCellTemplate component.

Such templates may include arbitrary components and HTML elements, with property and event bindings. All types of grid cells can be defined using templates (data cells, header cells, editors, etc).

This sample shows a grid with the templates for all cell types. The templates can be dynamically enabled or disabled by toggling the checkboxes.

Learn about MultiRow | MultiRow API Reference

This example uses Vue.

<template> <div class="container-fluid"> <p> Use a <b>wj-multi-row-cell-template</b> element to define a cell template. The content of the <b>wj-multi-row-cell-template</b> element defines the cell content. The <b>cellType</b> property specifies the type of the cells represented by the template. Use a <b>v-slot</b> directive to define a variable that contains an object with cell specific data, including the data item (<b>item</b>), row (<b>row</b>) and column (<b>col</b>) that the cell represents. </p> <p> Note that column-specific templates should be defined as children of the corresponding <b>wj-multi-row-cell</b> component, while the others are defined under the <b>wj-multi-row</b> element. </p> <wj-multi-row ref="mr" :itemsSource="itemsSource" :multiRowGroupHeaders="true"> <wj-multi-row-cell-template cellType="TopLeft" v-if="customTopLeft"> № </wj-multi-row-cell-template> <wj-multi-row-cell-template cellType="RowHeader" v-if="customRowHeader" v-slot="cell"> {{cell.row.index / $refs.mr.control.rowsPerItem + 1}} </wj-multi-row-cell-template> <wj-multi-row-cell-template cellType="RowHeaderEdit" v-if="customRowHeaderEdit"> ... </wj-multi-row-cell-template> <wj-multi-row-cell-group header="Identity" > <wj-multi-row-cell binding='id' header="ID" > <wj-multi-row-cell-template cellType="ColumnHeader" v-if="customColumnHeader"> <i>ID</i> </wj-multi-row-cell-template> </wj-multi-row-cell> <wj-multi-row-cell binding='date' header="Date" :width="140"> <wj-multi-row-cell-template cellType="CellEdit" v-if="customCellEdit" v-slot="cell"> <wj-input-date class="cell-editor" v-model="cell.value"></wj-input-date> </wj-multi-row-cell-template> </wj-multi-row-cell> </wj-multi-row-cell-group> <wj-multi-row-cell-group header="Statistics" :colspan="2"> <wj-multi-row-cell header="Country" binding="country" :colspan="2"> <wj-multi-row-cell-template cellType="ColumnHeader" v-if="customColumnHeader"> <i>Country</i> </wj-multi-row-cell-template> <wj-multi-row-cell-template cellType="Cell" v-if="customCell" v-slot="cell"> <img :src="'resources/' + cell.item.country + '.png'" /> {{cell.item.country}} </wj-multi-row-cell-template> <wj-multi-row-cell-template cellType="CellEdit" v-if="customCellEdit" v-slot="cell"> <wj-combo-box :itemsSource="countries" class="cell-editor" :selectedValue.sync="cell.value" :isEditable="false"> </wj-combo-box> </wj-multi-row-cell-template> <wj-multi-row-cell-template cellType="GroupHeader" v-if="customGroupHeader" v-slot="cell"> <input type="checkbox" v-model="cell.row.isCollapsed" /> {{cell.item.name}} ({{cell.item.items.length}} items) </wj-multi-row-cell-template> </wj-multi-row-cell> <wj-multi-row-cell header="Downloads" binding="downloads" :width="170" aggregate="Sum"> <wj-multi-row-cell-template cellType="Cell" v-if="customCell" v-slot="cell"> <span :style="{color: highlightDownloads? (cell.item.downloads>10000 ?'green':'red'):''}" style="font-weight:700"> {{cell.item.downloads}} </span> </wj-multi-row-cell-template> <wj-multi-row-cell-template cellType="CellEdit" v-if="customCellEdit" v-slot="cell"> <wj-input-number class="cell-editor" v-model="cell.value" :step="1"></wj-input-number> </wj-multi-row-cell-template> <wj-multi-row-cell-template cellType="Group" v-if="customGroup" v-slot="cell"> Downloads: {{formatNumber(cell.value, 'N0')}} </wj-multi-row-cell-template> </wj-multi-row-cell> <wj-multi-row-cell header="Sales" binding="sales" :width="170" aggregate="Sum"> <wj-multi-row-cell-template cellType="Cell" v-if="customCell" v-slot="cell"> <span :style="{color: highlightDownloads? (cell.item.sales>3000 ?'green':'red'):''}" style="font-weight:700"> {{cell.item.sales}} </span> </wj-multi-row-cell-template> <wj-multi-row-cell-template cellType="CellEdit" v-if="customCellEdit" v-slot="cell"> <wj-input-number class="cell-editor" v-model="cell.value" :step="1"></wj-input-number> </wj-multi-row-cell-template> <wj-multi-row-cell-template cellType="Group" v-if="customGroup" v-slot="cell"> Sales: {{formatNumber(cell.value, 'N0')}} </wj-multi-row-cell-template> </wj-multi-row-cell> </wj-multi-row-cell-group> </wj-multi-row> <div class="checkbox-list"> <div class="checkbox-list-title">Cell level templates:</div> <div class="checkbox-cell"> <label class="checkbox"> <input type="checkbox" v-model="customCell" /> Cell </label> <label class="checkbox"> <input type="checkbox" v-model="customCellEdit" /> CellEdit </label> </div> <div class="checkbox-cell"> <label class="checkbox"> <input type="checkbox" v-model="customColumnHeader" /> ColumnHeader </label> </div> <div class="checkbox-cell"> <label class="checkbox"> <input type="checkbox" v-model="customGroupHeader" /> GroupHeader </label> <label class="checkbox"> <input type="checkbox" v-model="customGroup" /> Group </label> </div> <div class="checkbox-list-title">MultiRow level templates:</div> <div class="checkbox-cell"> <label class="checkbox"> <input type="checkbox" v-model="customTopLeft" /> TopLeft </label> </div> <div class="checkbox-cell"> <label class="checkbox"> <input type="checkbox" v-model="customRowHeader" /> RowHeader </label> <label class="checkbox"> <input type="checkbox" v-model="customRowHeaderEdit" /> RowHeaderEdit </label> </div> </div> </div> </template> <script> import "@mescius/wijmo.styles/wijmo.css"; import "bootstrap.css"; import Vue from "vue"; import * as wjcCore from "@mescius/wijmo"; import * as wjcGrid from "@mescius/wijmo.grid"; import "@mescius/wijmo.vue2.input"; import "@mescius/wijmo.vue2.grid.multirow"; import * as dataService from './data'; let App = Vue.extend({ name: "app", data: function () { return { itemsSource: dataService.getCv(dataService.getData()), countries: dataService.getCountries(), customTopLeft: true, customRowHeader: true, customRowHeaderEdit: true, customCell: true, customCellEdit: true, customGroupHeader: true, customColumnHeader: true, customGroup: true, highlightDownloads: true } }, methods: { initialized: function(grid, e) { grid.columnFooters.rows.push(new wjcGrid.GroupRow()); }, formatNumber: function(value, format) { return wjcCore.Globalize.formatNumber(value, format); } }, }); new Vue({ render: h => h(App) }).$mount("#app"); </script> <style> body { margin-bottom: 24px; } label { margin-right: 3px; } .checkbox-list { padding: 0 20px; } .checkbox-cell { display: table-cell; padding-right: 50px; } .checkbox-list .checkbox { margin: 10px 0 0 0; } .checkbox-list-title { font-size: 18px; margin: 10px 0px 2px -20px; } .wj-flexgrid { max-height: 350px; max-width: 600px; margin: 10px 0; } .wj-cell .cell-editor { position: absolute; left: 0px; width: 100%; border-radius: 0px; margin: -4px 0 -3px 0; } </style>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Cell 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.vue'); </script> </head> <body> <div id="app"> </div> </body> </html>
import { CollectionView } from '@mescius/wijmo'; export function getData() { var countries = getCountries(), data = []; for (var i = 0; i < 30; i++) { data.push({ id: i, date: new Date(2015, Math.floor(i / countries.length) % 12, (Math.floor(i / countries.length) + 1) % 28), country: countries[i % countries.length], countryMapped: i % countries.length, downloads: Math.round(Math.random() * 20000), sales: Math.round(Math.random() * 10000 * 100) / 100, expenses: Math.random() * 5000, checked: i % 9 == 0 }); } return data; } export function getCountries() { return 'US,Germany,UK,Japan,Italy,Greece'.split(','); } export function getCv() { return new CollectionView(getData(), { //sortDescriptions: ['date'], groupDescriptions: ['country'] }); }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, meta: { '*.css': { loader: 'css' }, '*.vue': { loader: 'vue-loader' } //'*.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.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.min.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);