ColumnSettings

ColumnSettings adds column selection, reordering, and hiding to an HTML table that has already been generated by the server or another component. Unlike DataGrid, the adapter does not build headers or rows and does not manage the table data.

Markup requirements

The table must contain a real <thead>. Managed columns receive unique data-col attributes:

<table id="trades">
  <thead>
    <tr>
      <th data-col="time">Time</th>
      <th data-col="symbol">Instrument</th>
      <th data-col="price">Price</th>
      <th data-col="volume">Volume</th>
      <th>Actions</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>10:15:02</td>
      <td>SBER</td>
      <td>312.45</td>
      <td>10</td>
      <td><button type="button">Open</button></td>
    </tr>
  </tbody>
</table>

A column without data-col is treated as fixed: the user cannot hide it or move it from its original position. On creation, the adapter marks the corresponding body cells with the same keys. Rows with a different number of cells, such as a “No data” row with colspan, remain unchanged.

Setup

The host application provides three parts:

  • the table with server-rendered markup;
  • a dialog to which the component adds toggles and move buttons;
  • a store with read() and write() methods.
import { ColumnSettings } from '@stocksharp/grids/column-settings';

const dialogElement = document.querySelector<HTMLElement>('#column-dialog')!;
const list = dialogElement.querySelector<HTMLElement>('#column-list')!;

const settings = new ColumnSettings({
  table: document.querySelector<HTMLTableElement>('#trades')!,
  dialog: {
    list,
    moveUpTitle: 'Move up',
    moveDownTitle: 'Move down',
    classes: {
      item: 'column-picker-item',
      toggle: 'column-picker-toggle',
      label: 'column-picker-label',
      move: 'column-picker-move',
      moveUpIcon: 'icon-arrow-up',
      moveDownIcon: 'icon-arrow-down',
    },
    open: () => { dialogElement.hidden = false; },
    close: () => { dialogElement.hidden = true; },
  },
  store: {
    read: () => {
      const value = localStorage.getItem('trades-columns');
      return value ? JSON.parse(value) : null;
    },
    write: visible => {
      if (visible === null)
        localStorage.removeItem('trades-columns');
      else
        localStorage.setItem('trades-columns', JSON.stringify(visible));
    },
  },
});

document.querySelector('#open-columns')!
  .addEventListener('click', () => settings.openPicker());

document.querySelector('#apply-columns')!
  .addEventListener('click', () => settings.applyPicked());

document.querySelector('#reset-columns')!
  .addEventListener('click', () => settings.resetToDefault());

The component populates only the list element. The title, confirm and reset buttons, animation, and opening and closing of the modal belong to the application, so handlers for applyPicked() and resetToDefault() must also be assigned by the application.

Storing the layout

ColumnLayoutStore.read() returns an array of visible keys in the required order, or null when the original layout applies. The constructor reads the value immediately and applies it before the first user interaction.

write(visibleKeys) receives only the visible managed columns. A null value means that the original order is selected and no column is hidden. This lets a URL or localStorage store remove an unnecessary entry instead of saving the complete default value.

Keys are normalized to lowercase inside the adapter. Unknown and duplicate keys are discarded when a layout is applied.

Methods

  • defaultKeys() returns the original order of managed columns;
  • apply(visibleKeys) immediately reorders and hides columns without saving the layout;
  • isDefault(visibleKeys) checks whether the layout matches the original;
  • openPicker() reads the current DOM, builds the list, and opens the dialog;
  • applyPicked() applies the current selection, saves it, and closes the dialog;
  • resetToDefault() restores all managed columns, invokes write(null), and closes the dialog.

Styling

ColumnSettings does not provide CSS and does not depend on a specific modal library or icon set. Through ColumnPickerClasses, the application defines classes for the row, checkbox, label, buttons, and two icons. moveUpTitle and moveDownTitle must be localized before they are passed to the component.

See also