Custom Editors

Although the FlexGrid control provides efficient, Excel-style editing by default, you may want to customize the editing experience by using custom editors.

This is easily done by assigning an instance of an editor control to the column's editor property. This sample demonstrates this using Wijmo's InputDate, InputTime, ComboBox, AutoComplete, MultiSelect, InputMask, InputColor and InputNumber controls.

Learn about FlexGrid | FlexGrid Documentation | FlexGrid API Reference

import 'bootstrap.css'; import '@mescius/wijmo.styles/wijmo.css'; import './styles.css'; import { FlexGrid, DataMap } from '@mescius/wijmo.grid'; import { InputDate, InputTime, InputNumber, InputColor, ComboBox, AutoComplete, InputMask, MultiSelect } from '@mescius/wijmo.input'; import { getData, getCountries, getProducts, getNames } from './data'; document.readyState === 'complete' ? init() : window.onload = init; function init() { // create a grid with custom editors new FlexGrid('#theGrid', { showMarquee: true, selectionMode: 'MultiRange', alternatingRowStep: 0, autoGenerateColumns: false, columns: [ { header: 'ID', binding: 'id', width: 80, isReadOnly: true }, { header: 'Date', binding: 'date', format: 'd', editor: new InputDate(document.createElement('div')) }, { header: 'Time', binding: 'time', format: 't', editor: new InputTime(document.createElement('div'), { isEditable: true, format: 't', step: 30 }) }, { header: 'Country', binding: 'country', editor: new ComboBox(document.createElement('div'), { itemsSource: getCountries() }) }, { header: 'Product', binding: 'productId', dataMap: new DataMap(getProducts(), 'id', 'name'), editor: new AutoComplete(document.createElement('div'), { itemsSource: getProducts(), selectedValuePath: 'id', displayMemberPath: 'name' }) }, { header: 'Names', binding: 'name', width: 250, editor: new MultiSelect(document.createElement('div'), { itemsSource: getNames(), showSelectAllCheckbox: true }) }, { header: 'Phone', binding: 'phone', editor: new InputMask(document.createElement('div'), { mask: '(000) 000-0000' }) }, { header: 'Color', binding: 'color', cellTemplate: '<span class="colorbox" style="background:${text};"></span> ${text}', editor: new InputColor(document.createElement('div')) }, { header: 'Amount', binding: 'amount', format: 'n2', editor: new InputNumber(document.createElement('div'), { format: 'n2', step: 10, min: 0, max: 10000 }) }, { header: 'Premium', binding: 'premium', cssClass: 'switch' } ], itemsSource: getData() }); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>MESCIUS Wijmo FlexGrid Custom Editors</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"> <div id="theGrid"></div> </div> </body> </html>
export function getData(cnt = 100) { var data = [], countries = getCountries(), products = getProducts(), dt = new Date(), names = getNames(), yr = dt.getFullYear(); for (var i = 0; i < cnt; i++) { data.push({ id: i, date: new Date(yr, i % 12, 25, i % 24, i % 60, i % 60), time: new Date(yr, i % 12, 25, i % 24, i % 60, i % 60), country: pickOne(countries), productId: pickOne(products).id, name: [pickOne(names), pickOne(names)], phone: "(" + generateNumber(100, 999) + ") " + generateNumber(100, 999) + "-" + generateNumber(1000, 9999), color: pickOne('Red,Green,Blue,Yellow,Pink,Orange,Gold'.split(',')), amount: Math.random() * 10000, discount: Math.random() / 4, premium: Math.random() > .8 }); } return data; } export function getCountries() { return 'US,Germany,UK,Japan,Italy,Greece'.split(','); } export function getProducts() { let p = 'Andy Capp\'s fries,Barcel,Brannigans,Bugles,Cape Cod Potato Chips,Cheese Flavoured Moments,' + 'Cheetos,Cheez Doodles,Cheez-It,Cheezies,CornNuts,David Sunflower Seeds,Doritos,Frazzles,Frito-Lay,' + 'Fritos,Golden Wonder,Hula Hoops,Kettle Foods,KP Nuts,Kurkure,Lay\'s Stax,McCoys Crisps,' + 'Monster Munch,Munchos,Nobby\'s Nuts,Phileas Fogg,Pirate\'s Booty,Pringles,Ringos,Ruffles,' + 'Salt\'n\' Shake,San Nicasio,Space Raiders,Sun Chips,Smith\'s Crisps,Tudor Crisps,Twiglets,' + 'Twisties,Tyrrells,Tyrrells Apple Chips,Walkers Crisps,Wheat Crunchies,Wise Foods,Wotsits'; return p.split(',').map((name, id) => { return { id: id, name: name }; }); } export function getNames() { return 'Aaron Smith,Paul Johnson,John Richards,Mark Bannon,Sue Wong'.split(','); } function pickOne(arr) { return arr[Math.floor(Math.random() * arr.length)]; } function generateNumber(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
body { margin-bottom: 24px; } .wj-flexgrid { height: 300px; margin-bottom: 12px; } .wj-flexgrid .wj-cell { padding: 6px 8px; } .colorbox { display: inline-block; width: 12px; height: 1.5em; margin: 0 3px 0 -3px; border: 1px solid black; vertical-align: bottom; } /* switch-style checkbox */ .wj-cell.switch input[type=checkbox] { opacity: 0; width: 100%; } .wj-cell.switch label { width: 3em; position: relative; } .wj-cell.switch input[type=checkbox]+span { pointer-events: none; background: rgba(0, 0, 0, 0.4); } .wj-cell.switch input[type=checkbox]:checked+span { background: #0085c7; /* rgb(27, 255, 27) */ } .wj-cell.switch:hover input[type=checkbox]+span:after { box-shadow: 0 3px 3px rgba(0, 0, 0, 0.4); transition: all 0.3s; } .wj-cell.switch input[type=checkbox]+span:before { content: ''; position: absolute; display: block; left: 0; top: .45em; width: 2.5em; height: .75em; border-radius: 1em; background: rgba(0, 0, 0, .4); opacity: .25; } .wj-cell.switch input[type=checkbox]:checked+span:before { background: inherit; } .wj-cell.switch input[type=checkbox]+span:after { content: ''; position: absolute; left: 0; top: 0.13em; width: 1.3em; height: 1.3em; background: white; border-radius: 1em; border: 1px solid rgba(0, 0, 0, .2); box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2); } .wj-cell.switch input[type=checkbox]:checked+span:after { left: 1.25em; transition: all 0.3s; background: inherit; }
(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);