TablixJS provides comprehensive row selection functionality with support for both single and multi-row selection modes. This guide covers all aspects of implementing and customizing row selection in your tables.
- Basic Setup
- Selection Modes
- User Interactions
- Programmatic API
- Event System
- Integration with Other Features
- Styling and Theming
- Advanced Usage
- Best Practices
To enable row selection, add the selection configuration to your table options:
const table = new Table('#container', {
selection: {
enabled: false, // Default: selection is disabled
mode: 'single', // 'single' or 'multi'
dataIdKey: 'id' // Key to use as stable row identifier
}
});| Option | Type | Default | Description |
|---|---|---|---|
enabled |
Boolean | false |
Enable/disable row selection |
mode |
String | 'single' |
Selection mode: 'single' or 'multi' |
dataIdKey |
String | 'id' |
Data property to use as stable row identifier |
- Click: Select the clicked row (clears previous selection)
- Click: Select the clicked row (clears other selections)
- Ctrl+Click (Cmd+Click on Mac): Add/remove individual rows
- Shift+Click: Select range from last selected row to clicked row
Fired before a selection changes.
table.eventManager.on('beforeSelect', (event) => {
console.log('Before select:', event);
// event contains: { rowData, rowId, currentSelection, isCtrlClick, isShiftClick }
});Fired after a selection changes.
table.eventManager.on('afterSelect', (event) => {
console.log('After select:', event);
// event contains: { rowData, rowId, selectedRows, selectedData }
});Returns array of selected row data objects.
const selectedRows = table.getSelectedData();
console.log('Selected rows:', selectedRows);Returns array of selected row IDs.
const selectedIds = table.getSelectedIds();
console.log('Selected IDs:', selectedIds);Returns number of selected rows.
const count = table.getSelectionCount();
console.log(`${count} rows selected`);Checks if a specific row is selected.
if (table.isRowSelected('123')) {
console.log('Row 123 is selected');
}Programmatically select rows by ID(s).
// Select single row
table.selectRows('123');
// Select multiple rows
table.selectRows(['123', '456', '789']);Programmatically deselect rows by ID(s).
// Deselect single row
table.deselectRows('123');
// Deselect multiple rows
table.deselectRows(['123', '456']);Clear all selections.
table.clearSelection();Enable selection functionality.
table.enableSelection();Disable selection functionality.
table.disableSelection();Change selection mode.
table.setSelectionMode('multi'); // or 'single'- Selection is preserved for rows that remain visible
- Rows hidden by pagination keep their selection state
- Selection works across different pages
- Rows hidden by filters/search are automatically deselected
- Selection state is preserved for visible rows
- Filtering triggers
afterSelectevent if selection changes
- Selection is preserved using stable row IDs
- Visual selection updates after sorting
- No selection state is lost during sorting operations
Selection styles can be customized using CSS variables:
:root {
/* Regular selected row */
--tablix-row-selected-bg: #e3f2fd;
--tablix-row-selected-hover-bg: #bbdefb;
/* Last selected row (in multi-mode) */
--tablix-row-last-selected-bg: #abd5f8; /* will change */
--tablix-row-last-selected-color: #ffffff;
--tablix-row-last-selected-hover-bg: #9ec0e0; /* will change */
/* Selection indicator */
--tablix-selection-indicator-color: #9ec0e0; /* will change */
}const table = new Table('#container', {
data: users,
columns: columns,
selection: {
enabled: true,
mode: 'single'
}
});
table.eventManager.on('afterSelect', (event) => {
const selected = event.selectedData[0];
if (selected) {
console.log('Selected user:', selected.name);
}
});const table = new Table('#container', {
data: users,
columns: columns,
selection: {
enabled: true,
mode: 'multi',
dataIdKey: 'userId'
}
});
// Handle selection changes
table.eventManager.on('afterSelect', (event) => {
const count = event.selectedData.length;
document.getElementById('selectedCount').textContent =
`${count} users selected`;
});
// Programmatically select specific users
document.getElementById('selectAdmins').addEventListener('click', () => {
const adminIds = users
.filter(user => user.role === 'admin')
.map(user => user.userId);
table.selectRows(adminIds);
});// Toggle selection mode
function toggleSelectionMode() {
const currentMode = table.selectionManager.options.mode;
const newMode = currentMode === 'single' ? 'multi' : 'single';
table.setSelectionMode(newMode);
}
// Bulk operations
function deleteSelected() {
const selectedIds = table.getSelectedIds();
if (selectedIds.length === 0) {
alert('No rows selected');
return;
}
if (confirm(`Delete ${selectedIds.length} selected items?`)) {
// Perform delete operation
selectedIds.forEach(id => deleteUser(id));
// Refresh table data
table.loadData(updatedData);
}
}- Stable Row IDs: Always use a stable, unique identifier for
dataIdKey(like database IDs) - Event Handling: Use
afterSelectevent for UI updates and actions - User Feedback: Provide clear visual feedback for selection states
- Accessibility: Selection works with keyboard navigation (Enter/Space on rows)
- Performance: Selection state is efficiently managed using Sets for O(1) lookups
- Selection is based on data IDs, not row indexes
- Filtered-out rows are automatically deselected
- Server-side pagination requires careful handling of selection persistence
- Maximum selection size is limited by browser memory (typically thousands of rows)