UNPKG

@eclipse-scout/core

Version:
185 lines (164 loc) 5.61 kB
/* * Copyright (c) 2010, 2025 BSI Business Systems Integration AG * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 * which is available at https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 */ import {BooleanColumnModel, Cell, CheckBoxField, Column, comparators, scout, TableRow} from '../../index'; /** * A column holding boolean values represented by check boxes. */ export class BooleanColumn extends Column<boolean> implements BooleanColumnModel { declare model: BooleanColumnModel; triStateEnabled: boolean; constructor() { super(); this.comparator = comparators.NUMERIC; this.filterType = 'ColumnUserFilter'; this.horizontalAlignment = 0; this.minWidth = Column.SMALL_MIN_WIDTH; this.triStateEnabled = false; this.textBased = false; } protected override _formatValue(value: boolean, row?: TableRow): string { if (this.triStateEnabled && value === null) { return '?'; } return value ? 'X' : ''; } override buildCell(cell: Cell<boolean>, row: TableRow): string { let content = '', enabled = row.enabled, tableNodeColumn = this.table.isTableNodeColumn(this), rowPadding = 0; if (tableNodeColumn) { rowPadding = this.table._calcRowLevelPadding(row); } if (cell.empty) { // if cell wants to be really empty (e.g. no checkbox icon, use logic of base class) return super.buildCell(cell, row); } enabled = enabled && cell.editable; let cssClass = this._cellCssClass(cell, tableNodeColumn); let style = this._cellStyle(cell, tableNodeColumn, rowPadding); if (!enabled) { cssClass += ' disabled'; } let checkBoxCssClass = 'check-box'; let ariaChecked = ''; if (cell.value === true) { checkBoxCssClass += ' checked'; ariaChecked = 'aria-checked="true"'; } if (cell.value === false) { ariaChecked = 'aria-checked="false"'; } if (this.triStateEnabled && cell.value !== true && cell.value !== false) { checkBoxCssClass += ' undefined'; ariaChecked = 'aria-checked="mixed"'; } if (!enabled) { checkBoxCssClass += ' disabled'; } if (tableNodeColumn && row.expandable) { this.tableNodeColumn = true; content = this._expandIcon(row.expanded, rowPadding) + content; if (row.expanded) { cssClass += ' expanded'; } } // empty aria label added so screen readers finds the checkbox in the column (adding &nbsp in the div content would work, too) content = content + '<div aria-label=" " role="checkbox" ' + ariaChecked + ' class="' + checkBoxCssClass + '"></div>'; return this._buildCell(cell, content, style, cssClass); } $checkBox($row: JQuery): JQuery { let $cell = this.table.$cell(this, $row); return $cell.children('.check-box'); } protected override _cellCssClass(cell: Cell<boolean>, tableNode?: boolean): string { let cssClass = super._cellCssClass(cell); cssClass = cssClass.replace(' editable', ''); cssClass += ' checkable'; if (tableNode) { cssClass += ' table-node'; } return cssClass; } /** * This function does intentionally _not_ call the super function (prepareCellEdit) because we don't want to * show an editor for BooleanColumns when user clicks on a cell. */ override onMouseUp(event: JQuery.MouseUpEvent, $row: JQuery) { let row = $row.data('row') as TableRow, cell = this.cell(row); if (this.table.checkableColumn === this) { this.table.checkRow(row, !row.checked); } else if (this.isCellEditable(row, cell, event)) { this._toggleCellValue(row, cell); } } /** * In a remote app this function is overridden, the default implementation is the local case. * @see TableAdapter */ protected _toggleCellValue(row: TableRow, cell: Cell<boolean>) { let prepareEvent = this.table.trigger('prepareCellEdit', { column: this, row: row }); if (prepareEvent.defaultPrevented) { return; } let value = cell.value as boolean; let newValue = !value; if (this.triStateEnabled) { if (value === false) { newValue = true; } else if (value === true) { newValue = null; } else if (value === null) { newValue = false; } } let dummyField = scout.create(CheckBoxField, { parent: this.table, value: newValue }); let completeEvent = this.table.trigger('completeCellEdit', { field: dummyField, row: row, column: this, cell: cell }); if (!completeEvent.defaultPrevented) { this.setCellValue(row, newValue); } dummyField.destroy(); } protected override _createEditor(row: TableRow): CheckBoxField { return scout.create(CheckBoxField, { parent: this.table, triStateEnabled: this.triStateEnabled }); } override cellTextForGrouping(row: TableRow): string { let cell = this.cell(row); if (this.triStateEnabled && cell.value === null) { return this.session.text('ui.BooleanColumnGroupingMixed'); } if (cell.value === true) { return this.session.text('ui.BooleanColumnGroupingTrue'); } return this.session.text('ui.BooleanColumnGroupingFalse'); } setTriStateEnabled(triStateEnabled: boolean) { if (this.triStateEnabled === triStateEnabled) { return; } this.triStateEnabled = triStateEnabled; this.table.rows.forEach(row => this._updateCellText(row, this.cell(row))); } }