Allow for selection

This commit is contained in:
pk 2022-11-07 10:01:24 +01:00
parent 8b7facdc64
commit 1f7f38932f
3 changed files with 50 additions and 25 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@tp/tp-table", "name": "@tp/tp-table",
"version": "1.0.0", "version": "1.0.1",
"description": "", "description": "",
"main": "tp-table.js", "main": "tp-table.js",
"scripts": { "scripts": {

View File

@ -41,6 +41,17 @@ class TpTableItem extends BaseElement {
align-items: center; align-items: center;
} }
[part="chk"] {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
tp-checkbox::part(label) {
display: none;
}
[part="cell"] { [part="cell"] {
align-self: stretch; align-self: stretch;
overflow: hidden; overflow: hidden;
@ -63,13 +74,13 @@ class TpTableItem extends BaseElement {
return html` return html`
<div id="grid" class="wrap" part="row"> <div id="grid" class="wrap" part="row">
${this.selectable ? html` ${this.selectable ? html`
<div class="chk"> <div class="chk" part="chk">
<tp-checkbox id="selectionChk" @click=${this._updateSelectionState}></tp-checkbox> <tp-checkbox id="selectionChk" @click=${this._updateSelectionState}></tp-checkbox>
</div> </div>
` : null} ` : null}
${Array.isArray(columns) ? columns.map(column => { ${Array.isArray(columns) ? columns.map((column, idx) => {
if (column.visible !== true && column.required !== true) return; if (column.visible !== true && column.required !== true) return;
return this.renderColumn(column, item) || null; return this.renderColumn(column, item, idx) || null;
}) : null }) : null
} }
</div> </div>
@ -79,7 +90,7 @@ class TpTableItem extends BaseElement {
static get properties() { static get properties() {
return { return {
index: { type: Array }, index: { type: Array },
item: { type: Object }, item: { type: Object, hasChanged: () => true },
columns: { type: Array }, columns: { type: Array },
selectable: { type: Boolean }, selectable: { type: Boolean },
}; };

View File

@ -132,7 +132,14 @@ export class TpTable extends DomQuery(LitElement) {
} }
.select-col { .select-col {
padding: 0px 20px 10px; display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.select-col tp-checkbox::part(label) {
display: none;
} }
lit-virtualizer { lit-virtualizer {
@ -177,7 +184,7 @@ export class TpTable extends DomQuery(LitElement) {
<div class="wrap"> <div class="wrap">
<div id="tableHeader" part="header" class="list-headline" @track=${this._colResizeTracked}> <div id="tableHeader" part="header" class="list-headline" @track=${this._colResizeTracked}>
${this.selectable ? html` ${this.selectable ? html`
<div class="select-col"><tp-checkbox @checked-changed=${e => this._checkedChanged(e)}></tp-checkbox></div> <div class="select-col" part="chkAll"><tp-checkbox @checked-changed=${e => this._checkedChanged(e)}></tp-checkbox></div>
` : null} ` : null}
${columns.map(column => this.renderColumnHeader(column))} ${columns.map(column => this.renderColumnHeader(column))}
</div> </div>
@ -227,7 +234,7 @@ export class TpTable extends DomQuery(LitElement) {
renderItem(item, idx, columns) { renderItem(item, idx, columns) {
return html` return html`
<tp-table-item <tp-table-item
exportparts="cell,odd,row" exportparts="cell,odd,row,chk"
item item
.index=${idx} .index=${idx}
.item=${item} .item=${item}
@ -294,6 +301,10 @@ export class TpTable extends DomQuery(LitElement) {
this.reloadPagedList(); this.reloadPagedList();
} }
scrollToIndex(idx) {
this.$.virtualList.scrollToIndex(idx);
}
firstUpdated() { firstUpdated() {
this.shadowRoot.querySelector('tp-scroll-threshold').target = this.shadowRoot.querySelector('lit-virtualizer'); this.shadowRoot.querySelector('tp-scroll-threshold').target = this.shadowRoot.querySelector('lit-virtualizer');
new ColumResizer(this.$.tableHeader, '.width-handle'); new ColumResizer(this.$.tableHeader, '.width-handle');
@ -319,11 +330,11 @@ export class TpTable extends DomQuery(LitElement) {
} }
_updateColumns() { _updateColumns() {
this.$.tableHeader.style.gridTemplateColumns = this._updateColumnWidths(this.selectable ? [ '40px' ] : []).join(' '); this.$.tableHeader.style.gridTemplateColumns = this._updateColumnWidths(this.selectable ? ['40px'] : []).join(' ');
} }
_updateColumnWidths(prepend) { _updateColumnWidths(prepend) {
return [ ...(prepend || []), ...this.columns.filter(col => col.required || col.visible).map(col => col.width) ]; return [...(prepend || []), ...this.columns.filter(col => col.required || col.visible).map(col => col.width)];
} }
_colResizeTracked(e) { _colResizeTracked(e) {
@ -376,26 +387,29 @@ export class TpTable extends DomQuery(LitElement) {
_checkedChanged(e) { _checkedChanged(e) {
if (Array.isArray(this.items) === false) return; if (Array.isArray(this.items) === false) return;
if (e.detail.value) { if (e.detail) {
this._selectAll(); this._selectAll();
} else { } else {
this._selectNone(); this._selectNone();
} }
this.items = [...this.times]; this.items = [...this.items];
} }
_selectAll() { _selectAll() {
this.items.forEach((entry, idx) => { this.items = this.items.map((entry) => {
this.items[idx].__selected__ = true; entry.__selected__ = true;
return entry;
}); });
this.requestUpdate('items');
this._selectionChanged(); this._selectionChanged();
} }
_selectNone() { _selectNone() {
this._items.forEach((entry, idx) => { this.items = this.items.map((entry) => {
this._items[idx].__selected__ = false; entry.__selected__ = false;
return entry;
}); });
this._selectionChanged(); this._selectionChanged();
@ -405,28 +419,28 @@ export class TpTable extends DomQuery(LitElement) {
if (this.__restoringSelection) return; if (this.__restoringSelection) return;
if (e !== undefined) { if (e !== undefined) {
const item = this._items.find(item => item._id === e.detail.item._id); const item = this.items.find(item => item._id === e.detail.item._id);
item.__selected__ = e.detail.selected; item.__selected__ = e.detail.selected;
} }
this._selItems = this._items.filter(entry => entry.__selected__ === true); this._selItems = this.items.filter(entry => entry.__selected__ === true);
this.dispatchEvent(new CustomEvent('item-selection-changed', { detail: this._selItems, bubbles: true, composed: true })); this.dispatchEvent(new CustomEvent('item-selection-changed', { detail: this._selItems, bubbles: true, composed: true }));
} }
_updateSelEntries() { _updateSelEntries() {
this._hiddenSelection = 0; this._hiddenSelection = 0;
if (!this._items) { if (!this.items) {
this._selItems = []; this._selItems = [];
} else { } else {
this._selItems.forEach(sel => { this._selItems.forEach(sel => {
const idx = this._items.findIndex(entry => entry._id === sel._id); const idx = this.items.findIndex(entry => entry._id === sel._id);
if (idx > -1) { if (idx > -1) {
// Suppress rebuild of the selected invoices list. // Suppress rebuild of the selected invoices list.
// When we restore the selection on a filtered list of invoices we would loose the selection of hidden onces // When we restore the selection on a filtered list of invoices we would loose the selection of hidden onces
// when _selectionChanged is triggered. So we set a flag that the observer is skipped. // when _selectionChanged is triggered. So we set a flag that the observer is skipped.
this.__restoringSelection = true; this.__restoringSelection = true;
this._items[idx].__selected__ = true; this.items[idx].__selected__ = true;
this.__restoringSelection = false; this.__restoringSelection = false;
} else { } else {
this._hiddenSelection++; this._hiddenSelection++;