Skip to content

Column Selection

Enable spreadsheet-style selection for complete visible columns. Header labels select columns, while the dedicated sort and filter affordances keep their normal behavior.

Source code
TypeScriptts
import { defineCustomElements } from '@revolist/revogrid/loader';
defineCustomElements();

import { currentTheme, useRandomData } from '../composables/useRandomData';
import {
  ColumnSelectionPlugin,
  ColumnStretchPlugin,
  RowOddPlugin,
} from '@revolist/revogrid-pro';

const { createRandomData } = useRandomData();
const { isDark } = currentTheme();

export function load(parentSelector: string) {
  const parent = document.querySelector(parentSelector);
  if (!parent) return;

  const grid = document.createElement('revo-grid');
  grid.source = createRandomData(100);
  grid.columns = [
    { name: '#', prop: 'id', size: 50 },
    { name: '🍎 Fruit', prop: 'name', sortable: true, order: 'asc' },
    { name: '💰 Price', prop: 'price', sortable: true },
  ];
  grid.plugins = [ColumnSelectionPlugin, ColumnStretchPlugin, RowOddPlugin];
  grid.stretch = 'all';

  grid.theme = isDark() ? 'darkMaterial' : 'material';
  grid.hideAttribution = true;
  grid.range = true;
  grid.resize = true;
  grid.style.minHeight = '320px';

  parent.appendChild(grid);
}
Vuevue
<template>
  <RevoGrid
    :theme="isDark ? 'darkMaterial' : 'material'"
    :columns="columns"
    :source="source"
    :plugins="plugins"
    stretch="all"
    hide-attribution
    range
    resize
    style="min-height: 320px;"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import RevoGrid, { type ColumnRegular } from '@revolist/vue3-datagrid';
import {
  ColumnSelectionPlugin,
  ColumnStretchPlugin,
  RowOddPlugin,
} from '@revolist/revogrid-pro';
import { currentThemeVue, useRandomData } from '../composables/useRandomData';

const { createRandomData } = useRandomData();
const { isDark } = currentThemeVue();

const source = ref(createRandomData(100));
const columns = ref<ColumnRegular[]>([
  { name: '#', prop: 'id', size: 50 },
  { name: '🍎 Fruit', prop: 'name', sortable: true, order: 'asc' },
  { name: '💰 Price', prop: 'price', sortable: true },
]);

const plugins = [ColumnSelectionPlugin, ColumnStretchPlugin, RowOddPlugin];
</script>
Reacttsx
// src/components/column-selection/ColumnSelection.tsx

import { useState, useMemo } from 'react';
import { RevoGrid, type ColumnRegular, type DataType } from '@revolist/react-datagrid';
import {
  ColumnSelectionPlugin,
  ColumnStretchPlugin,
  RowOddPlugin,
} from '@revolist/revogrid-pro';

import { useRandomData, currentTheme } from '../composables/useRandomData';

const { isDark } = currentTheme();
const { createRandomData } = useRandomData();

function ColumnSelection() {
  const [source] = useState<DataType[]>(createRandomData(100));

  const columns = useMemo<ColumnRegular[]>(
    () => [
      { name: '#', prop: 'id', size: 50 },
      { name: '🍎 Fruit', prop: 'name', sortable: true, order: 'asc' },
      { name: '💰 Price', prop: 'price', sortable: true },
    ],
    [],
  );

  return (
    <div>
      <RevoGrid
        columns={columns}
        source={source}
        range
        stretch="all"
        hide-attribution
        theme={isDark() ? 'darkMaterial' : 'material'}
        plugins={[ColumnSelectionPlugin, ColumnStretchPlugin, RowOddPlugin]}
        resize
        style={{ minHeight: '320px' }}
      />
    </div>
  );
}

export default ColumnSelection;
Angularts
import { Component } from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import {
  ColumnSelectionPlugin,
  ColumnStretchPlugin,
  RowOddPlugin,
} from '@revolist/revogrid-pro';
import { currentTheme, useRandomData } from '../composables/useRandomData';

const { createRandomData } = useRandomData();
const { isDark } = currentTheme();

@Component({
  selector: 'column-selection-grid',
  standalone: true,
  imports: [RevoGrid],
  template: `
    <revo-grid
      [source]="source"
      [columns]="columns"
      [plugins]="plugins"
      stretch="all"
      [theme]="theme"
      [hideAttribution]="true"
      range
      resize
      style="min-height: 320px;"
    ></revo-grid>
  `,
})
export class ColumnSelectionGridComponent {
  source = createRandomData(100);
  theme = isDark() ? 'darkMaterial' : 'material';
  plugins = [ColumnSelectionPlugin, ColumnStretchPlugin, RowOddPlugin];

  columns = [
    { name: '#', prop: 'id', size: 50 },
    { name: '🍎 Fruit', prop: 'name', sortable: true, order: 'asc' },
    { name: '💰 Price', prop: 'price', sortable: true },
  ];
}
GestureResult
Click a headerReplace the selection with that column
Shift-clickSelect the contiguous span from the anchor column
Ctrl/Cmd-clickToggle a disjoint column
Ctrl/Cmd+Shift-clickAdd an anchored column span
Drag across headersSelect the dragged contiguous span
Ctrl/Cmd-dragAdd the dragged span
Ctrl+SpaceSelect the focused cell’s entire column
Ctrl+Shift+SpaceExtend from the column anchor to the focused column
Click a sort iconSort without changing the column selection

The plugin reuses RevoGrid’s multi-range selection engine, so copying, clearing, and editing disjoint selected columns follow the same rules as ordinary multi-range selections. Selections follow column prop values through sorting and reordering and update to the current visible row extent after source or filter changes.

beforecolumnselection is cancelable. Its detail describes the gesture source, selection mode, target column, resulting column props, anchor, and original pointer or keyboard event. Canceling it leaves the normal header action, such as sorting a sortable column, available.

Use the plugin instance to read selected column props in visual order:

const plugin = (await grid.getPlugins())
.find(plugin => plugin instanceof ColumnSelectionPlugin);
const selectedColumns = plugin?.getSelectedColumns();