UNPKG

@eclipse-scout/core

Version:
209 lines (176 loc) 6.17 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 { 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; } }