Angular Data Grid Column Pinning

Column pinning

Freeze Angular Data Grid columns to the left or right edge so they stay visible while the rest of the grid scrolls horizontally.

On this page

Keep an identifier or an actions column in view while users scroll a wide grid sideways. Pinning freezes columns against the left or right edge with sticky positioning; everything else scrolls between them.

Column pinning

Freeze columns against the left or right edge with [columnPinning]="{ left, right }" — they stay put while the rest of the grid scrolls horizontally. Pass [columnPinning]="true" on its own to enable the feature and pin later through grid.table.setColumnPinning(...). When a column is pinned left and selection is on, the checkbox column travels with it. The last left and first right column cast a shadow over the scrolling content.

Pinning physically moves the column to its edge — the rendered order is always left-pinned, center, right-pinned.

1 Alice Smith [email protected] Poland
2 Bob Jones [email protected] Germany
3 Carol Brown [email protected] France
4 Dave Taylor [email protected] Spain
5 Eve Wilson [email protected] Italy
6 Frank Davies [email protected] Poland
7 Grace Evans [email protected] Germany
8 Heidi Thomas [email protected] France
9 Ivan Smith [email protected] Spain
10 Judy Jones [email protected] Italy
1–10 of 1000
ts
import { Component } from '@angular/core'
import { DataGridCellDirective, DataGridComponent } from '@coreui/angular-data-grid'
import type { DataGridColumn, DataGridItem } from '@coreui/angular-data-grid'

const firstNames = ['Alice', 'Bob', 'Carol', 'Dave', 'Eve', 'Frank', 'Grace', 'Heidi', 'Ivan', 'Judy']
const lastNames = ['Smith', 'Jones', 'Brown', 'Taylor', 'Wilson', 'Davies', 'Evans', 'Thomas']
const countries = ['Poland', 'Germany', 'France', 'Spain', 'Italy']

@Component({
  selector: 'docs-data-grid-pinning-example',
  imports: [DataGridCellDirective, DataGridComponent],
  template: `
    <c-data-grid
      [columns]="columns"
      [items]="items"
      [itemKey]="itemKey"
      [columnPinning]="{ left: ['id'], right: ['actions'] }"
      [rowSelection]="true"
      [pagination]="{ pageSize: 10 }"
    >
      <ng-template cDataGridCell="actions" let-item>
        <button type="button" class="btn btn-sm btn-outline-primary" (click)="edit(item)">Edit</button>
      </ng-template>
    </c-data-grid>
  `
})
export class DataGridPinningExample {
  readonly columns: DataGridColumn[] = [
    { key: 'id', label: '#', width: 80 },
    { key: 'firstName', label: 'First name', width: 160 },
    { key: 'lastName', label: 'Last name', width: 160 },
    { key: 'email', label: 'Email', width: 260 },
    { key: 'country', label: 'Country', width: 200 },
    {
 key: 'actions', label: '', sortable: false, width: 120
}
  ]
readonly items: DataGridItem[] = Array.from({ length: 1000 }, (_, i) => ({
    id: i + 1,
    firstName: firstNames[i % firstNames.length],
    lastName: lastNames[i % lastNames.length],
    email: `${firstNames[i % firstNames.length].toLowerCase()}${i}@example.com`,
    country: countries[i % countries.length]
  }))
readonly itemKey = (item: DataGridItem) => String(item.id)

  edit(item: DataGridItem) {
    alert(`Edit ${item.firstName} (#${item.id})`)
  }
}

Options

OptionTypeDefaultDescription
columnPinningboolean | { left?: string[], right?: string[] }falseFreezes columns (by key) to the left/right edge. true enables the feature with no initial pins.

Pinning emits the pinningChange output with the grid’s { columnPinning } state. Reordering via column ordering never crosses a pinning boundary.