From 2a21a4550c4b0471e64218bd943e32b1c4bf4258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Gla=CC=88ser?= Date: Thu, 4 Jun 2026 18:44:58 +0200 Subject: [PATCH] Simulate server-side load more --- components/data-display.html | 84 ++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/components/data-display.html b/components/data-display.html index df7305d..cccc309 100644 --- a/components/data-display.html +++ b/components/data-display.html @@ -207,14 +207,14 @@
E10
-
+
@@ -235,19 +235,46 @@ const headerCells = Array.from(table.querySelectorAll('[role="columnheader"][data-sort-key]')); const headerButtons = headerCells.map((cell) => cell.querySelector('.sg-large-table__sort-button')); - const rows = Array.from(table.querySelectorAll('[data-component-part="large-table-row"]')); + const dataRows = Array.from(table.querySelectorAll('[data-component-part="large-table-row"]')).filter((row) => !row.hasAttribute('data-large-table-load-more-row')); + const loadMoreRow = table.querySelector('[data-large-table-load-more-row="true"]'); + const loadMoreTrigger = table.querySelector('[data-large-table-load-more-trigger="true"]'); const headerRow = table.querySelector('[data-component-part="large-table-header-row"]'); const searchInput = table.querySelector('[data-large-table-search]'); const searchFieldWrap = table.querySelector('[data-component="single-line-input"]'); const searchClearButton = table.querySelector('.sg-input-clear-button'); let searchTimer = null; + let loadMoreTimer = null; + const totalRows = Array.from({ length: 20 }, (_, index) => { + const number = index + 1; + return ['A' + number, 'B' + number, 'C' + number, 'D' + number, 'E' + number]; + }); const state = { columnIndex: 0, direction: 'ascending', query: '', - loading: false, + loadingSearch: false, + loadingMore: false, + loadedCount: dataRows.length, }; + function createDataRow(values) { + const row = document.createElement('div'); + row.className = 'sg-card-segment sg-card-segment--body sg-card-segment--white sg-large-table__row'; + row.setAttribute('role', 'row'); + row.setAttribute('data-component-part', 'large-table-row'); + row.setAttribute('data-large-table-data-row', 'true'); + + values.forEach((value) => { + const cell = document.createElement('div'); + cell.className = 'sg-large-table__cell'; + cell.setAttribute('role', 'cell'); + cell.textContent = value; + row.appendChild(cell); + }); + + return row; + } + function setHeaderState(activeIndex, direction) { headerCells.forEach((cell, index) => { const icon = cell.querySelector('.sg-large-table__sort-icon'); @@ -297,8 +324,8 @@ } function renderRows() { - table.setAttribute('aria-busy', state.loading ? 'true' : 'false'); - const sortedRows = rows.slice().sort((leftRow, rightRow) => { + table.setAttribute('aria-busy', state.loadingSearch || state.loadingMore ? 'true' : 'false'); + const sortedRows = dataRows.slice().sort((leftRow, rightRow) => { const leftCell = leftRow.querySelectorAll('[role="cell"]')[state.columnIndex]; const rightCell = rightRow.querySelectorAll('[role="cell"]')[state.columnIndex]; const leftValue = leftCell ? leftCell.textContent : ''; @@ -314,6 +341,13 @@ row.setAttribute('aria-hidden', isVisible ? 'false' : 'true'); }); + if (loadMoreRow) { + const hasMoreRows = state.loadedCount < totalRows.length; + loadMoreRow.classList.toggle('sg-large-table__row--hidden', !hasMoreRows); + loadMoreRow.setAttribute('aria-hidden', hasMoreRows ? 'false' : 'true'); + table.appendChild(loadMoreRow); + } + setHeaderState(state.columnIndex, state.direction); } @@ -338,7 +372,7 @@ if (searchFieldWrap) { searchFieldWrap.setAttribute('data-has-value', searchInput.value ? 'true' : 'false'); } - state.loading = true; + state.loadingSearch = true; renderRows(); if (searchTimer) { @@ -347,7 +381,7 @@ searchTimer = window.setTimeout(() => { state.query = searchInput.value.trim().toLowerCase(); - state.loading = false; + state.loadingSearch = false; renderRows(); }, 250); }); @@ -361,7 +395,7 @@ } searchInput.value = ''; state.query = ''; - state.loading = false; + state.loadingSearch = false; if (searchFieldWrap) { searchFieldWrap.setAttribute('data-has-value', 'false'); } @@ -370,6 +404,38 @@ }); } + if (loadMoreTrigger) { + loadMoreTrigger.addEventListener('click', (event) => { + event.preventDefault(); + + if (state.loadingMore || state.loadedCount >= totalRows.length) { + return; + } + + if (loadMoreTimer) { + window.clearTimeout(loadMoreTimer); + } + + state.loadingMore = true; + loadMoreTrigger.textContent = 'Lädt ...'; + renderRows(); + + loadMoreTimer = window.setTimeout(() => { + const nextCount = Math.min(state.loadedCount + 5, totalRows.length); + const nextRows = totalRows.slice(state.loadedCount, nextCount).map((values) => createDataRow(values)); + + nextRows.forEach((row) => { + dataRows.push(row); + }); + + state.loadedCount = nextCount; + state.loadingMore = false; + loadMoreTrigger.textContent = 'Mehr laden'; + renderRows(); + }, 350); + }); + } + if (headerRow) { setHeaderState(state.columnIndex, state.direction); }