Chapter 18 of 34

Fix columns on the left and right

ID stays on the left, Total on the right – 40 columns scroll in between.

After this chapter you can

  • fix columns in the model
  • know west, center and east
  • see horizontal virtual scrolling at work

Fixed columns belong to the model

Two numbers in TableFactory.createTableModel(): fixedLeftColumnCount and fixedRightColumnCount. The first n columns go to the west side, the last m to the east side – in header, body and footer.

Header, body and footer, each split into west (fixed left), center (scrolls) and east (fixed right) west (fixed) center (scrolls) east (fixed) header header-west header-center header-east body body-west body-center body-east footer footer-west footer-center footer-east fixedLeftColumnCount all other columns – virtual, horizontally and vertically fixedRightColumnCount scrolls
Every area asks its area model: getRowCount(), getValueAt(row, col), getRowHeight(row) …
src/model/order-wide-model.ts
function createWideOrdersModel(orders: Order[]): TableModelIf {
const columns = createOrderColumns();
const total = columns.find(c => c.property === "total")!;
const wideColumns: ColumnDefIf[] = [
...columns.filter(c => c !== total),
...MONTHS.map(m => new ColumnDef(m, m, px90, allRight)),
total // total is the last column
];
const tableModel = TableFactory.createTableModel({
rows: widenOrders(orders),
columnDefs: wideColumns,
fixedLeftColumnCount: 1, // ID stays on the left (west)
fixedRightColumnCount: 1, // Total stays on the right (east)
footerAreaModel: new OrderTotalsFooterModel(
() => tableModel.getBodyModel() as AreaModelObjectArray<Order>, wideColumns)
});
return tableModel;
}

The 30 month columns are generated – 40 columns in total:

// 40 columns: the orders plus 30 months of (made-up) follow-up revenue
const MONTHS = Array.from({ length: 30 }, (_, i) => new Date(Date.UTC(2024, i, 1)).toISOString().slice(0, 7));
type WideOrder = Order & Record<string, number | string>;
function widenOrders(orders: Order[]): WideOrder[] {
return orders.map(o => {
const wide: WideOrder = { ...o };
MONTHS.forEach((m, i) => wide[m] = Math.round(o.total * ((o.id * 7919 + i * 104_729) % 97) / 200));
return wide;
});
}
Live 40 columns, ID and Total fixed
Screenshot: 40 columns, ID and Total fixed Screenshot: 40 columns, ID and Total fixed
Scroll sideways: ID stays on the left, Total on the right – in the footer, too.

Horizontal virtual scrolling

Look at the DOM count in the toolbar: of 40 columns only the visible ones are rendered. The table virtualises in both directions – that's why a table with 400 columns is as fast as one with 10.

Next

Part 5 starts with the options: chapter 19 (TableOptions).

API used in this chapter