Chapter 22 of 34

Select cells, rows and ranges – and copy them

One selection model per table: cells, rows, columns or ranges, with mouse and keyboard.

  • ⏱ 5 min
  • ▶ Video episode 022
  • git tag ep-022
  • needs @guiexpert/table@1.1.88

After this chapter you can

  • choose a selection type
  • react to selection changes
  • copy the selection to the clipboard

A selection model per table

What can be selected is decided by a SelectionModel. It takes a type (ExtendedSelectionType) and a mode (SelectionMode):

import { type ExtendedSelectionType, SelectionModel, TableOptions, type TableOptionsIf } from "@guiexpert/table";
function createOptions(type: ExtendedSelectionType): TableOptionsIf {
const selectionModel = new SelectionModel(type, "multi"); // "cell" | "row" | "column" | "range"
return { ...new TableOptions(), getSelectionModel: () => selectionModel };
}
TypeA click selects …
"cell"one cell
"row" / "column"the whole row / column
"range"a rectangle – drag with the mouse or Shift+click
"none"nothing

Mode "multi" adds more selections with ⌘/Ctrl+click; "single" replaces the selection.

Mouse and keyboard

  • Drag = range (since 1.1.88), Shift+click = range up to here, ⌘/Ctrl+click = another cell.
  • ⌘/Ctrl+C copies, ⌘/Ctrl+A selects all, arrow keys move the focus.
  • Shortcuts can be remapped or switched off (shortcutActionIdMapping, shortcutActionsDisabled in TableOptionsIf).

React to the selection

import { EventAdapter, type SelectionModelIf } from "@guiexpert/table";
class SelectionEvents extends EventAdapter {
constructor(private readonly show: (text: string) => void) {
super();
}
override onSelectionChanged(model: SelectionModelIf): void {
const ranges = model.getRanges().filter(r => !r.gammaRange); // skip special ranges
if (!ranges.length) return this.show("nothing selected");
const cells = ranges.reduce((n, r) => n + (r.r2 - r.r1 + 1) * (r.c2 - r.c1 + 1), 0);
this.show(`${cells} cells in ${ranges.length} range(s) · ⌘/Ctrl+C copies`);
}
}

EventListenerIf.onSelectionChanged() gets the model; SelectionModelIf.getRanges() returns the selected rectangles (r1, c1, r2, c2). Event listeners in general: chapter 23 (Events & context menu).

Copy

copyButton.addEventListener("click", async () => {
const text = await tableApi.copyToClipboard(); // tabs + newlines → Excel
info.textContent = `copied ${text.split("\n").length} lines`;
});

TableApi.copyToClipboard() resolves with the copied text – tab-separated, one line per row. Pasted into Excel, Numbers or Google Sheets it lands in cells.

Live Selection types
Screenshot: Selection types Screenshot: Selection types
Switch the type with the buttons. In “range” drag across cells, then press ⌘/Ctrl+C or “copy”.

Next

Clicks, double-clicks and a context menu of your own: chapter 23 (Events & context menu).

API used in this chapter