Data Grid Column Ordering & Visibility

Column ordering & visibility

Let users reorder Data Grid columns by drag-and-drop and hide or show columns through a column chooser.

On this page

Give users control over the layout: drag headers to reorder columns and toggle columns on and off to focus on what matters. Both features are driven through the headless table, so you can wire them into your own toolbar — as the column chooser in this demo does.

Column ordering & visibility

columnOrder: true makes headers draggable — drop one onto another to reorder (dragging never crosses a pinning boundary); pass an array for an initial order. columnVisibility: true enables hiding and showing columns through the headless table (column.toggleVisibility(), column.getIsVisible()); pass an object like { email: false } to start with a column hidden. Opt a column out with movable: false / hideable: false. For a ready-made chooser, enable the built-in toolbar (toolbar: { columns: true }); this demo instead builds one entirely with the toolbar slot to show the headless API.

html
<div id="dataGridOrderVisibility"></div>
js
const roles = ['admin', 'editor', 'viewer']

const items = Array.from({ length: 1000 }, (_, i) => ({
  id: i + 1,
  name: `User ${i + 1}`,
  email: `user${i + 1}@example.com`,
  role: roles[i % roles.length]
}))

new coreui.DataGrid(document.getElementById('dataGridOrderVisibility'), {
  columns: [
    {
      key: 'id', label: '#', width: 90, movable: false, hideable: false
    },
    { key: 'name', label: 'Name' },
    { key: 'email', label: 'Email', style: { width: '30%' } },
    { key: 'role', label: 'Role', width: 110 }
  ],
  items,
  itemKey: item => String(item.id),
  columnOrder: true,
  columnVisibility: true,
  pagination: { pageSize: 10 },
  slots: {
    toolbar({ table }) {
      const element = document.createElement('div')
      element.className = 'd-flex gap-3 mb-2'
      const inputs = []

      for (const column of table.getAllLeafColumns()) {
        if (!column.getCanHide()) {
          continue
        }

        const label = document.createElement('label')
        label.className = 'form-check form-check-inline m-0'
        const input = document.createElement('input')
        input.type = 'checkbox'
        input.className = 'form-check-input me-1'
        input.addEventListener('change', () => column.toggleVisibility(input.checked))
        label.append(input, column.id)
        element.append(label)
        inputs.push([column, input])
      }

      return {
        element,
        update() {
          for (const [column, input] of inputs) {
            input.checked = column.getIsVisible()
          }
        }
      }
    }
  }
})

Options

OptionTypeDefaultDescription
columnOrderboolean | string[]falseDrag-and-drop reordering; an array sets the initial order. Never crosses a pinning boundary.
columnVisibilityboolean | Record<string, boolean>falseEnables hiding/showing columns; an object sets the initial visibility.
movable (column)booleantrueSet false to exclude a column from reordering.
hideable (column)booleantrueSet false to prevent hiding a column.

Reordering emits orderChange.coreui.data-grid { columnOrder }; toggling visibility emits visibilityChange.coreui.data-grid { columnVisibility }. The column menu offers a keyboard-accessible Move left/right as an alternative to drag-and-drop.