Aller au contenu

Sélection et plages

Deux choses différentes : les lignes sont sélectionnées (un ensemble de lignes, pour une action sur elles), les cellules sont prises en bloc (un rectangle, pour copier, coller et recopier).

Le réglage selection l’active ; aucune fonction n’est requise.

import { createGrid } from '@dzgrid/dom';
import { idOfDataKey, type SelectionState } from '@dzgrid/core';
import { FR } from '@dzgrid/dom/locales/fr';
type Seed = { id: string; plant: string; packets: number };
const grid = createGrid<Seed>(document.getElementById('seeds')!, {
rows: [{ id: 's1', plant: 'Courge de lune', packets: 12 }, { id: 's2', plant: 'Haricot de verre', packets: 0 }],
columns: [{ id: 'plant', header: 'Plante' }, { id: 'packets', header: 'Sachets', type: 'number' }],
getRowId: (s) => s.id,
messages: FR,
selection: { mode: 'multi', checkbox: true, keepOnFilter: true },
onEvent: (e) => {
if (e.type === 'selectionChanged') console.log(describe(e.selection), e.count);
},
});
function describe(s: SelectionState): string {
const ids = [...s.keys].map(idOfDataKey);
return s.mode === 'include' ? `seulement ${ids.join(', ')}` : `toutes les lignes sauf ${ids.join(', ')}`;
}
grid.kernel.dispatch({ type: 'selection.all' }, 'api');

Un clic sélectionne une ligne, Ctrl/Cmd+clic ajoute ou retire, Maj+clic sélectionne une suite ; la case du titre sélectionne tout.

  • mode : none, single ou multi. checkbox: true ajoute une colonne de cases avec une case dans le titre ; click: true permet au clic de sélectionner ; sans lui, un clic ne fait que déplacer le focus (sélection par Espace ou par la case).
  • Avec click: true, un clic sélectionne une ligne, Ctrl/Cmd+clic bascule, Maj+clic sélectionne une suite dans l’ordre de l’écran ; Espace bascule la ligne qui a le focus, Ctrl+A sélectionne tout. La sélection survit au tri et au filtrage.
  • La sélection contient des clés de ligne, pas vos identifiants. idOfDataKey(key) rend l’identifiant ; en Angular, selectedIds(controller) rend les identifiants de toute la sélection avec la requête.
  • mode: 'exclude' veut dire « toutes les lignes que la requête trouve, sauf ces clés » : après « tout sélectionner » sur des lignes paginées ou venues d’un serveur, la grille ne peut pas les lister, votre serveur le peut en rejouant la requête.
  • canSelect(row, selection, context) rend false, ou la phrase à dire, pour refuser une ligne ; il demande la fonction rules() de @dzgrid/dom/rules (textes -rules), qui dit pourquoi à l’utilisateur.

Chaque clé du réglage selection est sur sa page : selection.

range() de @dzgrid/dom/range ajoute les blocs : Maj+flèches, un glisser, Ctrl+A. Ctrl+C copie le bloc en texte séparé par des tabulations, que lisent les tableurs (nombres dans la forme de la locale, débuts de formule protégés), Ctrl+X coupe, Ctrl+V colle dans les cellules modifiables, Suppr les vide. Coller et couper demandent l’édition. Textes -range, CSS range.css.

fill(blocks) de @dzgrid/dom/fill ajoute la poignée de recopie au coin du bloc : faites-la glisser pour recopier le bloc, ou pour continuer une série (1, 2, 3… ; les jours de jour en jour) ; Ctrl+D et Ctrl+R recopient vers le bas et vers la droite au clavier. Textes -fill, CSS fill.css. Une recopie ou un collage fait une seule demande d’enregistrement et une seule annulation.

import { createGrid, type GridMessages } from '@dzgrid/dom';
import { edit } from '@dzgrid/dom/edit';
import { editors } from '@dzgrid/dom/editors-base';
import { range } from '@dzgrid/dom/range';
import { fill } from '@dzgrid/dom/fill';
import { FR } from '@dzgrid/dom/locales/fr';
import { FR_EDIT } from '@dzgrid/dom/locales/fr-edit';
import { FR_EDITORS } from '@dzgrid/dom/locales/fr-editors';
import { FR_RANGE } from '@dzgrid/dom/locales/fr-range';
import { FR_FILL } from '@dzgrid/dom/locales/fr-fill';
import '@dzgrid/theme/edit.css';
import '@dzgrid/theme/range.css';
import '@dzgrid/theme/fill.css';
type Shelf = { id: string; aisle: string; jars: number };
const blocks = range();
const handle = fill(blocks);
const messages: GridMessages = {
...FR,
text: { ...FR.text, ...FR_EDIT.text, ...FR_EDITORS.text, ...FR_RANGE.text, ...FR_FILL.text },
};
const grid = createGrid<Shelf>(document.getElementById('pantry')!, {
rows: [{ id: 'a1', aisle: 'Confitures', jars: 14 }, { id: 'a2', aisle: 'Miel', jars: 9 }],
columns: [
{ id: 'aisle', header: 'Rayon' },
{ id: 'jars', header: 'Bocaux', type: 'number', editable: true },
],
getRowId: (s) => s.id,
messages,
features: [edit<Shelf>(), editors(), blocks, handle],
onEvent: (e) => {
if (e.type === 'rangeCopied') console.log(`${e.cells} cellules copiées`);
},
});
const copied = blocks.api(grid)?.copy({ headers: true }); // le bloc en texte, comme le ferait Ctrl+C
console.log(copied);

Maj+flèches prennent un bloc ; faites glisser la poignée de son coin vers le bas dans Étagère ou Vérifié le pour continuer la série ; clic droit pour le menu.

Le menu du clic droit (contextMenu({ use: { range: blocks, fill: handle } }) de @dzgrid/dom/context-menu) offre les mêmes actions à la souris.