NuGrid emits events for various user interactions, allowing you to respond to clicks, edits, navigation, and state changes.
| Event | Payload | Description |
|---|---|---|
cell-clicked | NuGridCellClickEvent | Cell was clicked |
cell-double-clicked | NuGridCellClickEvent | Cell was double-clicked |
row-clicked | NuGridRowClickEvent | Row was clicked |
row-double-clicked | NuGridRowClickEvent | Row was double-clicked |
| Event | Payload | Description |
|---|---|---|
focused-cell-changed | NuGridFocusedCellChangedEvent | Focused cell changed |
focused-row-changed | NuGridFocusedRowChangedEvent | Focused row changed |
| Event | Payload | Description |
|---|---|---|
cell-editing-started | NuGridCellEditingStartedEvent | Cell editing began |
cell-editing-cancelled | NuGridCellEditingCancelledEvent | Cell editing was cancelled |
cell-value-changed | NuGridCellValueChangedEvent | Cell value was saved |
| Event | Payload | Description |
|---|---|---|
sort-changed | NuGridSortChangedEvent | Sorting changed |
filter-changed | NuGridFilterChangedEvent | Filters changed |
row-selection-changed | Record<string, boolean> | Selection changed |
| Event | Payload | Description |
|---|---|---|
row-add-requested | Row data | New row submitted |
row-dragged | Drag event | Row was reordered |
<script setup lang="ts">
import type { NuGridCellClickEvent } from '#nu-grid/types'
function onCellClicked(event: NuGridCellClickEvent<User>) {
console.log('Cell clicked:', {
row: event.row.original,
column: event.column.id,
value: event.value,
})
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
@cell-clicked="onCellClicked"
/>
</template>
<script setup lang="ts">
function onCellDoubleClicked(event) {
// Navigate to detail page on double-click
navigateTo(`/users/${event.row.original.id}`)
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
@cell-double-clicked="onCellDoubleClicked"
/>
</template>
<script setup lang="ts">
function onRowClicked(event) {
// Select row on click
selectedUserId.value = event.row.original.id
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
@row-clicked="onRowClicked"
/>
</template>
<script setup lang="ts">
import type { NuGridFocusedCellChangedEvent } from '#nu-grid/types'
function onFocusedCellChanged(event: NuGridFocusedCellChangedEvent<User>) {
console.log('Focus moved:', {
from: `${event.previousRowIndex}:${event.previousColumnIndex}`,
to: `${event.rowIndex}:${event.columnIndex}`,
rowId: event.rowId,
columnId: event.columnId,
})
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
:focus="{ mode: 'cell' }"
@focused-cell-changed="onFocusedCellChanged"
/>
</template>
<script setup lang="ts">
function onFocusedRowChanged(event) {
// Load details for focused row
loadUserDetails(event.rowId)
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
:focus="{ mode: 'row' }"
@focused-row-changed="onFocusedRowChanged"
/>
</template>
<script setup lang="ts">
function onCellEditingStarted(event) {
console.log('Started editing:', event.column.id, 'value:', event.value)
// Prevent editing for locked rows
if (event.row.original.locked) {
return false // Cancels the edit
}
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
:editing="{ enabled: true }"
@cell-editing-started="onCellEditingStarted"
/>
</template>
<script setup lang="ts">
async function onCellValueChanged(event) {
console.log('Value changed:', {
column: event.column.id,
oldValue: event.oldValue,
newValue: event.newValue,
})
// Persist to server
try {
await api.updateUser(event.row.original.id, {
[event.column.id]: event.newValue,
})
toast.add({ title: 'Saved', color: 'success' })
} catch (error) {
toast.add({ title: 'Failed to save', color: 'error' })
// Optionally revert
event.row.original[event.column.id] = event.oldValue
}
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
:editing="{ enabled: true }"
@cell-value-changed="onCellValueChanged"
/>
</template>
<script setup lang="ts">
function onCellEditingCancelled(event) {
console.log('Editing cancelled:', event.column.id)
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
:editing="{ enabled: true }"
@cell-editing-cancelled="onCellEditingCancelled"
/>
</template>
<script setup lang="ts">
function onSortChanged(event) {
console.log('Sorting:', event.sorting)
// [{ id: 'name', desc: false }, ...]
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
@sort-changed="onSortChanged"
/>
</template>
<script setup lang="ts">
function onFilterChanged(event) {
console.log('Filters:', event.columnFilters)
// [{ id: 'status', value: 'active' }, ...]
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
@filter-changed="onFilterChanged"
/>
</template>
<script setup lang="ts">
function onRowSelectionChanged(selection: Record<string, boolean>) {
const selectedIds = Object.entries(selection)
.filter(([, selected]) => selected)
.map(([id]) => id)
console.log('Selected:', selectedIds)
}
</script>
<template>
<NuGrid
:data="data"
:columns="columns"
selection="multi"
@row-selection-changed="onRowSelectionChanged"
/>
</template>
<script setup lang="ts">
interface LogEntry {
id: number
event: string
time: string
payload: string
}
const log = ref<LogEntry[]>([])
let counter = 0
function logEvent(name: string, payload: any) {
log.value.unshift({
id: ++counter,
event: name,
time: new Date().toLocaleTimeString(),
payload: JSON.stringify(payload, null, 2),
})
if (log.value.length > 50) {
log.value.pop()
}
}
</script>
<template>
<div class="flex gap-4">
<NuGrid
:data="data"
:columns="columns"
:editing="{ enabled: true }"
:focus="{ mode: 'cell' }"
selection="multi"
class="flex-1"
@cell-clicked="e => logEvent('cell-clicked', { row: e.row.id, col: e.column.id })"
@cell-double-clicked="e => logEvent('cell-double-clicked', { row: e.row.id, col: e.column.id })"
@focused-cell-changed="e => logEvent('focused-cell-changed', { row: e.rowIndex, col: e.columnIndex })"
@cell-editing-started="e => logEvent('cell-editing-started', { col: e.column.id })"
@cell-value-changed="e => logEvent('cell-value-changed', { old: e.oldValue, new: e.newValue })"
@sort-changed="e => logEvent('sort-changed', e.sorting)"
@row-selection-changed="e => logEvent('row-selection-changed', Object.keys(e).length)"
/>
<div class="w-80 rounded-lg border p-4">
<h3 class="mb-2 font-semibold">Event Log</h3>
<div class="max-h-96 space-y-2 overflow-auto text-xs">
<div v-for="entry in log" :key="entry.id" class="rounded bg-gray-50 p-2 dark:bg-gray-800">
<div class="flex justify-between">
<span class="font-medium text-primary">{{ entry.event }}</span>
<span class="text-gray-400">{{ entry.time }}</span>
</div>
<pre class="mt-1 text-gray-600 dark:text-gray-400">{{ entry.payload }}</pre>
</div>
</div>
</div>
</div>
</template>