The type of objects in the array. Each object represents a row in the table.
Creates an instance of AreaModelObjectArray.
Identifies which area of the table this model represents ('header', 'body', or 'footer')
The array of objects that represent the rows in this area
The default height for rows in this area (in pixels)
Optional columnDefs: ColumnDefIf[] = []Definitions for the columns in this area
Optional selectedRowClass: string = 'ge-selected-row'CSS class to apply to selected rows
Optional focusedRowClass: string = 'ge-focused-row'CSS class to apply to the focused row
const rows = [
{ id: 1, name: 'John', age: 30 },
{ id: 2, name: 'Jane', age: 25 }
];
const columnDefs: ColumnDefIf[] = [
new ColumnDef('id', 'ID', new Size(50, 'px')),
new ColumnDef('name', 'Name', new Size(150, 'px')),
new ColumnDef('age', 'Age', new Size(100, 'px'))
];
const bodyAreaModel = new AreaModelObjectArray(
'body',
rows,
30,
columnDefs
);
The index of the currently focused row. This is used to apply the focused row styling.
0
Identifies which area of the table this model represents ('header', 'body', or 'footer')
Protected cellProtected columnDefinitions for the columns in this area
The default height for rows in this area (in pixels)
Protected filteredA copy of the rows array that can be filtered and sorted without affecting the original data. This array is used for rendering the table and is updated when filtering or sorting is applied.
CSS class to apply to the focused row
Protected Readonly propertiesAn array of property names extracted from the column definitions. These properties are used to access values from the row objects.
A model and controller for row checkbox selection. This property allows the area to support row selection via checkboxes.
// Creating a checkbox model for row selection
import { CheckboxModel } from "@guiexpert/table";
const bodyModel = new AreaModel();
bodyModel.areaIdent = "body";
bodyModel.rowSelectionModel = new CheckboxModel();
// Later, check if a row is selected
const isSelected = bodyModel.isRowChecked(5);
Protected rowsThe array of objects that represent the rows in this area
CSS class to apply to selected rows
Protected yProtected arrayChanges the order of columns by moving a column from one position to another. This method updates both the properties array and calls the parent class implementation.
The index of the column to move
The index where the column should be moved to
// Move the second column (index 1) to the fourth position (index 3)
bodyAreaModel.changeColumnOrder(1, 3);
// Move the last column to the first position
const lastIndex = tableModel.getColumnCount() - 1;
bodyAreaModel.changeColumnOrder(lastIndex, 0);
Sorts the filtered rows based on the provided sort items. This method supports sorting by multiple columns with different sort directions.
An array of sort items, each containing a column index and sort state
Always returns true to indicate sorting was performed
// Sort by age in ascending order
bodyAreaModel.doSort([{ columnIndex: 2, sortState: 'asc' }]);
// Sort by name in descending order, then by age in ascending order
bodyAreaModel.doSort([
{ columnIndex: 1, sortState: 'desc' },
{ columnIndex: 2, sortState: 'asc' }
]);
// Clear sorting
bodyAreaModel.doSort([new SortItem(0, '')]);
Applies an external filter function to the rows array. This method updates the filtered rows array without modifying the original rows array.
A function that returns true for rows to keep and false for rows to filter out
// Filter rows where age is greater than 30
bodyAreaModel.externalFilterChanged(row => row.age > 30);
// Filter rows based on a search term
const searchTerm = 'john';
bodyAreaModel.externalFilterChanged(row =>
row.name.toLowerCase().includes(searchTerm.toLowerCase())
);
// Clear all filters
bodyAreaModel.externalFilterChanged(() => true);
Filters both the original rows and filtered rows arrays using the provided predicate function.
Unlike externalFilterChanged, this method permanently modifies the original rows array.
A function that returns true for rows to keep and false for rows to filter out
// Remove all rows where age is less than 30
bodyAreaModel.filterRowsByPredict(row => row.age >= 30);
Searches through all rows to find a row that matches the given criteria based on the predicate function. This method searches within the original rows array, including rows that may have been filtered out.
A partial object containing the search criteria
A function that takes the search criteria and a row, and returns true if the row matches the criteria
The first matching row from all rows, or undefined if no match is found
// Find a user by ID in all rows
const criteria = { id: 42 };
const user = bodyAreaModel.findRowFromAllRowsByAllCriteria(
criteria,
(criteria, row) => row.id === criteria.id
);
// Find a user with a specific property value in all rows
const criteria = { department: 'Engineering', role: 'Manager' };
const user = bodyAreaModel.findRowFromAllRowsByAllCriteria(
criteria,
(criteria, row) => row.department === criteria.department && row.role === criteria.role
);
Returns the first row from the filtered rows that matches the given criteria based on the provided predicate function. This method only searches within the filtered rows, not the original rows array.
A partial object containing the search criteria
A function that takes the search criteria and a row, and returns true if the row matches the criteria
The first matching row, or undefined if no match is found
// Find a user by name in the filtered rows
const criteria = { name: 'John' };
const user = bodyAreaModel.findRowFromFilteredRowsByAllCriteria(
criteria,
(criteria, row) => row.name === criteria.name
);
// Find a user by age range in the filtered rows
const criteria = { minAge: 25, maxAge: 35 };
const user = bodyAreaModel.findRowFromFilteredRowsByAllCriteria(
criteria,
(criteria, row) => row.age >= criteria.minAge && row.age <= criteria.maxAge
);
Protected genericCreates a comparator function for sorting rows based on a property and sort direction. This method supports custom sort comparators defined in column definitions.
The property to sort by
The sort direction factor: 1 for ascending, -1 for descending, 0 for no sorting
A comparator function that compares two rows
Creates a comparator function for sorting rows based on a property and sort direction. This method supports custom sort comparators defined in column definitions.
A comparator function that compares two rows
// inside a subclass: a comparator for sorting by name in ascending order
const comparator = this.genericFlatTableSortComparator('name', 1);
// Sort the rows using the comparator
const sortedRows = [...this.getFilteredRows()].sort(comparator);
// inside a subclass: a comparator for sorting by name in ascending order
const comparator = this.genericFlatTableSortComparator('name', 1);
// Sort the rows using the comparator
const sortedRows = [...this.getFilteredRows()].sort(comparator);
Returns the original, unfiltered array of rows. This can be useful when you need to access all data regardless of any applied filters.
The original array of row objects
// Get all rows, including those filtered out
const allRows = bodyAreaModel.getAllRows();
// Calculate average age across all rows
const totalAge = allRows.reduce((sum, row) => sum + row.age, 0);
const averageAge = totalAge / allRows.length;
Returns a cell renderer for the cell at the specified row and column indices. A cell renderer is responsible for rendering the cell content in a custom way. If undefined is returned, the cell value will be rendered directly.
The index of the row
The index of the column
A cell renderer instance, or undefined for default rendering
// Get a custom renderer for a cell
const renderer = bodyAreaModel.getCellRenderer(1, 2);
// Implementation example using column definitions
getCellRenderer(rowIndex: number, columnIndex: number): CellRendererIf | undefined {
// Get renderer from column definition
const columnDef = this.columnDefs[columnIndex];
return columnDef?.rendererMap?.[this.areaIdent];
}
Returns the column span value for the cell at the specified row and column indices. A colspan value of N means the cell spans N columns horizontally. Values less than 2 are ignored (no spanning).
The index of the row
The index of the column
The colspan value (number of columns the cell spans)
// Check if a cell spans multiple columns
const colspan = headerAreaModel.getColspanAt(0, 0);
if (colspan > 1) {
console.log(`This header cell spans ${colspan} columns`);
}
// Implementation example for a model with column spanning
getColspanAt(rowIndex: number, columnIndex: number): number {
// Special case: first row, first column spans 3 columns
if (rowIndex === 0 && columnIndex === 0) return 3;
// No spanning for other cells
return 1;
}
Gets the custom CSS classes that should be applied to a cell. This method extends the parent class implementation to add selection and focus classes.
The index of the row
The index of the column (unused in this implementation)
An array of CSS class names to apply to the cell
// Get the CSS classes for a cell
const classes = bodyAreaModel.getCustomClassesAt(1, 2);
console.log('CSS classes:', classes);
// Apply the classes to a cell element
const cellElement = document.createElement('div');
const classes = bodyAreaModel.getCustomClassesAt(rowIndex, columnIndex);
cellElement.classList.add(...classes);
Returns an object containing CSS style properties to apply to the cell at the specified row and column indices. This method allows for inline styling of individual cells.
The index of the row
The index of the column
An object with CSS style properties, or undefined if no custom styles
// Apply custom styles to cells
const styles = bodyAreaModel.getCustomStyleAt(1, 2);
console.log('Cell styles:', styles);
// Implementation example with conditional styling
getCustomStyleAt(rowIndex: number, columnIndex: number): { [key: string]: string } | undefined {
// Apply background color based on value
const value = this.getValueAt(rowIndex, columnIndex);
if (typeof value === 'number') {
// Color gradient based on value
if (value < 0) {
return { 'background-color': `rgba(255, 0, 0, ${Math.min(Math.abs(value) / 100, 0.5)})` };
} else if (value > 0) {
return { 'background-color': `rgba(0, 255, 0, ${Math.min(value / 100, 0.5)})` };
}
}
return undefined; // No custom styles
}
Retrieves the filtered and sorted rows from the dataset.
These rows are used for rendering the table.
Unlike getAllRows(), this method returns only the rows that match any applied filters.
An array containing the filtered (and sorted) rows
// Get all filtered rows
const filteredRows = bodyAreaModel.getFilteredRows();
// Count rows that match a certain condition
const adultsCount = filteredRows.filter(row => row.age >= 18).length;
Returns the maximum colspan value that can occur in this area model. This value is used to optimize rendering performance.
The maximum possible colspan value in this area
// Get the maximum colspan for optimization
const maxColspan = headerAreaModel.getMaxColspan();
// Implementation example
getMaxColspan(): number {
// If the model has no colspans, return 0 for optimization
return 0;
// If the model has colspans, return the maximum possible value
// return 3; // If some cells span up to 3 columns
}
Returns the maximum rowspan value that can occur in this area model. This value is used to optimize rendering performance.
The maximum possible rowspan value in this area
// Get the maximum rowspan for optimization
const maxRowspan = bodyAreaModel.getMaxRowspan();
// Implementation example
getMaxRowspan(): number {
// If the model has no rowspans, return 0 for optimization
return 0;
// If the model has rowspans, return the maximum possible value
// return 2; // If some cells span up to 2 rows
}
Returns the row object at the specified index from the filtered rows array. This method overrides the parent class implementation.
The index of the row to retrieve
The row object at the specified index, or undefined if the index is out of bounds
// Get the first row object
const row = bodyAreaModel.getRowByIndex(0);
console.log('First row:', row);
// Iterate through all rows
for (let i = 0; i < bodyAreaModel.getRowCount(); i++) {
const row = bodyAreaModel.getRowByIndex(i);
console.log(`Row ${i}:`, row);
}
Returns the number of rows in the filtered rows array. This is used to determine how many rows should be rendered in the table.
The number of rows in the filtered rows array
const rowCount = bodyAreaModel.getRowCount();
console.log(`The table has ${rowCount} rows`);
Returns the height of the row at the specified index. This implementation always returns the default row height. Override this method in subclasses to support variable row heights.
The index of the row (unused in this implementation)
The height of the row in pixels
const rowHeight = bodyAreaModel.getRowHeight(0);
console.log(`The first row has a height of ${rowHeight}px`);
Returns the row span value for the cell at the specified row and column indices. A rowspan value of N means the cell spans N rows vertically. Values less than 2 are ignored (no spanning).
The index of the row
The index of the column
The rowspan value (number of rows the cell spans)
// Check if a cell spans multiple rows
const rowspan = bodyAreaModel.getRowspanAt(0, 0);
if (rowspan > 1) {
console.log(`This cell spans ${rowspan} rows`);
}
// Implementation example for a model with row spanning
getRowspanAt(rowIndex: number, columnIndex: number): number {
// Special case: first column spans 2 rows at the beginning
if (columnIndex === 0 && rowIndex % 2 === 0) return 2;
// No spanning for other cells
return 1;
}
Returns a string representation of the cell value at the specified row and column indices. This method is used when exporting the table data or copying to clipboard.
The index of the row
The index of the column
The text value of the specified cell
// Get the text value of a cell for export
const textValue = bodyAreaModel.getTextValueAt(1, 2);
// Implementation example
getTextValueAt(rowIndex: number, columnIndex: number): string {
const value = this.getValueAt(rowIndex, columnIndex);
// Handle different data types appropriately
if (value === null || value === undefined) return '';
if (value instanceof Date) return value.toISOString();
return String(value);
}
Returns the tooltip text for the cell at the specified row and column indices. This tooltip will be displayed when the user hovers over the cell.
The index of the row
The index of the column
The tooltip content (usually a string)
// Get the tooltip for a cell
const tooltip = bodyAreaModel.getTooltipAt(1, 2);
// Implementation example
getTooltipAt(rowIndex: number, columnIndex: number): any {
// Use the cell value as the tooltip
return this.getValueAt(rowIndex, columnIndex);
// Or provide a more detailed tooltip
// const value = this.getValueAt(rowIndex, columnIndex);
// return `Value: ${value}\nRow: ${rowIndex}\nColumn: ${columnIndex}`;
}
Gets the value at the specified row and column indices. This method handles tree rows and nested properties.
The index of the row
The index of the column
The value at the specified cell, or an empty string if not found
// Get the value in the first row, second column
const value = bodyAreaModel.getValueAt(0, 1);
console.log(`The value is: ${value}`);
// Iterate through all cells in a row
const rowIndex = 0;
for (let colIndex = 0; colIndex < columnDefs.length; colIndex++) {
const value = bodyAreaModel.getValueAt(rowIndex, colIndex);
console.log(`Cell (${rowIndex}, ${colIndex}): ${value}`);
}
Gets a value from an object using a property path. This method supports accessing nested properties using dot notation (e.g., 'person.name').
The object to get the value from
The property path to access (e.g., 'name' or 'person.contact.email')
The value at the specified property path, or undefined if not found
const user = { id: 1, name: 'John', contact: { email: 'john@example.com' } };
// Access simple property
const name = bodyAreaModel.getValueByT(user, 'name');
console.log(name); // 'John'
// Access nested property
const email = bodyAreaModel.getValueByT(user, 'contact.email');
console.log(email); // 'john@example.com'
Returns the Y-coordinate (in pixels) of the top of the row at the specified index. This method is used for scrolling and positioning rows in the viewport.
The index of the row
The Y-coordinate of the top of the row, in pixels
// Get the Y-position of a row
const yPos = bodyAreaModel.getYPosByRowIndex(10);
console.log(`Row 10 starts at Y-position: ${yPos}px`);
// Implementation example with fixed row heights
getYPosByRowIndex(rowIndex: number): number {
return rowIndex * this.defaultRowHeight;
}
// Implementation example with variable row heights
getYPosByRowIndex(rowIndex: number): number {
// Use a pre-calculated array of Y-positions
return this.yPositions[rowIndex];
// Or calculate on-the-fly
// let yPos = 0;
// for (let i = 0; i < rowIndex; i++) {
// yPos += this.getRowHeight(i);
// }
// return yPos;
}
Initializes the area model. This method is called internally by the TableModel during initialization. It can be used to perform any necessary setup, such as calculating row positions.
// Implementation example
init(): void {
// Calculate y-positions for all rows
this.calculateYPositions();
// Initialize any other internal state
this.initialized = true;
}
Determines whether the cell at the specified row and column indices is editable. If true, the user can edit the cell content.
The index of the row
The index of the column
True if the cell is editable, false otherwise
// Check if a cell is editable
const editable = bodyAreaModel.isEditable(1, 2);
if (editable) {
console.log('This cell can be edited by the user');
}
// Implementation example using column definitions
isEditable(rowIndex: number, columnIndex: number): boolean {
// Get editability from column definition
const columnDef = this.columnDefs[columnIndex];
return columnDef?.editable?.() ?? false;
}
// Implementation example with conditional editability
isEditable(rowIndex: number, columnIndex: number): boolean {
// Header cells are not editable
if (this.areaIdent === 'header') return false;
// First column is not editable (e.g., ID column)
if (columnIndex === 0) return false;
// Other cells in the body are editable
return this.areaIdent === 'body';
}
Determines whether this area supports filtering. If true, the area can be filtered using the externalFilterChanged method.
True if the area is filterable, false otherwise
// Check if an area is filterable
const filterable = bodyAreaModel.isFilterable();
if (filterable) {
console.log('This area supports filtering');
}
// Implementation example
isFilterable(): boolean {
// Only the body area is filterable
return this.areaIdent === 'body';
}
Determines whether the row at the specified index is checkable. If true, a checkbox will be rendered at the beginning of the row.
The index of the row
True if the row is checkable, false otherwise
// Check if a row is checkable
const checkable = bodyAreaModel.isRowCheckable(1);
if (checkable) {
console.log('This row can be checked by the user');
}
// Implementation example
isRowCheckable(rowIndex: number): boolean {
// All rows are checkable by default
return true;
// Or implement custom logic
// const row = this.getRowByIndex(rowIndex);
// return row && !row.locked; // Only unlocked rows are checkable
}
Returns the checked state of the row at the specified index.
The index of the row
The checked state of the row (true, false, or 'indeterminate'), or undefined if the row is not checkable
// Check if a row is checked
const checkedState = bodyAreaModel.isRowChecked(1);
if (checkedState === "full") {
console.log('This row is checked');
} else if (checkedState === "semi") {
console.log('This row is partially checked');
}
// Implementation example using a row selection model
isRowChecked(rowIndex: number): CheckedType | undefined {
if (!this.rowSelectionModel) return undefined;
const row = this.getRowByIndex(rowIndex);
return this.rowSelectionModel.isRowChecked(row);
}
Determines whether the cell at the specified row and column indices is selectable. If true, the user can select the cell.
The index of the row
The index of the column
True if the cell is selectable, false otherwise
// Check if a cell is selectable
const selectable = bodyAreaModel.isSelectable(1, 2);
if (selectable) {
console.log('This cell can be selected by the user');
}
// Implementation example
isSelectable(rowIndex: number, columnIndex: number): boolean {
// All cells are selectable by default
return true;
// Or implement custom logic
// return this.areaIdent === 'body'; // Only body cells are selectable
}
Protected setSets the checked state of the row at the specified index.
The index of the row
The new checked state
// Check a row
bodyAreaModel.setRowChecked(1, true);
// Uncheck a row
bodyAreaModel.setRowChecked(2, false);
// Implementation example using a row selection model
setRowChecked(rowIndex: number, checked: boolean): void {
if (!this.rowSelectionModel) return;
const row = this.getRowByIndex(rowIndex);
if (row) {
this.rowSelectionModel.checkRow(row, checked);
}
}
Replaces the current rows array with a new one. This also resets the filtered rows to match the new rows array.
The new array of row objects
// Replace the current rows with new data
const newRows = [
{ id: 4, name: 'Alice', age: 35 },
{ id: 5, name: 'Charlie', age: 45 }
];
bodyAreaModel.setRows(newRows);
Sets the value of a cell at the specified row and column indices. This method is called when a cell is edited by the user or programmatically.
The index of the row containing the cell
The index of the column containing the cell
The new value to set
// Set the value of a cell
areaModel.setValue(1, 2, "New Value");
// Implementation example for an object-based model
setValue(rowIndex: number, columnIndex: number, value: any): boolean {
const row = this.getRowByIndex(rowIndex);
if (!row) return false;
const property = this.columnDefs[columnIndex].property;
row[property] = value;
return true;
}
Sorts the filtered rows using a custom comparator function.
This method provides more flexibility than doSort() for complex sorting logic.
A function that compares two rows and returns a number:
// Sort by name length
bodyAreaModel.sort((a, b) => a.name.length - b.name.length);
// Sort by a computed value
bodyAreaModel.sort((a, b) => {
const scoreA = a.wins * 3 + a.draws;
const scoreB = b.wins * 3 + b.draws;
return scoreB - scoreA; // Descending order
});
Description
The
AreaModelObjectArrayclass is a fundamental component of the GuiExpert Table library that represents a data model for a specific area of a table (header, body, or footer) where the data is stored as an array of objects.This class extends AbstractAreaModel and implements ObjectArrayHolderIf, providing a robust implementation for handling tabular data where each row is represented as an object in an array.
The class provides functionality for:
Example
Example
Example
Example
Example
Example
Example
See