@eclipse-scout/core
Version:
Eclipse Scout runtime
209 lines (176 loc) • 6.17 kB
text/typescript
/*
* 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 {
arrays, Column, InitModelOf, ListBoxLayout, ListBoxModel, ListBoxTableAccessibilityRenderer, LookupBox, lookupField, LookupResult, LookupRow, ObjectOrChildModel, objects, scout, Table, TableModel, TableRowModel, TableRowsCheckedEvent,
Widget
} from '../../../index';
import $ from 'jquery';
export class ListBox<TValue> extends LookupBox<TValue> implements ListBoxModel<TValue> {
declare model: ListBoxModel<TValue>;
table: Table;
constructor() {
super();
this.table = null;
this._addWidgetProperties(['table', 'filterBox']);
}
protected override _init(model: InitModelOf<this>) {
super._init(model);
this.table.on('rowsChecked', this._onTableRowsChecked.bind(this));
this.table.setScrollTop(this.scrollTop);
}
protected _initStructure(value: TValue[]) {
if (!this.table) {
this.table = this._createDefaultListBoxTable();
}
this.table.accessibilityRenderer = new ListBoxTableAccessibilityRenderer();
// align checkableColumn in table with checkboxes of tree fields
if (this.table.checkableColumn) { // may be null if a non-default list-box-table with checkable=false is used
this.table.checkableColumn.minWidth = 28;
this.table.checkableColumn.width = this.table.checkableColumn.minWidth; // do not use setWidth here
}
}
protected override _render() {
super._render();
this.$container.addClass('list-box');
}
protected _createFieldContainerLayout(): ListBoxLayout {
return new ListBoxLayout(this, this.table, this.filterBox);
}
protected _renderStructure() {
this.table.render(this.$fieldContainer);
this.addField(this.table.$container);
}
protected _onTableRowsChecked(event: TableRowsCheckedEvent) {
this._syncTableToValue();
}
protected _syncTableToValue() {
if (!this.lookupCall || this._valueSyncing) {
return;
}
this._valueSyncing = true;
let valueArray = [];
this.table.rows.forEach(row => {
if (row.checked) {
valueArray.push(row.lookupRow.key);
}
});
this.setValue(valueArray);
this._valueSyncing = false;
}
protected override _valueChanged() {
super._valueChanged();
this._syncValueToTable(this.value);
}
protected _syncValueToTable(newValue: TValue[]) {
if (!this.lookupCall || this._valueSyncing || !this.initialized) {
return;
}
this._valueSyncing = true;
let opts = {
checkOnlyEnabled: false
};
try {
if (arrays.empty(newValue)) {
this.table.uncheckRows(this.table.rows, opts);
} else {
// if lookup was not executed yet: do it now.
let lookupScheduled = this._ensureLookupCallExecuted();
if (lookupScheduled) {
return; // was the first lookup: table has no rows yet. cancel sync. Will be executed again after lookup execution.
}
let rowsToCheck = [];
this.table.uncheckRows(this.table.rows, opts);
this.table.rows.forEach(row => {
if (arrays.containsAny(newValue, row.lookupRow.key)) {
rowsToCheck.push(row);
}
}, this);
this.table.checkRows(rowsToCheck, opts);
}
this._updateDisplayText();
} finally {
this._valueSyncing = false;
}
}
protected override _lookupByAllDone(result: LookupResult<TValue>) {
super._lookupByAllDone(result);
this._populateTable(result);
}
protected _populateTable(result: LookupResult<TValue>) {
let
tableRows = [],
lookupRows = result.lookupRows;
lookupRows.forEach(lookupRow => {
tableRows.push(this._createTableRow(lookupRow));
});
this.table.deleteAllRows();
this.table.insertRows(tableRows);
this._syncValueToTable(this.value);
}
/**
* Returns a lookup row for each value currently checked.
*/
getCheckedLookupRows(): LookupRow<TValue>[] {
if (this.value === null || arrays.empty(this.value) || this.table.rows.length === 0) {
return [];
}
return this.table.rows
.filter(row => row.checked)
.map(row => row.lookupRow);
}
protected _createTableRow(lookupRow: LookupRow<TValue>): TableRowModel {
let cell = lookupField.createTableCell(lookupRow);
let row: TableRowModel = {
cells: [cell],
lookupRow: lookupRow
};
if (lookupRow.enabled === false) {
row.enabled = false;
}
if (lookupRow.cssClass) {
row.cssClass = lookupRow.cssClass;
}
if (lookupRow.active === false) {
row.active = false;
row.cssClass = (row.cssClass ? (row.cssClass + ' ') : '') + 'inactive';
}
return row;
}
protected override _prepareWidgetProperty(propertyName: string, models: ObjectOrChildModel<Widget>): Widget;
protected override _prepareWidgetProperty(propertyName: string, models: ObjectOrChildModel<Widget>[]): Widget[];
protected override _prepareWidgetProperty(propertyName: string, models: ObjectOrChildModel<Widget> | ObjectOrChildModel<Widget>[]): Widget | Widget[] {
if (propertyName === 'table' && objects.isPojo(models)) {
// Enhance given model with list box specific defaults
models = $.extend(this._createDefaultListBoxTableModel(), models);
}
return super._prepareWidgetProperty(propertyName, models as ObjectOrChildModel<Widget>);
}
protected _createDefaultListBoxTable(): Table {
return scout.create(Table, {
parent: this,
...this._createDefaultListBoxTableModel()
});
}
protected _createDefaultListBoxTableModel(): TableModel {
return {
autoResizeColumns: true,
checkable: true,
checkableStyle: Table.CheckableStyle.CHECKBOX_TABLE_ROW,
headerVisible: false,
footerVisible: false,
columns: [{
objectType: Column
}]
};
}
override getDelegateScrollable(): Widget {
return this.table;
}
}