Checkbox-based Selection (Vue)

Use FlexGrid's Selector class to add a checkbox-based scheme for row selection.

This selection scheme works great on mobile devices, which have no keyboards with shift and control keys which are normally used to create extended selections.

The Selector class works with flat and hierarchical views. When used with hierarchical views, users can toggle the selected state for entire groups at once.

The Selector class can be used on header columns as well as on regular scrollable/data columns.

Learn about FlexGrid | FlexGrid API Reference

This example uses Vue.

app.vue
index.html
data.js
Copy to CodeMine
<template> <div class="container-fluid"> <label> Grouped Data <input type="checkbox" :checked="grouped" @click="setGroups($event.target.checked)" /> </label> <label> Header Column <input type="checkbox" :checked="headers" @click="setHeaders($event.target.checked)" /> </label> <p> There are now <b>{{ selectedItems.length }}</b> items selected. </p> <wj-flex-grid :deferResizing="true" :showMarquee="true" :alternatingRowStep="0" :itemsSource="view" :initialized="initGrid"> <wj-flex-grid-column binding="id" header="ID" :isReadOnly="true" /> <wj-flex-grid-column binding="country" header="Country" /> <wj-flex-grid-column binding="product" header="Product" /> <wj-flex-grid-column binding="discount" header="Discount" format="p0" /> <wj-flex-grid-column binding="downloads" header="Downloads" /> <wj-flex-grid-column binding="sales" header="Sales" /> <wj-flex-grid-column binding="expenses" header="Expenses" /> </wj-flex-grid> </div> </template> <script setup> import { FlexGrid, HeadersVisibility } from "@mescius/wijmo.grid"; import { Selector } from "@mescius/wijmo.grid.selector"; import { CollectionView, PropertyGroupDescription } from "@mescius/wijmo"; import { getData } from "./data"; import { ref } from "vue"; const view = ref(new CollectionView(getData(30))); const grouped = ref(true); const headers = ref(true); const selectedItems = ref([]); let selector; const initGrid = (grid) => { setGroups(true); selector = new Selector(grid, { itemChecked: () => { selectedItems.value = grid.rows.filter(r => r.isSelected); }, }); }; const setGroups = (groupsOn) => { const groups = view.value.groupDescriptions; groups.clear(); if (groupsOn) { groups.push( new PropertyGroupDescription('country'), new PropertyGroupDescription('product') ); } grouped.value = groupsOn; }; const setHeaders = (headersOn) => { const theGrid = selector.column.grid; theGrid.headersVisibility = headersOn ? HeadersVisibility.All : HeadersVisibility.Column; selector.column = headersOn ? theGrid.rowHeaders.columns[0] : theGrid.columns[0]; headers.value = headersOn; }; </script> <style> /* fixed grid height */ .wj-flexgrid { height: 350px; } /* some extra cell padding */ .wj-flexgrid .wj-cell { padding: 8px; } /* some space after the labels */ label { margin-right: 4em; } </style>
<template> <div class="container-fluid"> <label> Grouped Data <input type="checkbox" :checked="grouped" @click="setGroups($event.target.checked)" /> </label> <label> Header Column <input type="checkbox" :checked="headers" @click="setHeaders($event.target.checked)" /> </label> <p> There are now <b>{{ selectedItems.length }}</b> items selected. </p> <wj-flex-grid :deferResizing="true" :showMarquee="true" :alternatingRowStep="0" :itemsSource="view" :initialized="initGrid"> <wj-flex-grid-column binding="id" header="ID" :isReadOnly="true" /> <wj-flex-grid-column binding="country" header="Country" /> <wj-flex-grid-column binding="product" header="Product" /> <wj-flex-grid-column binding="discount" header="Discount" format="p0" /> <wj-flex-grid-column binding="downloads" header="Downloads" /> <wj-flex-grid-column binding="sales" header="Sales" /> <wj-flex-grid-column binding="expenses" header="Expenses" /> </wj-flex-grid> </div> </template> <script setup> import { FlexGrid, HeadersVisibility } from "@mescius/wijmo.grid"; import { Selector } from "@mescius/wijmo.grid.selector"; import { CollectionView, PropertyGroupDescription } from "@mescius/wijmo"; import { getData } from "./data"; import { ref } from "vue"; const view = ref(new CollectionView(getData(30))); const grouped = ref(true); const headers = ref(true); const selectedItems = ref([]); let selector; const initGrid = (grid) => { setGroups(true); selector = new Selector(grid, { itemChecked: () => { selectedItems.value = grid.rows.filter(r => r.isSelected); }, }); }; const setGroups = (groupsOn) => { const groups = view.value.groupDescriptions; groups.clear(); if (groupsOn) { groups.push( new PropertyGroupDescription('country'), new PropertyGroupDescription('product') ); } grouped.value = groupsOn; }; const setHeaders = (headersOn) => { const theGrid = selector.column.grid; theGrid.headersVisibility = headersOn ? HeadersVisibility.All : HeadersVisibility.Column; selector.column = headersOn ? theGrid.rowHeaders.columns[0] : theGrid.columns[0]; headers.value = headersOn; }; </script> <style> /* fixed grid height */ .wj-flexgrid { height: 350px; } /* some extra cell padding */ .wj-flexgrid .wj-cell { padding: 8px; } /* some space after the labels */ label { margin-right: 4em; } </style>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>MESCIUS Wijmo FlexGrid Selector: Checkbox Selection</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>
export function getData(count) { var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(','), products = 'Widgets,Gadgets,Yahoos'.split(','), data = []; for (var i = 0; i < count; i++) { var item = { id: i, country: pickOne(countries), product: pickOne(products), discount: Math.random() * .3, downloads: Math.round(Math.random() * 200000), sales: Math.random() * 100000, expenses: Math.random() * 50000 }; data.push(item); } return data; } function pickOne(items) { return items[randBetween(0, items.length - 1)]; } function randBetween(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); }
(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);